diff --git a/src/backend_task/core/mod.rs b/src/backend_task/core/mod.rs index a4c9bd368..faa3c1e51 100644 --- a/src/backend_task/core/mod.rs +++ b/src/backend_task/core/mod.rs @@ -2,15 +2,18 @@ mod refresh_wallet_info; mod start_dash_qt; use crate::backend_task::BackendTaskSuccessResult; +use crate::config::Config; use crate::context::AppContext; use crate::model::wallet::Wallet; use dash_sdk::dashcore_rpc::RpcApi; +use dash_sdk::dashcore_rpc::{Auth, Client}; use dash_sdk::dpp::dashcore::{Address, ChainLock, Network, OutPoint, Transaction, TxOut}; use std::sync::{Arc, RwLock}; #[derive(Debug, Clone)] pub(crate) enum CoreTask { GetBestChainLock, + GetBestChainLocks, RefreshWalletInfo(Arc>), StartDashQT(Network, Option, bool), } @@ -18,6 +21,7 @@ impl PartialEq for CoreTask { fn eq(&self, other: &Self) -> bool { match (self, other) { (CoreTask::GetBestChainLock, CoreTask::GetBestChainLock) => true, + (CoreTask::GetBestChainLocks, CoreTask::GetBestChainLocks) => true, (CoreTask::RefreshWalletInfo(_), CoreTask::RefreshWalletInfo(_)) => true, (CoreTask::StartDashQT(_, _, _), CoreTask::StartDashQT(_, _, _)) => true, _ => false, @@ -29,6 +33,7 @@ impl PartialEq for CoreTask { pub(crate) enum CoreItem { ReceivedAvailableUTXOTransaction(Transaction, Vec<(OutPoint, TxOut, Address)>), ChainLock(ChainLock, Network), + ChainLocks(Option, Option), // Mainnet, Testnet } impl AppContext { @@ -44,6 +49,87 @@ impl AppContext { )) }) .map_err(|e| e.to_string()), + CoreTask::GetBestChainLocks => { + tracing::info!("Getting best chain locks for testnet and mainnet"); + + // Load configs + let config = match Config::load() { + Ok(config) => config, + Err(e) => { + return Err(format!("Failed to load config: {}", e)); + } + }; + let maybe_mainnet_config = config.config_for_network(Network::Dash); + let maybe_testnet_config = config.config_for_network(Network::Testnet); + + // Get mainnet best chainlock + let mainnet_result = if let Some(mainnet_config) = maybe_mainnet_config { + let mainnet_addr = format!( + "http://{}:{}", + mainnet_config.core_host, mainnet_config.core_rpc_port + ); + let mainnet_client = Client::new( + &mainnet_addr, + Auth::UserPass( + mainnet_config.core_rpc_user.to_string(), + mainnet_config.core_rpc_password.to_string(), + ), + ) + .map_err(|_| "Failed to create mainnet client".to_string())?; + mainnet_client.get_best_chain_lock().map_err(|e| { + format!( + "Failed to get best chain lock for mainnet: {}", + e.to_string() + ) + }) + } else { + Err("Mainnet config not found".to_string()) + }; + + // Get testnet best chainlock + let testnet_result = if let Some(testnet_config) = maybe_testnet_config { + let testnet_addr = format!( + "http://{}:{}", + testnet_config.core_host, testnet_config.core_rpc_port + ); + let testnet_client = Client::new( + &testnet_addr, + Auth::UserPass( + testnet_config.core_rpc_user.to_string(), + testnet_config.core_rpc_password.to_string(), + ), + ) + .map_err(|_| "Failed to create testnet client".to_string())?; + testnet_client.get_best_chain_lock().map_err(|e| { + format!( + "Failed to get best chain lock for testnet: {}", + e.to_string() + ) + }) + } else { + Err("Testnet config not found".to_string()) + }; + + // Handle results + match (mainnet_result, testnet_result) { + (Ok(mainnet_chainlock), Ok(testnet_chainlock)) => { + Ok(BackendTaskSuccessResult::CoreItem(CoreItem::ChainLocks( + Some(mainnet_chainlock), + Some(testnet_chainlock), + ))) + } + (Ok(mainnet_chainlock), Err(_)) => Ok(BackendTaskSuccessResult::CoreItem( + CoreItem::ChainLocks(Some(mainnet_chainlock), None), + )), + (Err(_), Ok(testnet_chainlock)) => Ok(BackendTaskSuccessResult::CoreItem( + CoreItem::ChainLocks(None, Some(testnet_chainlock)), + )), + (Err(_), Err(_)) => { + Err("Failed to get best chain lock for both mainnet and testnet" + .to_string()) + } + } + } CoreTask::RefreshWalletInfo(wallet) => self.refresh_wallet_info(wallet), CoreTask::StartDashQT(network, custom_dash_qt, overwrite_dash_conf) => self .start_dash_qt(network, custom_dash_qt, overwrite_dash_conf) diff --git a/src/ui/network_chooser_screen.rs b/src/ui/network_chooser_screen.rs index 98e35a781..8ce7f4702 100644 --- a/src/ui/network_chooser_screen.rs +++ b/src/ui/network_chooser_screen.rs @@ -2,12 +2,10 @@ use crate::app::AppAction; use crate::backend_task::core::{CoreItem, CoreTask}; use crate::backend_task::{BackendTask, BackendTaskSuccessResult}; use crate::context::AppContext; -use crate::model::password_info::PasswordInfo; use crate::ui::components::left_panel::add_left_panel; use crate::ui::components::top_panel::add_top_panel; use crate::ui::wallet::add_new_wallet_screen::AddNewWalletScreen; use crate::ui::{RootScreenType, Screen, ScreenLike}; -use dash_sdk::dashcore_rpc::RpcApi; use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::identity::TimestampMillis; use eframe::egui::{self, Color32, Context, Ui}; @@ -20,7 +18,6 @@ pub struct NetworkChooserScreen { pub current_network: Network, pub mainnet_core_status_online: bool, pub testnet_core_status_online: bool, - status_checked: bool, pub recheck_time: Option, custom_dash_qt_path: Option, custom_dash_qt_error_message: Option, @@ -41,7 +38,6 @@ impl NetworkChooserScreen { current_network, mainnet_core_status_online: false, testnet_core_status_online: false, - status_checked: false, recheck_time: None, custom_dash_qt_path, custom_dash_qt_error_message: None, @@ -63,11 +59,6 @@ impl NetworkChooserScreen { self.context_for_network(self.current_network) } - /// Function to check the status of Dash Core for a given network - async fn check_core_status(app_context: &Arc) -> bool { - app_context.core_client.get_best_chain_lock().is_ok() - } - /// Render the network selection table fn render_network_table(&mut self, ui: &mut Ui) -> AppAction { let mut app_action = AppAction::None; @@ -85,10 +76,10 @@ impl NetworkChooserScreen { ui.label("Start"); ui.end_row(); - // Render Mainnet + // Render Mainnet Row app_action |= self.render_network_row(ui, Network::Dash, "Mainnet"); - // Render Testnet + // Render Testnet Row app_action |= self.render_network_row(ui, Network::Testnet, "Testnet"); }); egui::CollapsingHeader::new("Show more advanced settings") @@ -170,23 +161,11 @@ impl NetworkChooserScreen { let mut app_action = AppAction::None; ui.label(name); - // Simulate checking network status + // Check network status let is_working = self.check_network_status(network); let status_color = if is_working { Color32::from_rgb(0, 255, 0) // Green if working } else { - if let Some(recheck_time) = self.recheck_time { - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards"); - let current_time_ms = current_time.as_millis() as u64; - if current_time_ms >= recheck_time { - app_action |= - AppAction::BackendTask(BackendTask::CoreTask(CoreTask::GetBestChainLock)); - self.recheck_time = - Some((current_time + Duration::from_secs(5)).as_millis() as u64); - } - } Color32::from_rgb(255, 0, 0) // Red if not working }; @@ -216,7 +195,7 @@ impl NetworkChooserScreen { } else { &self.testnet_app_context.as_ref().unwrap() }; - app_action |= + app_action = AppAction::AddScreen(Screen::AddNewWalletScreen(AddNewWalletScreen::new(context))); } @@ -225,7 +204,7 @@ impl NetworkChooserScreen { if ui.checkbox(&mut is_selected, "Select").clicked() && is_selected { self.current_network = network; app_action = AppAction::SwitchNetwork(network); - // in 1 second + // Recheck in 1 second self.recheck_time = Some( (SystemTime::now() .duration_since(UNIX_EPOCH) @@ -237,26 +216,18 @@ impl NetworkChooserScreen { // Add a button to start the network if ui.button("Start").clicked() { - app_action |= AppAction::BackendTask(BackendTask::CoreTask(CoreTask::StartDashQT( + app_action = AppAction::BackendTask(BackendTask::CoreTask(CoreTask::StartDashQT( network, self.custom_dash_qt_path.clone(), self.overwrite_dash_conf, ))); - // in 5 seconds - self.recheck_time = Some( - (SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards") - + Duration::from_secs(5)) - .as_millis() as u64, - ); } ui.end_row(); app_action } - /// Simulate a function to check if the network is working + /// Check if the network is working fn check_network_status(&self, network: Network) -> bool { match network { Network::Dash => self.mainnet_core_status_online, @@ -267,23 +238,33 @@ impl NetworkChooserScreen { } impl ScreenLike for NetworkChooserScreen { + fn display_message(&mut self, message: &str, _message_type: super::MessageType) { + if message.contains("Failed to get best chain lock for both mainnet and testnet") { + self.mainnet_core_status_online = false; + self.testnet_core_status_online = false; + } + } + fn display_task_result(&mut self, backend_task_success_result: BackendTaskSuccessResult) { - if let BackendTaskSuccessResult::CoreItem(CoreItem::ChainLock(_, network)) = - backend_task_success_result - { - match network { - Network::Dash => { - self.mainnet_core_status_online = true; + match backend_task_success_result { + BackendTaskSuccessResult::CoreItem(CoreItem::ChainLocks( + mainnet_chainlock, + testnet_chainlock, + )) => { + match mainnet_chainlock { + Some(_) => self.mainnet_core_status_online = true, + None => self.mainnet_core_status_online = false, } - Network::Testnet => { - self.testnet_core_status_online = true; + match testnet_chainlock { + Some(_) => self.testnet_core_status_online = true, + None => self.testnet_core_status_online = false, } - _ => {} } + _ => {} } } + fn ui(&mut self, ctx: &Context) -> AppAction { - //let _ = self.current_app_context().db.get_settings(); let mut action = add_top_panel( ctx, self.current_app_context(), @@ -291,11 +272,6 @@ impl ScreenLike for NetworkChooserScreen { vec![], ); - if !self.status_checked { - self.status_checked = true; - action |= AppAction::BackendTask(BackendTask::CoreTask(CoreTask::GetBestChainLock)); - } - action |= add_left_panel( ctx, self.current_app_context(), @@ -306,6 +282,23 @@ impl ScreenLike for NetworkChooserScreen { action |= self.render_network_table(ui); }); + // Recheck both network status every 3 seconds + let recheck_time = Duration::from_secs(3); + if action == AppAction::None { + let current_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards"); + if let Some(time) = self.recheck_time { + if current_time.as_millis() as u64 >= time { + action = + AppAction::BackendTask(BackendTask::CoreTask(CoreTask::GetBestChainLocks)); + self.recheck_time = Some((current_time + recheck_time).as_millis() as u64); + } + } else { + self.recheck_time = Some((current_time + recheck_time).as_millis() as u64); + } + } + action } }