mirror of
https://github.com/jwinterm/grim.git
synced 2026-11-15 18:23:55 +01:00
fix: check wallet state from node, build: update common deps, tor: optimize running service check, p2p: async peer saving, update seeds
- Update common dependencies - Optimize check of running Tor service - Async peer saving - Add mainnet and testnet seeds - Remove grinnode.live from default external connections Reviewed-on: https://code.gri.mw/GUI/grim/pulls/43
This commit is contained in:
@@ -399,6 +399,7 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
/// To draw with egui`s eframe (for wgpu, glow backends and wasm target).
|
||||
impl<Platform: PlatformCallbacks> eframe::App for App<Platform> {
|
||||
fn update(&mut self, ctx: &Context, _: &mut eframe::Frame) {
|
||||
ctx.plugin_or_default::<egui_async::EguiAsyncPlugin>();
|
||||
self.ui(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use egui::{Align, Id, Layout, RichText, StrokeKind};
|
||||
use egui_async::Bind;
|
||||
use grin_core::global::ChainTypes;
|
||||
|
||||
use crate::AppConfig;
|
||||
@@ -44,8 +45,10 @@ pub struct P2PSetup {
|
||||
/// Flag to check if p2p port from saved config value is available.
|
||||
is_port_available: bool,
|
||||
|
||||
/// Flag to check if entered peer address is correct and/or available.
|
||||
is_correct_address_edit: bool,
|
||||
/// Async check entered peer address.
|
||||
address_check: Bind<bool, String>,
|
||||
/// Flag to check if peer is correct and/or available.
|
||||
address_available: Option<bool>,
|
||||
/// Peer edit value for modal.
|
||||
peer_edit: String,
|
||||
|
||||
@@ -92,14 +95,15 @@ impl Default for P2PSetup {
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
let default_test_seeds = grin_servers::TESTNET_DNS_SEEDS
|
||||
let default_test_seeds = Node::TESTNET_DNS_SEEDS
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
Self {
|
||||
port_edit: port,
|
||||
port_available_edit: is_port_available,
|
||||
is_correct_address_edit: true,
|
||||
address_check: Bind::new(false),
|
||||
address_available: Some(true),
|
||||
is_port_available,
|
||||
peer_edit: "".to_string(),
|
||||
default_main_seeds,
|
||||
@@ -192,7 +196,6 @@ impl ContentContainer for P2PSetup {
|
||||
// Show preferred peers setup.
|
||||
self.peer_list_ui(ui, &PeerType::Preferred);
|
||||
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -377,7 +380,8 @@ impl P2PSetup {
|
||||
};
|
||||
View::button(ui, add_text, Colors::white_or_black(false), || {
|
||||
// Setup values for modal.
|
||||
self.is_correct_address_edit = true;
|
||||
self.address_check = Bind::new(false);
|
||||
self.address_available = Some(true);
|
||||
self.peer_edit = "".to_string();
|
||||
// Select modal id.
|
||||
let modal_id = match peer_type {
|
||||
@@ -405,26 +409,34 @@ impl P2PSetup {
|
||||
|
||||
/// Draw peer creation [`Modal`] content.
|
||||
fn peer_modal(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
let on_save = |c: &mut P2PSetup| {
|
||||
// Check if peer is correct and/or available.
|
||||
let peer = c.peer_edit.clone();
|
||||
let is_correct_address = PeersConfig::peer_to_addr(peer.clone()).is_some();
|
||||
c.is_correct_address_edit = is_correct_address;
|
||||
|
||||
// Save peer at config.
|
||||
if is_correct_address {
|
||||
match modal.id {
|
||||
CUSTOM_SEED_MODAL => NodeConfig::save_custom_seed(peer),
|
||||
ALLOW_PEER_MODAL => NodeConfig::allow_peer(peer),
|
||||
DENY_PEER_MODAL => NodeConfig::deny_peer(peer),
|
||||
PREFER_PEER_MODAL => NodeConfig::prefer_peer(peer),
|
||||
&_ => {}
|
||||
if self.address_available.is_none() {
|
||||
let peer = self.peer_edit.clone();
|
||||
if let Some(res) = self.address_check.read_or_request(|| async {
|
||||
let available = PeersConfig::peer_to_addr(peer).is_some();
|
||||
Ok(available)
|
||||
}) {
|
||||
match res {
|
||||
Ok(available) => {
|
||||
self.address_available = Some(*available);
|
||||
// Save peer at config.
|
||||
if *available {
|
||||
let peer = self.peer_edit.clone();
|
||||
match modal.id {
|
||||
CUSTOM_SEED_MODAL => NodeConfig::save_custom_seed(peer),
|
||||
ALLOW_PEER_MODAL => NodeConfig::allow_peer(peer),
|
||||
DENY_PEER_MODAL => NodeConfig::deny_peer(peer),
|
||||
PREFER_PEER_MODAL => NodeConfig::prefer_peer(peer),
|
||||
&_ => {}
|
||||
}
|
||||
Modal::close();
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
self.address_available = Some(false);
|
||||
}
|
||||
}
|
||||
|
||||
c.is_port_available = true;
|
||||
Modal::close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ui.add_space(6.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
@@ -437,17 +449,22 @@ impl P2PSetup {
|
||||
|
||||
// Draw peer address text edit.
|
||||
let mut edit = TextEdit::new(Id::from(modal.id)).paste();
|
||||
if self.address_available.is_none() {
|
||||
edit = edit.disable();
|
||||
}
|
||||
edit.ui(ui, &mut self.peer_edit, cb);
|
||||
if edit.enter_pressed {
|
||||
on_save(self);
|
||||
self.address_available = None;
|
||||
}
|
||||
|
||||
// Show error when specified address is incorrect.
|
||||
if !self.is_correct_address_edit {
|
||||
ui.add_space(10.0);
|
||||
ui.label(RichText::new(t!("network_settings.peer_address_error"))
|
||||
.size(16.0)
|
||||
.color(Colors::red()));
|
||||
if let Some(available) = self.address_available {
|
||||
if !available {
|
||||
ui.add_space(10.0);
|
||||
ui.label(RichText::new(t!("network_settings.peer_address_error"))
|
||||
.size(16.0)
|
||||
.color(Colors::red()));
|
||||
}
|
||||
}
|
||||
ui.add_space(12.0);
|
||||
|
||||
@@ -465,7 +482,9 @@ impl P2PSetup {
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.save"), Colors::white_or_black(false), || {
|
||||
on_save(self);
|
||||
if self.address_available.is_some() {
|
||||
self.address_available = None;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -179,7 +179,7 @@ impl WalletTransactionsContent {
|
||||
});
|
||||
}
|
||||
|
||||
if !tx.cancelled() && !tx.cancelling() && !tx.posting() {
|
||||
if wallet.synced_from_node() && !tx.cancelled() && !tx.cancelling() && !tx.posting() {
|
||||
let resend = tx.broadcasting_timed_out(wallet);
|
||||
|
||||
// Draw button to cancel transaction.
|
||||
|
||||
@@ -248,7 +248,7 @@ impl WalletTransactionContent {
|
||||
return;
|
||||
}
|
||||
|
||||
if !tx.cancelled() && !tx.cancelling() && !tx.posting() {
|
||||
if wallet.synced_from_node() && !tx.cancelled() && !tx.cancelling() && !tx.posting() {
|
||||
let rebroadcast = tx.broadcasting_timed_out(&wallet);
|
||||
|
||||
// Draw button to cancel transaction.
|
||||
|
||||
+13
-2
@@ -87,12 +87,23 @@ impl Node {
|
||||
|
||||
/// Default Mainnet DNS Seeds
|
||||
pub const MAINNET_DNS_SEEDS: &'static[&'static str] = &[
|
||||
"main.gri.mw",
|
||||
"grincoin.org",
|
||||
"mainnet.seed.grin.lesceller.com",
|
||||
"grinseed.revcore.net",
|
||||
"mainnet-seed.grinnode.live",
|
||||
"mainnet.grin.punksec.de",
|
||||
"grinnode.30-r.com",
|
||||
"grincoin.org"
|
||||
"grinnode.30-r.com"
|
||||
];
|
||||
|
||||
/// Default Testnet DNS Seeds
|
||||
pub const TESTNET_DNS_SEEDS: &'static[&'static str] = &[
|
||||
"test.gri.mw",
|
||||
"testnet.grincoin.org",
|
||||
"floonet.seed.grin.lesceller.com",
|
||||
"grintestseed.revcore.net",
|
||||
"testnet.grin.punksec.de",
|
||||
"testnet.grinnode.30-r.com"
|
||||
];
|
||||
|
||||
/// Stop the [`Server`] and setup exit flag after if needed.
|
||||
|
||||
+38
-25
@@ -275,26 +275,26 @@ impl Tor {
|
||||
.nickname(hs_nickname.clone())
|
||||
.build()
|
||||
.unwrap();
|
||||
if let Ok((service, request)) =
|
||||
client_thread.launch_onion_service(service_config)
|
||||
{
|
||||
// Launch service proxy.
|
||||
let addr = SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), port);
|
||||
tokio::spawn(Self::run_service_proxy(
|
||||
addr,
|
||||
client_thread.clone(),
|
||||
service.clone(),
|
||||
request,
|
||||
hs_nickname.clone(),
|
||||
)).await.unwrap();
|
||||
// Check service availability.
|
||||
let addr = service.onion_address()
|
||||
.unwrap()
|
||||
.display_unredacted()
|
||||
.to_string();
|
||||
let url = format!("http://{}/", addr);
|
||||
Self::check_service(service_id, client_thread, url, port, key);
|
||||
return;
|
||||
if let Ok(res) = client_thread.launch_onion_service(service_config) {
|
||||
if let Some((service, request)) = res {
|
||||
// Launch service proxy.
|
||||
let addr = SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), port);
|
||||
tokio::spawn(Self::run_service_proxy(
|
||||
addr,
|
||||
client_thread.clone(),
|
||||
service.clone(),
|
||||
request,
|
||||
hs_nickname.clone(),
|
||||
)).await.unwrap();
|
||||
// Check service availability.
|
||||
let addr = service.onion_address()
|
||||
.unwrap()
|
||||
.display_unredacted()
|
||||
.to_string();
|
||||
let url = format!("http://{}/", addr);
|
||||
Self::check_service(service_id, client_thread, url, port, key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
on_error(service_id);
|
||||
})
|
||||
@@ -333,11 +333,18 @@ impl Tor {
|
||||
const MAX_ERRORS: i32 = 3;
|
||||
let mut errors_count = 0;
|
||||
loop {
|
||||
if !Self::is_service_running(&service_id) {
|
||||
// Remove service from checking.
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.checking_services.write();
|
||||
w_services.remove(&service_id);
|
||||
// Check if service is running.
|
||||
fn is_running(service_id: &String) -> bool {
|
||||
let running = Tor::is_service_running(service_id);
|
||||
if !running {
|
||||
// Remove service from checking.
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.checking_services.write();
|
||||
w_services.remove(service_id);
|
||||
}
|
||||
running
|
||||
}
|
||||
if !is_running(&service_id) {
|
||||
break;
|
||||
}
|
||||
// Send request.
|
||||
@@ -354,10 +361,16 @@ impl Tor {
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.failed_services.write();
|
||||
w_services.remove(&service_id);
|
||||
if !is_running(&service_id) {
|
||||
break;
|
||||
}
|
||||
// Check again after 50 seconds.
|
||||
Duration::from_millis(50000)
|
||||
}
|
||||
Err(_) => {
|
||||
if !is_running(&service_id) {
|
||||
break;
|
||||
}
|
||||
// Restart service on 3rd error.
|
||||
errors_count += 1;
|
||||
if errors_count == MAX_ERRORS {
|
||||
|
||||
@@ -35,10 +35,9 @@ pub struct ExternalConnection {
|
||||
}
|
||||
|
||||
/// Default external node URL for main network.
|
||||
const DEFAULT_MAIN_URLS: [&'static str; 3] = [
|
||||
const DEFAULT_MAIN_URLS: [&'static str; 2] = [
|
||||
"https://main.gri.mw",
|
||||
"https://grincoin.org",
|
||||
"https://grinnode.live:3413"
|
||||
"https://grincoin.org"
|
||||
];
|
||||
|
||||
/// Default external node URL for main network.
|
||||
|
||||
@@ -533,6 +533,7 @@ impl Wallet {
|
||||
let mut w_conn = conn.write();
|
||||
*w_conn = wallet_close.get_config().connection();
|
||||
}
|
||||
wallet_close.from_node.store(false, Ordering::Relaxed);
|
||||
// Start sync to exit from thread.
|
||||
wallet_close.sync();
|
||||
});
|
||||
@@ -570,7 +571,7 @@ impl Wallet {
|
||||
self.sync_error.store(error, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Check if last synchronization finished from node.
|
||||
/// Check if wallet was synced from node after opening.
|
||||
pub fn synced_from_node(&self) -> bool {
|
||||
self.from_node.load(Ordering::Relaxed)
|
||||
}
|
||||
@@ -1573,7 +1574,9 @@ fn sync_wallet_data(wallet: &Wallet, from_node: bool) {
|
||||
|
||||
// Update wallet transactions.
|
||||
if update_txs(wallet, instance.clone(), info).is_ok() {
|
||||
wallet.from_node.store(from_node, Ordering::Relaxed);
|
||||
if !wallet.from_node.load(Ordering::Relaxed) {
|
||||
wallet.from_node.store(from_node, Ordering::Relaxed);
|
||||
}
|
||||
wallet.reset_sync_attempts();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user