From 561df4cebf53f118c67a731fa26448f843f1baf1 Mon Sep 17 00:00:00 2001 From: jjy Date: Thu, 16 Jan 2025 23:54:44 +0800 Subject: [PATCH] fix: pending connection dead lock --- Cargo.lock | 2 +- mutiny-core/src/node.rs | 4 +-- mutiny-core/src/peermanager.rs | 52 +++++++++++++++++++++++----------- mutiny-wasm/Cargo.toml | 2 +- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9735455b..e2aa03f70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1524,7 +1524,7 @@ dependencies = [ [[package]] name = "mutiny-wasm" -version = "1.10.28" +version = "1.10.29-rc1" dependencies = [ "anyhow", "async-trait", diff --git a/mutiny-core/src/node.rs b/mutiny-core/src/node.rs index bb35260ed..dc9ab3eab 100644 --- a/mutiny-core/src/node.rs +++ b/mutiny-core/src/node.rs @@ -95,7 +95,7 @@ use web_time::Instant; const INITIAL_RECONNECTION_DELAY: u64 = 2; const MAX_RECONNECTION_DELAY: u64 = 60; -pub(crate) type PendingConnections = Arc>>; +pub(crate) type PendingConnections = Arc>>; pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler< Arc>, @@ -846,7 +846,7 @@ impl NodeBuilder { }); log_trace!(logger, "finished spawning ldk background thread"); - let pending_connections = Arc::new(async_lock::RwLock::new(Default::default())); + let pending_connections = Arc::new(Mutex::new(Default::default())); if !self.do_not_connect_peers { #[cfg(target_arch = "wasm32")] diff --git a/mutiny-core/src/peermanager.rs b/mutiny-core/src/peermanager.rs index 4f2d89bdd..e2e711c9c 100644 --- a/mutiny-core/src/peermanager.rs +++ b/mutiny-core/src/peermanager.rs @@ -4,7 +4,7 @@ use crate::messagehandler::MutinyMessageHandler; use crate::networking::socket::{schedule_descriptor_read, MutinySocketDescriptor}; use crate::node::{NetworkGraph, OnionMessenger, PendingConnections}; use crate::storage::MutinyStorage; -use crate::utils; +use crate::utils::{self, sleep}; use crate::{error::MutinyError, fees::MutinyFeeEstimator}; use crate::{gossip, ldkstorage::PhantomChannelManager, logging::MutinyLogger}; use crate::{gossip::read_peer_info, node::PubkeyConnectionInfo}; @@ -382,23 +382,43 @@ pub(crate) async fn connect_peer_if_necessary< } let node_id = NodeId::from_pubkey(&peer_connection_info.pubkey); - let pending = pending_connections.read().await; - let now_secs = utils::now().as_secs() as u32; - let pending_expire_secs = now_secs - IGNORE_CONN_SECS; - if pending - .get(&node_id) - .is_some_and(|&last| pending_expire_secs < last) - { - return Ok(()); - } - // save pending connections - let mut pending = pending_connections.write().await; - pending.insert(node_id, now_secs); + let mut retries = 0; + let max_retries = 10; + while retries < max_retries { + match pending_connections.try_lock() { + Some(mut pending) => { + log::debug!("get pending connections"); + let now_secs = utils::now().as_secs() as u32; + let pending_expire_secs = now_secs - IGNORE_CONN_SECS; + if pending + .get(&node_id) + .is_some_and(|&last| pending_expire_secs < last) + { + log::debug!("Ignoring connection request to {node_id}"); + return Ok(()); + } + + // save pending connections + pending.insert(node_id, now_secs); - // clear expired pending connections - if pending.len() > 20 { - pending.retain(|_, last| pending_expire_secs < *last); + // clear expired pending connections + if pending.len() > 20 { + pending.retain(|_, last| pending_expire_secs < *last); + } + break; + } + None if retries > max_retries => { + log::error!("Can't get pending connections lock"); + return Err(MutinyError::ConnectionFailed); + } + None => { + retries += 1; + log::debug!("Can't get pending connections lock {retries}"); + sleep(200).await; + continue; + } + }; } // make sure we have the device lock before connecting diff --git a/mutiny-wasm/Cargo.toml b/mutiny-wasm/Cargo.toml index 5966ea678..4c0e61e01 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.10.28" +version = "1.10.29-rc1" edition = "2021" authors = ["utxostack"] forced-target = "wasm32-unknown-unknown"