@@ -845,6 +845,79 @@ impl Node {
845845 self . channel_manager . list_channels ( )
846846 }
847847
848+ /// Connect to a node on the peer-to-peer network.
849+ ///
850+ /// If `permanently` is set to `true`, we'll remember the peer and reconnect to it on restart.
851+ pub fn connect_peer (
852+ & self , pubkey : & PublicKey , address : & SocketAddr , permanently : bool ,
853+ ) -> Result < ( ) , Error > {
854+ let runtime_lock = self . running . read ( ) . unwrap ( ) ;
855+ if runtime_lock. is_none ( ) {
856+ return Err ( Error :: NotRunning ) ;
857+ }
858+
859+ let runtime = runtime_lock. as_ref ( ) . unwrap ( ) ;
860+
861+ let peer_info = PeerInfo { pubkey : pubkey. clone ( ) , address : address. clone ( ) } ;
862+
863+ let con_peer_pubkey = peer_info. pubkey . clone ( ) ;
864+ let con_peer_addr = peer_info. address . clone ( ) ;
865+ let con_success = Arc :: new ( AtomicBool :: new ( false ) ) ;
866+ let con_success_cloned = Arc :: clone ( & con_success) ;
867+ let con_logger = Arc :: clone ( & self . logger ) ;
868+ let con_pm = Arc :: clone ( & self . peer_manager ) ;
869+
870+ tokio:: task:: block_in_place ( move || {
871+ runtime. tokio_runtime . block_on ( async move {
872+ let res =
873+ connect_peer_if_necessary ( con_peer_pubkey, con_peer_addr, con_pm, con_logger)
874+ . await ;
875+ con_success_cloned. store ( res. is_ok ( ) , Ordering :: Release ) ;
876+ } )
877+ } ) ;
878+
879+ if !con_success. load ( Ordering :: Acquire ) {
880+ return Err ( Error :: ConnectionFailed ) ;
881+ }
882+
883+ if permanently {
884+ self . peer_store . add_peer ( peer_info. clone ( ) ) ?;
885+ }
886+
887+ log_info ! ( self . logger, "Connected to peer {}@{}. " , peer_info. pubkey, peer_info. address, ) ;
888+
889+ Ok ( ( ) )
890+ }
891+
892+ /// Disconnects the peer with the given node id.
893+ ///
894+ /// Will also remove the peer from the peer store, i.e., after this has been called we won't
895+ /// try to reconnect on restart.
896+ pub fn disconnect_peer ( & self , counterparty_node_id : & str ) -> Result < ( ) , Error > {
897+ let runtime_lock = self . running . read ( ) . unwrap ( ) ;
898+ if runtime_lock. is_none ( ) {
899+ return Err ( Error :: NotRunning ) ;
900+ }
901+
902+ let node_id = match hex_utils:: to_compressed_pubkey ( counterparty_node_id) {
903+ Some ( node_id) => node_id,
904+ None => {
905+ log_error ! ( self . logger, "Failed to parse node id from {}" , counterparty_node_id, ) ;
906+ return Err ( Error :: PeerInfoParseFailed ) ;
907+ }
908+ } ;
909+
910+ log_info ! ( self . logger, "Disconnecting peer {}.." , node_id, ) ;
911+
912+ match self . peer_store . remove_peer ( & node_id) {
913+ Ok ( ( ) ) => { }
914+ Err ( e) => log_error ! ( self . logger, "Failed to remove peer {}: {}" , node_id, e) ,
915+ }
916+
917+ self . peer_manager . disconnect_by_node_id ( node_id) ;
918+ Ok ( ( ) )
919+ }
920+
848921 /// Connect to a node and open a new channel. Disconnects and re-connects are handled automatically
849922 ///
850923 /// Returns a temporary channel id
0 commit comments