diff --git a/gui/src/app/mod.rs b/gui/src/app/mod.rs index cc57fb89..4d818e68 100644 --- a/gui/src/app/mod.rs +++ b/gui/src/app/mod.rs @@ -63,7 +63,12 @@ impl Panels { ) -> Panels { Self { current: Menu::Home, - home: Home::new(wallet.clone(), &cache.coins, cache.blockheight), + home: Home::new( + wallet.clone(), + &cache.coins, + cache.blockheight, + daemon_backend.clone(), + ), coins: CoinsPanel::new(&cache.coins, wallet.main_descriptor.first_timelock_value()), transactions: TransactionsPanel::new(wallet.clone()), psbts: PsbtsPanel::new(wallet.clone()), @@ -242,7 +247,7 @@ impl App { pub fn stop(&mut self) { info!("Close requested"); - if self.daemon.backend() == DaemonBackend::EmbeddedLianad { + if self.daemon.backend().is_embedded() { if let Err(e) = Handle::current().block_on(async { self.daemon.stop().await }) { error!("{}", e); } else { diff --git a/gui/src/app/state/mod.rs b/gui/src/app/state/mod.rs index 6a4c8f13..d9e13729 100644 --- a/gui/src/app/state/mod.rs +++ b/gui/src/app/state/mod.rs @@ -23,9 +23,12 @@ use super::{cache::Cache, error::Error, menu::Menu, message::Message, view, wall pub const HISTORY_EVENT_PAGE_SIZE: u64 = 20; -use crate::daemon::{ - model::{remaining_sequence, Coin, HistoryTransaction, Labelled}, - Daemon, +use crate::{ + daemon::{ + model::{remaining_sequence, Coin, HistoryTransaction, Labelled}, + Daemon, DaemonBackend, + }, + node::NodeType, }; pub use coins::CoinsPanel; use label::LabelsEdited; @@ -66,9 +69,24 @@ pub fn redirect(menu: Menu) -> Command { }) } +fn wallet_is_syncing(daemon_backend: DaemonBackend, blockheight: i32) -> bool { + match daemon_backend { + // If user imported descriptor and is using a local bitcoind, a rescan + // will need to be performed in order to see past transactions and so the + // syncing status could be misleading as it could suggest the rescan is + // being performed. + // For external daemon or if we otherwise don't know the node type, + // treat it the same as bitcoind to be sure we don't mislead the user. + DaemonBackend::EmbeddedLianad(Some(NodeType::Bitcoind)) + | DaemonBackend::EmbeddedLianad(None) + | DaemonBackend::ExternalLianad => false, + _ => blockheight <= 0, + } +} + pub struct Home { wallet: Arc, - blockheight: i32, + wallet_is_syncing: bool, balance: Amount, unconfirmed_balance: Amount, remaining_sequence: Option, @@ -83,7 +101,12 @@ pub struct Home { } impl Home { - pub fn new(wallet: Arc, coins: &[Coin], blockheight: i32) -> Self { + pub fn new( + wallet: Arc, + coins: &[Coin], + blockheight: i32, + daemon_backend: DaemonBackend, + ) -> Self { let (balance, unconfirmed_balance) = coins.iter().fold( (Amount::from_sat(0), Amount::from_sat(0)), |(balance, unconfirmed_balance), coin| { @@ -97,9 +120,11 @@ impl Home { }, ); + let wallet_is_syncing = wallet_is_syncing(daemon_backend, blockheight); + Self { wallet, - blockheight, + wallet_is_syncing, balance, unconfirmed_balance, remaining_sequence: None, @@ -113,10 +138,6 @@ impl Home { processing: false, } } - - fn wallet_is_syncing(&self) -> bool { - self.blockheight <= 0 - } } impl State for Home { @@ -148,7 +169,7 @@ impl State for Home { &self.events, self.is_last_page, self.processing, - self.wallet_is_syncing(), + self.wallet_is_syncing, ), ) } @@ -226,10 +247,10 @@ impl State for Home { } }, Message::UpdatePanelCache(is_current, Ok(cache)) => { - let wallet_was_syncing = self.wallet_is_syncing(); - self.blockheight = cache.blockheight; + let wallet_was_syncing = self.wallet_is_syncing; + self.wallet_is_syncing = wallet_is_syncing(daemon.backend(), cache.blockheight); // If this is the current panel, reload it if wallet is no longer syncing. - if is_current && wallet_was_syncing && !self.wallet_is_syncing() { + if is_current && wallet_was_syncing && !self.wallet_is_syncing { return self.reload(daemon, self.wallet.clone()); } } @@ -310,7 +331,7 @@ impl State for Home { wallet: Arc, ) -> Command { // Wait for wallet to finish syncing before reloading data. - if self.wallet_is_syncing() { + if self.wallet_is_syncing { return Command::none(); } self.selected_event = None; diff --git a/gui/src/app/state/settings/mod.rs b/gui/src/app/state/settings/mod.rs index ef2b3596..d8c6505f 100644 --- a/gui/src/app/state/settings/mod.rs +++ b/gui/src/app/state/settings/mod.rs @@ -62,7 +62,7 @@ impl State for SettingsState { BitcoindSettingsState::new( daemon.config().cloned(), cache, - daemon.backend() != DaemonBackend::EmbeddedLianad, + !daemon.backend().is_embedded(), self.internal_bitcoind, ) .into(), diff --git a/gui/src/daemon/embedded.rs b/gui/src/daemon/embedded.rs index 06f6203c..c4f77d7a 100644 --- a/gui/src/daemon/embedded.rs +++ b/gui/src/daemon/embedded.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use std::path::Path; use tokio::sync::Mutex; -use super::{model::*, Daemon, DaemonBackend, DaemonError}; +use super::{model::*, node, Daemon, DaemonBackend, DaemonError}; use async_trait::async_trait; use liana::{ commands::{CoinStatus, LabelItem}, @@ -51,7 +51,12 @@ impl std::fmt::Debug for EmbeddedDaemon { #[async_trait] impl Daemon for EmbeddedDaemon { fn backend(&self) -> DaemonBackend { - DaemonBackend::EmbeddedLianad + let node_type = self + .config + .bitcoin_backend + .as_ref() + .map(node::NodeType::from); + DaemonBackend::EmbeddedLianad(node_type) } fn config(&self) -> Option<&Config> { diff --git a/gui/src/daemon/mod.rs b/gui/src/daemon/mod.rs index 863a82ef..d4413ac6 100644 --- a/gui/src/daemon/mod.rs +++ b/gui/src/daemon/mod.rs @@ -20,7 +20,7 @@ use liana::{ StartupError, }; -use crate::hw::HardwareWalletConfig; +use crate::{hw::HardwareWalletConfig, node}; #[derive(Debug)] pub enum DaemonError { @@ -62,11 +62,17 @@ impl std::fmt::Display for DaemonError { #[derive(Debug, Clone, PartialEq, Eq)] pub enum DaemonBackend { - EmbeddedLianad, + EmbeddedLianad(Option), ExternalLianad, RemoteBackend, } +impl DaemonBackend { + pub fn is_embedded(&self) -> bool { + matches!(self, DaemonBackend::EmbeddedLianad(_)) + } +} + #[async_trait] pub trait Daemon: Debug { fn backend(&self) -> DaemonBackend; diff --git a/gui/src/loader.rs b/gui/src/loader.rs index 91080545..f08b59d7 100644 --- a/gui/src/loader.rs +++ b/gui/src/loader.rs @@ -22,7 +22,6 @@ use liana_ui::{ widget::*, }; -use crate::daemon::DaemonBackend; use crate::{ app::{ cache::Cache, @@ -227,7 +226,7 @@ impl Loader { pub fn stop(&mut self) { info!("Close requested"); if let Step::Syncing { daemon, .. } = &mut self.step { - if daemon.backend() == DaemonBackend::EmbeddedLianad { + if daemon.backend().is_embedded() { info!("Stopping internal daemon..."); if let Err(e) = Handle::current().block_on(async { daemon.stop().await }) { warn!("Internal daemon failed to stop: {}", e); diff --git a/gui/src/node/mod.rs b/gui/src/node/mod.rs index 293a6526..70aabae3 100644 --- a/gui/src/node/mod.rs +++ b/gui/src/node/mod.rs @@ -1,3 +1,5 @@ +use liana::config::BitcoinBackend; + pub mod bitcoind; pub mod electrum; @@ -6,3 +8,12 @@ pub enum NodeType { Bitcoind, Electrum, } + +impl From<&BitcoinBackend> for NodeType { + fn from(bitcoin_backend: &BitcoinBackend) -> Self { + match bitcoin_backend { + BitcoinBackend::Bitcoind(_) => Self::Bitcoind, + BitcoinBackend::Electrum(_) => Self::Electrum, + } + } +}