diff --git a/Cargo.lock b/Cargo.lock index 2aec593a3..28a6a4374 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,7 +1525,7 @@ dependencies = [ [[package]] name = "mutiny-wasm" -version = "1.14.5" +version = "1.14.6" dependencies = [ "anyhow", "async-trait", diff --git a/mutiny-core/src/lib.rs b/mutiny-core/src/lib.rs index 7d07e83cb..818c0d5a9 100644 --- a/mutiny-core/src/lib.rs +++ b/mutiny-core/src/lib.rs @@ -46,7 +46,9 @@ pub use crate::ldkstorage::{ ACTIVE_NODE_ID_KEY, CHANNEL_CLOSURE_BUMP_PREFIX, CHANNEL_CLOSURE_PREFIX, CHANNEL_MANAGER_KEY, MONITORS_PREFIX_KEY, }; -use crate::lsp::lndchannel::fetch_lnd_channels_snapshot; +use crate::lsp::lndchannel::{ + fetch_lnd_channels, fetch_lnd_channels_snapshot, LndChannelsSnapshot, +}; use crate::messagehandler::CommonLnEventCallback; use crate::nodemanager::NodeManager; use crate::nodemanager::{ChannelClosure, MutinyBip21RawMaterials}; @@ -835,11 +837,12 @@ impl MutinyWalletBuilder { return; }; - let first_lnd_snapshot = - match fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger).await { - Ok(snapshot) => { - log_debug!(logger, "First fetched lnd snapshot: {:?}", snapshot); - snapshot + let (lnd_channels, first_lnd_snapshot) = + match fetch_lnd_channels(&Client::new(), lsp_url, &node_id, &logger).await { + Ok(lnd_channels) => { + let lnd_snapshot: LndChannelsSnapshot = lnd_channels.clone().into(); + log_debug!(logger, "First fetched lnd snapshot: {:?}", lnd_snapshot); + (lnd_channels, lnd_snapshot) } Err(e) => { log_error!(logger, "First lnd snapshot fetch failed: {e}"); @@ -851,7 +854,7 @@ impl MutinyWalletBuilder { let only_device_lock_vss_pending = pending.len() == 1 && pending.iter().any(|(key, _)| key == DEVICE_LOCK_KEY); let can_update_snapshot = (pending.is_empty() || only_device_lock_vss_pending) - && CONNECTED_PEER_MANAGER.is_any_connected(); + && CONNECTED_PEER_MANAGER.validate_peer_connections(&lnd_channels); if can_update_snapshot { let second_lnd_snapshot = match fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger).await diff --git a/mutiny-core/src/lsp/lndchannel.rs b/mutiny-core/src/lsp/lndchannel.rs index 52effeb77..ec39d58f0 100644 --- a/mutiny-core/src/lsp/lndchannel.rs +++ b/mutiny-core/src/lsp/lndchannel.rs @@ -23,6 +23,7 @@ pub struct ChannelConstraints { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct LndChannel { pub active: bool, + pub local_pubkey: String, pub remote_pubkey: String, pub channel_point: String, pub chan_id: String, diff --git a/mutiny-core/src/peermanager.rs b/mutiny-core/src/peermanager.rs index ab387f46b..d6b84a309 100644 --- a/mutiny-core/src/peermanager.rs +++ b/mutiny-core/src/peermanager.rs @@ -1,4 +1,5 @@ use crate::keymanager::PhantomKeysManager; +use crate::lsp::lndchannel::LndChannel; use crate::messagehandler::CommonLnEvent; use crate::messagehandler::MutinyMessageHandler; #[cfg(target_arch = "wasm32")] @@ -24,7 +25,8 @@ use lightning::routing::gossip::NodeId; use lightning::util::logger::Logger; use lightning::{ln::msgs::SocketAddress, log_warn}; use lightning::{log_debug, log_error}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use std::str::FromStr; use std::sync::atomic::AtomicBool; use std::sync::Arc; use utils::Mutex; @@ -660,8 +662,43 @@ impl ConnectedPeerManager { } } - pub fn is_any_connected(&self) -> bool { - let lock = self.peers.lock().unwrap(); - !lock.is_empty() + pub fn validate_peer_connections(&self, channels: &[LndChannel]) -> bool { + let (peers_of_active_channels, valid) = + channels + .iter() + .fold( + (HashSet::new(), true), + |(mut s, valid), c| match PublicKey::from_str(&c.local_pubkey) { + Ok(k) => { + s.insert(k); + (s, valid) + } + Err(e) => { + if let Some(l) = &*self.logger.lock().unwrap() { + log_warn!(l, "Invalid local_pubkey in {}: {}", c.chan_id, e); + } + (s, false) + } + }, + ); + if !valid { + return false; + } + + let peers_in_manager = { + let peers = self.peers.lock().unwrap(); + peers.keys().cloned().collect::>() + }; + + let is_match = peers_of_active_channels.is_subset(&peers_in_manager); + if !is_match { + if let Some(l) = &*self.logger.lock().unwrap() { + peers_of_active_channels + .difference(&peers_in_manager) + .for_each(|pk| log_warn!(l, "Missing peer: {}", pk)); + } + } + + is_match } } diff --git a/mutiny-wasm/Cargo.toml b/mutiny-wasm/Cargo.toml index 70b648f08..8eb9ad3d2 100644 --- a/mutiny-wasm/Cargo.toml +++ b/mutiny-wasm/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["per-package-target"] [package] name = "mutiny-wasm" -version = "1.14.5" +version = "1.14.6" edition = "2021" authors = ["utxostack"] forced-target = "wasm32-unknown-unknown"