From: Matt Corallo Date: Thu, 11 Nov 2021 17:54:42 +0000 (+0000) Subject: Auto-reconnect peers every second X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=7d0af178ba9a79008af7b3ea89e563749f8f7252;p=ldk-sample Auto-reconnect peers every second --- diff --git a/src/cli.rs b/src/cli.rs index 0bea870..d34512c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -492,6 +492,16 @@ pub(crate) async fn connect_peer_if_necessary( return Ok(()); } } + let res = do_connect_peer(pubkey, peer_addr, peer_manager).await; + if res.is_err() { + println!("ERROR: failed to connect to peer"); + } + res +} + +pub(crate) async fn do_connect_peer( + pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc, +) -> Result<(), ()> { match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), pubkey, peer_addr).await { Some(connection_closed_future) => { @@ -499,24 +509,19 @@ pub(crate) async fn connect_peer_if_necessary( loop { match futures::poll!(&mut connection_closed_future) { std::task::Poll::Ready(_) => { - println!("ERROR: Peer disconnected before we finished the handshake"); return Err(()); } std::task::Poll::Pending => {} } // Avoid blocking the tokio context by sleeping a bit match peer_manager.get_peer_node_ids().iter().find(|id| **id == pubkey) { - Some(_) => break, + Some(_) => return Ok(()), None => tokio::time::sleep(Duration::from_millis(10)).await, } } } - None => { - println!("ERROR: failed to connect to peer"); - return Err(()); - } + None => Err(()), } - Ok(()) } fn open_channel( diff --git a/src/main.rs b/src/main.rs index 421069b..39237d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -641,22 +641,39 @@ async fn start_ldk() { logger.clone(), ); - // Reconnect to channel peers if possible. + // Regularly reconnect to channel peers. + let connect_cm = Arc::clone(&channel_manager); + let connect_pm = Arc::clone(&peer_manager); let peer_data_path = format!("{}/channel_peer_data", ldk_data_dir.clone()); - match disk::read_channel_peer_data(Path::new(&peer_data_path)) { - Ok(mut info) => { - for (pubkey, peer_addr) in info.drain() { - for chan_info in channel_manager.list_channels() { - if pubkey == chan_info.counterparty.node_id { - let _ = - cli::connect_peer_if_necessary(pubkey, peer_addr, peer_manager.clone()) + tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(1)); + loop { + interval.tick().await; + match disk::read_channel_peer_data(Path::new(&peer_data_path)) { + Ok(info) => { + let peers = connect_pm.get_peer_node_ids(); + for node_id in connect_cm + .list_channels() + .iter() + .map(|chan| chan.counterparty.node_id) + .filter(|id| !peers.contains(id)) + { + for (pubkey, peer_addr) in info.iter() { + if *pubkey == node_id { + let _ = cli::do_connect_peer( + *pubkey, + peer_addr.clone(), + Arc::clone(&connect_pm), + ) .await; + } + } } } + Err(e) => println!("ERROR: errored reading channel peer info from disk: {:?}", e), } } - Err(e) => println!("ERROR: errored reading channel peer info from disk: {:?}", e), - } + }); // Regularly broadcast our node_announcement. This is only required (or possible) if we have // some public channels, and is only useful if we have public listen address(es) to announce.