From b826243ac0c236096d63847753951d42936a2bd7 Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Fri, 21 Mar 2025 13:00:54 +0800 Subject: [PATCH 1/4] impl ConnectedPeerManager --- mutiny-core/src/lib.rs | 2 +- mutiny-core/src/messagehandler.rs | 11 ++++ mutiny-core/src/peermanager.rs | 90 +++++++++++++++++++++++++++++++ mutiny-wasm/src/lib.rs | 2 + 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/mutiny-core/src/lib.rs b/mutiny-core/src/lib.rs index c9fac490b..01448fb53 100644 --- a/mutiny-core/src/lib.rs +++ b/mutiny-core/src/lib.rs @@ -28,7 +28,7 @@ mod networking; mod node; pub mod nodemanager; mod onchain; -mod peermanager; +pub mod peermanager; pub mod scorer; pub mod storage; mod subscription; diff --git a/mutiny-core/src/messagehandler.rs b/mutiny-core/src/messagehandler.rs index 18f2e7c64..81d06769e 100644 --- a/mutiny-core/src/messagehandler.rs +++ b/mutiny-core/src/messagehandler.rs @@ -10,6 +10,7 @@ use lightning::util::ser::{Writeable, Writer}; use serde::{Deserialize, Serialize}; use crate::node::LiquidityManager; +use crate::peermanager::CONNECTED_PEER_MANAGER; use crate::storage::MutinyStorage; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] @@ -175,6 +176,14 @@ impl CustomMessageHandler for MutinyMessageHandler { msg: &lightning::ln::msgs::Init, inbound: bool, ) -> Result<(), ()> { + CONNECTED_PEER_MANAGER.add_peer( + *their_node_id, + inbound, + msg.remote_network_address + .as_ref() + .map(|addr| format!("{}", addr)), + ); + if let Some(cb) = self.ln_event_callback.clone() { let event = CommonLnEvent::OnConnect { their_node_id: their_node_id.to_string(), @@ -190,6 +199,8 @@ impl CustomMessageHandler for MutinyMessageHandler { } fn peer_disconnected(&self, their_node_id: &PublicKey) { + CONNECTED_PEER_MANAGER.remove_peer(their_node_id); + if let Some(cb) = self.ln_event_callback.clone() { let event = CommonLnEvent::OnDisconnect { their_node_id: their_node_id.to_string(), diff --git a/mutiny-core/src/peermanager.rs b/mutiny-core/src/peermanager.rs index 6faaa2abb..c547cfdad 100644 --- a/mutiny-core/src/peermanager.rs +++ b/mutiny-core/src/peermanager.rs @@ -24,8 +24,10 @@ 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::sync::atomic::AtomicBool; use std::sync::Arc; +use utils::Mutex; #[cfg(target_arch = "wasm32")] use crate::networking::ws_socket::WsTcpSocketDescriptor; @@ -36,6 +38,9 @@ use lightning::ln::peer_handler::SocketDescriptor as LdkSocketDescriptor; #[cfg(target_arch = "wasm32")] use crate::networking::proxy::WsProxy; +pub static CONNECTED_PEER_MANAGER: once_cell::sync::Lazy = + once_cell::sync::Lazy::new(ConnectedPeerManager::default); + #[allow(dead_code)] pub trait PeerManager: Send + Sync + 'static { fn get_peer_node_ids(&self) -> Vec; @@ -581,3 +586,88 @@ fn try_parse_addr_string(addr: &str) -> (Option, Option, + pub connected_at_timestamp: u64, +} + +pub struct ConnectedPeerManager { + peers: Arc>>, + logger: Mutex>>, +} + +impl Default for ConnectedPeerManager { + fn default() -> Self { + Self::new() + } +} + +impl ConnectedPeerManager { + pub fn new() -> Self { + Self { + peers: Arc::new(Mutex::new(HashMap::new())), + logger: Mutex::new(None), + } + } + + pub fn set_logger(&self, logger: Arc) { + let mut lock = self.logger.lock().unwrap(); + *lock = Some(logger); + } + + pub fn add_peer( + &self, + their_node_id: PublicKey, + inbound: bool, + remote_address: Option, + ) { + let timestamp = utils::now().as_secs(); + + let info = ConnectedPeerInfo { + inbound, + remote_address, + connected_at_timestamp: timestamp, + }; + + let mut peers = self.peers.lock().unwrap(); + let inserted = peers.insert(their_node_id, info).is_none(); + let logger = { + let guard = self.logger.lock().expect( + " + Failed to lock logger", + ); + guard.clone() + }; + if inserted { + if let Some(logger) = logger { + log_debug!(logger, "Connected to peer: {}", their_node_id); + } + } + } + + pub fn remove_peer(&self, their_node_id: &PublicKey) { + let mut peers = self.peers.lock().unwrap(); + let removed = peers.remove(their_node_id).is_some(); + + let logger = { + let guard = self.logger.lock().expect( + " + Failed to lock logger", + ); + guard.clone() + }; + if removed { + if let Some(logger) = logger { + log_debug!(logger, "Disconnected from peer: {}", their_node_id); + } + } + } + + pub fn is_any_connected(&self) -> bool { + let lock = self.peers.lock().unwrap(); + !lock.is_empty() + } +} diff --git a/mutiny-wasm/src/lib.rs b/mutiny-wasm/src/lib.rs index f231b2043..6f3016dfd 100644 --- a/mutiny-wasm/src/lib.rs +++ b/mutiny-wasm/src/lib.rs @@ -32,6 +32,7 @@ use mutiny_core::authmanager::AuthManager; use mutiny_core::encrypt::decrypt_with_password; use mutiny_core::error::MutinyError; use mutiny_core::messagehandler::{CommonLnEvent, CommonLnEventCallback}; +use mutiny_core::peermanager::CONNECTED_PEER_MANAGER; use mutiny_core::storage::{DeviceLock, MutinyStorage, DEVICE_LOCK_KEY}; use mutiny_core::utils::sleep; use mutiny_core::vss::{MutinyVssClient, VSS_MANAGER}; @@ -225,6 +226,7 @@ impl MutinyWallet { log_info!(logger, "Node version {version}"); VSS_MANAGER.set_logger(logger.clone()); + CONNECTED_PEER_MANAGER.set_logger(logger.clone()); let cipher = password .as_ref() From 2fdb4fb1d8b3d38717404daecff1c2d2c3e307c8 Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Fri, 21 Mar 2025 13:07:26 +0800 Subject: [PATCH 2/4] checking peer connection when update lnd snapshot --- mutiny-core/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mutiny-core/src/lib.rs b/mutiny-core/src/lib.rs index 01448fb53..7d07e83cb 100644 --- a/mutiny-core/src/lib.rs +++ b/mutiny-core/src/lib.rs @@ -51,6 +51,7 @@ use crate::messagehandler::CommonLnEventCallback; use crate::nodemanager::NodeManager; use crate::nodemanager::{ChannelClosure, MutinyBip21RawMaterials}; pub use crate::onchain::BroadcastTx1InMultiOut; +use crate::peermanager::CONNECTED_PEER_MANAGER; use crate::storage::{get_invoice_by_hash, DEVICE_LOCK_KEY, LND_CHANNELS_SNAPSHOT_KEY}; use crate::utils::{now, sleep, spawn, spawn_with_handle, StopHandle}; use crate::vss::VSS_MANAGER; @@ -847,9 +848,11 @@ impl MutinyWalletBuilder { }; let pending = VSS_MANAGER.get_pending_writes(); - if pending.is_empty() - || (pending.len() == 1 && pending.iter().any(|(key, _)| key == DEVICE_LOCK_KEY)) - { + 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(); + if can_update_snapshot { let second_lnd_snapshot = match fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger).await { From 1e4bc7e8cea778102d4fc06f1935c22638e8bf7a Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Fri, 21 Mar 2025 13:08:16 +0800 Subject: [PATCH 3/4] bump version to 1.14.5 --- Cargo.lock | 2 +- mutiny-wasm/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0ad2d91a..2aec593a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,7 +1525,7 @@ dependencies = [ [[package]] name = "mutiny-wasm" -version = "1.14.4" +version = "1.14.5" dependencies = [ "anyhow", "async-trait", diff --git a/mutiny-wasm/Cargo.toml b/mutiny-wasm/Cargo.toml index 395de77b7..70b648f08 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.4" +version = "1.14.5" edition = "2021" authors = ["utxostack"] forced-target = "wasm32-unknown-unknown" From b085502d1a685ad77af09661840c8636459405d4 Mon Sep 17 00:00:00 2001 From: EthanYuan Date: Sat, 22 Mar 2025 16:02:11 +0800 Subject: [PATCH 4/4] cargo fmt --- mutiny-core/src/peermanager.rs | 10 ++------- mutiny-core/src/vss.rs | 37 ++++++++++++++++------------------ 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/mutiny-core/src/peermanager.rs b/mutiny-core/src/peermanager.rs index c547cfdad..ab387f46b 100644 --- a/mutiny-core/src/peermanager.rs +++ b/mutiny-core/src/peermanager.rs @@ -635,10 +635,7 @@ impl ConnectedPeerManager { let mut peers = self.peers.lock().unwrap(); let inserted = peers.insert(their_node_id, info).is_none(); let logger = { - let guard = self.logger.lock().expect( - " - Failed to lock logger", - ); + let guard = self.logger.lock().expect("Failed to lock logger"); guard.clone() }; if inserted { @@ -653,10 +650,7 @@ impl ConnectedPeerManager { let removed = peers.remove(their_node_id).is_some(); let logger = { - let guard = self.logger.lock().expect( - " - Failed to lock logger", - ); + let guard = self.logger.lock().expect("Failed to lock logger"); guard.clone() }; if removed { diff --git a/mutiny-core/src/vss.rs b/mutiny-core/src/vss.rs index 92e61a393..b1f949718 100644 --- a/mutiny-core/src/vss.rs +++ b/mutiny-core/src/vss.rs @@ -250,10 +250,10 @@ impl VssManager { pub fn get_pending_writes(&self) -> Vec<(String, VssPendingWrite)> { self.check_timeout(); - let writes = self.pending_writes.lock().expect( - " - Failed to lock pending writes", - ); + let writes = self + .pending_writes + .lock() + .expect("Failed to lock pending writes"); writes.iter().map(|(k, v)| (k.clone(), v.clone())).collect() } @@ -271,33 +271,30 @@ impl VssManager { } pub fn on_complete_write(&self, key: String) { - let mut pending_writes = self.pending_writes.lock().expect( - " - Failed to lock pending writes", - ); + let mut pending_writes = self + .pending_writes + .lock() + .expect("Failed to lock pending writes"); pending_writes.remove(&key); } pub fn has_in_progress(&self) -> bool { self.check_timeout(); - let writes = self.pending_writes.lock().expect( - " - Failed to lock pending writes", - ); + let writes = self + .pending_writes + .lock() + .expect("Failed to lock pending writes"); !writes.is_empty() } fn check_timeout(&self) { let current_time = utils::now().as_secs(); - let mut writes = self.pending_writes.lock().expect( - " - Failed to lock pending writes", - ); + let mut writes = self + .pending_writes + .lock() + .expect("Failed to lock pending writes"); let logger = { - let guard = self.logger.lock().expect( - " - Failed to lock logger", - ); + let guard = self.logger.lock().expect("Failed to lock logger"); guard.clone() }; writes.retain(|key, write| {