Skip to content

Commit

Permalink
fix: pending connection dead lock
Browse files Browse the repository at this point in the history
  • Loading branch information
jjyr committed Jan 16, 2025
1 parent 85d7ca5 commit 561df4c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions mutiny-core/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<async_lock::RwLock<HashMap<NodeId, u32>>>;
pub(crate) type PendingConnections = Arc<Mutex<HashMap<NodeId, u32>>>;

pub(crate) type BumpTxEventHandler<S: MutinyStorage> = BumpTransactionEventHandler<
Arc<MutinyChain<S>>,
Expand Down Expand Up @@ -846,7 +846,7 @@ impl<S: MutinyStorage> NodeBuilder<S> {
});
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")]
Expand Down
52 changes: 36 additions & 16 deletions mutiny-core/src/peermanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion mutiny-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 561df4c

Please sign in to comment.