Merge pull request #85 from ch1ru/main
authorvalentinewallace <valentinewallace@users.noreply.github.com>
Thu, 5 Jan 2023 17:14:43 +0000 (12:14 -0500)
committerGitHub <noreply@github.com>
Thu, 5 Jan 2023 17:14:43 +0000 (12:14 -0500)
Add `disconnectpeer` subcommand

1  2 
src/cli.rs

diff --combined src/cli.rs
index da6d97fb2587ae1e990d4203b0542a3261e7ee00,64ee04df71874ee24bfbd356f37ceb0ea0a85322..030109ecf792d353cf41b6adae34f58d3a05f946
@@@ -21,7 -21,7 +21,7 @@@ use lightning_invoice::{utils, Currency
  use std::env;
  use std::io;
  use std::io::Write;
 -use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
 +use std::net::{SocketAddr, ToSocketAddrs};
  use std::ops::Deref;
  use std::path::Path;
  use std::str::FromStr;
@@@ -40,6 -40,107 +40,6 @@@ pub(crate) struct LdkUserInfo 
        pub(crate) network: Network,
  }
  
 -pub(crate) fn parse_startup_args() -> Result<LdkUserInfo, ()> {
 -      if env::args().len() < 3 {
 -              println!("ldk-tutorial-node requires 3 arguments: `cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> ldk_storage_directory_path [<ldk-incoming-peer-listening-port>] [bitcoin-network] [announced-node-name announced-listen-addr*]`");
 -              return Err(());
 -      }
 -      let bitcoind_rpc_info = env::args().skip(1).next().unwrap();
 -      let bitcoind_rpc_info_parts: Vec<&str> = bitcoind_rpc_info.rsplitn(2, "@").collect();
 -      if bitcoind_rpc_info_parts.len() != 2 {
 -              println!("ERROR: bad bitcoind RPC URL provided");
 -              return Err(());
 -      }
 -      let rpc_user_and_password: Vec<&str> = bitcoind_rpc_info_parts[1].split(":").collect();
 -      if rpc_user_and_password.len() != 2 {
 -              println!("ERROR: bad bitcoind RPC username/password combo provided");
 -              return Err(());
 -      }
 -      let bitcoind_rpc_username = rpc_user_and_password[0].to_string();
 -      let bitcoind_rpc_password = rpc_user_and_password[1].to_string();
 -      let bitcoind_rpc_path: Vec<&str> = bitcoind_rpc_info_parts[0].split(":").collect();
 -      if bitcoind_rpc_path.len() != 2 {
 -              println!("ERROR: bad bitcoind RPC path provided");
 -              return Err(());
 -      }
 -      let bitcoind_rpc_host = bitcoind_rpc_path[0].to_string();
 -      let bitcoind_rpc_port = bitcoind_rpc_path[1].parse::<u16>().unwrap();
 -
 -      let ldk_storage_dir_path = env::args().skip(2).next().unwrap();
 -
 -      let mut ldk_peer_port_set = true;
 -      let ldk_peer_listening_port: u16 = match env::args().skip(3).next().map(|p| p.parse()) {
 -              Some(Ok(p)) => p,
 -              Some(Err(_)) => {
 -                      ldk_peer_port_set = false;
 -                      9735
 -              }
 -              None => {
 -                      ldk_peer_port_set = false;
 -                      9735
 -              }
 -      };
 -
 -      let mut arg_idx = match ldk_peer_port_set {
 -              true => 4,
 -              false => 3,
 -      };
 -      let network: Network = match env::args().skip(arg_idx).next().as_ref().map(String::as_str) {
 -              Some("testnet") => Network::Testnet,
 -              Some("regtest") => Network::Regtest,
 -              Some("signet") => Network::Signet,
 -              Some(net) => {
 -                      panic!("Unsupported network provided. Options are: `regtest`, `testnet`, and `signet`. Got {}", net);
 -              }
 -              None => Network::Testnet,
 -      };
 -
 -      let ldk_announced_node_name = match env::args().skip(arg_idx + 1).next().as_ref() {
 -              Some(s) => {
 -                      if s.len() > 32 {
 -                              panic!("Node Alias can not be longer than 32 bytes");
 -                      }
 -                      arg_idx += 1;
 -                      let mut bytes = [0; 32];
 -                      bytes[..s.len()].copy_from_slice(s.as_bytes());
 -                      bytes
 -              }
 -              None => [0; 32],
 -      };
 -
 -      let mut ldk_announced_listen_addr = Vec::new();
 -      loop {
 -              match env::args().skip(arg_idx + 1).next().as_ref() {
 -                      Some(s) => match IpAddr::from_str(s) {
 -                              Ok(IpAddr::V4(a)) => {
 -                                      ldk_announced_listen_addr
 -                                              .push(NetAddress::IPv4 { addr: a.octets(), port: ldk_peer_listening_port });
 -                                      arg_idx += 1;
 -                              }
 -                              Ok(IpAddr::V6(a)) => {
 -                                      ldk_announced_listen_addr
 -                                              .push(NetAddress::IPv6 { addr: a.octets(), port: ldk_peer_listening_port });
 -                                      arg_idx += 1;
 -                              }
 -                              Err(_) => panic!("Failed to parse announced-listen-addr into an IP address"),
 -                      },
 -                      None => break,
 -              }
 -      }
 -
 -      Ok(LdkUserInfo {
 -              bitcoind_rpc_username,
 -              bitcoind_rpc_password,
 -              bitcoind_rpc_host,
 -              bitcoind_rpc_port,
 -              ldk_storage_dir_path,
 -              ldk_peer_listening_port,
 -              ldk_announced_listen_addr,
 -              ldk_announced_node_name,
 -              network,
 -      })
 -}
 -
  struct UserOnionMessageContents {
        tlv_type: u64,
        data: Vec<u8>,
@@@ -256,6 -357,32 +256,32 @@@ pub(crate) async fn poll_for_user_input
                                                println!("SUCCESS: connected to peer {}", pubkey);
                                        }
                                }
+                               "disconnectpeer" => {
+                                       let peer_pubkey = words.next();
+                                       if peer_pubkey.is_none() {
+                                               println!("ERROR: disconnectpeer requires peer public key: `disconnectpeer <peer_pubkey>`");
+                                               continue;
+                                       }
+                                       let peer_pubkey =
+                                               match bitcoin::secp256k1::PublicKey::from_str(peer_pubkey.unwrap()) {
+                                                       Ok(pubkey) => pubkey,
+                                                       Err(e) => {
+                                                               println!("ERROR: {}", e.to_string());
+                                                               continue;
+                                                       }
+                                               };
+                                       if do_disconnect_peer(
+                                               peer_pubkey,
+                                               peer_manager.clone(),
+                                               channel_manager.clone(),
+                                       )
+                                       .is_ok()
+                                       {
+                                               println!("SUCCESS: disconnected from peer {}", peer_pubkey);
+                                       }
+                               }
                                "listchannels" => list_channels(&channel_manager, &network_graph),
                                "listpayments" => {
                                        list_payments(inbound_payments.clone(), outbound_payments.clone())
@@@ -429,6 -556,7 +455,7 @@@ fn help() 
        println!("      listchannels");
        println!("\n  Peers:");
        println!("      connectpeer pubkey@host:port");
+       println!("      disconnectpeer <peer_pubkey>");
        println!("      listpeers");
        println!("\n  Payments:");
        println!("      sendpayment <invoice>");
@@@ -587,6 -715,29 +614,29 @@@ pub(crate) async fn do_connect_peer
        }
  }
  
+ fn do_disconnect_peer(
+       pubkey: bitcoin::secp256k1::PublicKey, peer_manager: Arc<PeerManager>,
+       channel_manager: Arc<ChannelManager>,
+ ) -> Result<(), ()> {
+       //check for open channels with peer
+       for channel in channel_manager.list_channels() {
+               if channel.counterparty.node_id == pubkey {
+                       println!("Error: Node has an active channel with this peer, close any channels first");
+                       return Err(());
+               }
+       }
+       //check the pubkey matches a valid connected peer
+       let peers = peer_manager.get_peer_node_ids();
+       if !peers.contains(&pubkey) {
+               println!("Error: Could not find peer {}", pubkey);
+               return Err(());
+       }
+       peer_manager.disconnect_by_node_id(pubkey, false);
+       Ok(())
+ }
  fn open_channel(
        peer_pubkey: PublicKey, channel_amt_sat: u64, announced_channel: bool,
        channel_manager: Arc<ChannelManager>,