Auto-reconnect peers every second
authorMatt Corallo <git@bluematt.me>
Thu, 11 Nov 2021 17:54:42 +0000 (17:54 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 12 Nov 2021 04:42:08 +0000 (04:42 +0000)
src/cli.rs
src/main.rs

index 0bea87041252b9b0cfcca134a8cf52a2cbb2fe16..d34512c56e3dc31b52b9e95f7d8bccb99d7583ce 100644 (file)
@@ -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<PeerManager>,
+) -> 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(
index 421069b804ed2aae75ebecc35389a4a4705203f0..39237d844d6969ddc341d8b5c2f802b423f4ba51 100644 (file)
@@ -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.