@@ -431,6 +431,26 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
431431 fn disconnect_socket ( & mut self ) ;
432432}
433433
434+ /// Details of a connected peer as returned by [`PeerManager::list_peers`].
435+ pub struct PeerDetails {
436+ /// The node id of the peer.
437+ ///
438+ /// For outbound connections, this [`PublicKey`] will be the same as the `their_node_id` parameter
439+ /// passed in to [`PeerManager::new_outbound_connection`].
440+ pub counterparty_node_id : PublicKey ,
441+ /// The socket address the peer provided in the initial handshake.
442+ ///
443+ /// Will only be `Some` if an address had been previously provided to
444+ /// [`PeerManager::new_outbound_connection`] or [`PeerManager::new_inbound_connection`].
445+ pub socket_address : Option < SocketAddress > ,
446+ /// The features the peer provided in the initial handshake.
447+ pub init_features : InitFeatures ,
448+ /// Indicates the direction of the peer connection.
449+ ///
450+ /// Will be `true` for inbound connections, and `false` for outbound connections.
451+ pub is_inbound_connection : bool ,
452+ }
453+
434454/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
435455/// generate no further read_event/write_buffer_space_avail/socket_disconnected calls for the
436456/// descriptor.
@@ -958,27 +978,60 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
958978 }
959979 }
960980
961- /// Get a list of tuples mapping from node id to network addresses for peers which have
962- /// completed the initial handshake.
963- ///
964- /// For outbound connections, the [`PublicKey`] will be the same as the `their_node_id` parameter
965- /// passed in to [`Self::new_outbound_connection`], however entries will only appear once the initial
966- /// handshake has completed and we are sure the remote peer has the private key for the given
967- /// [`PublicKey`].
968- ///
969- /// The returned `Option`s will only be `Some` if an address had been previously given via
970- /// [`Self::new_outbound_connection`] or [`Self::new_inbound_connection`].
971- pub fn get_peer_node_ids ( & self ) -> Vec < ( PublicKey , Option < SocketAddress > ) > {
981+ /// Returns a list of [`PeerDetails`] for connected peers that have completed the initial
982+ /// handshake.
983+ pub fn list_peers ( & self ) -> Vec < PeerDetails > {
972984 let peers = self . peers . read ( ) . unwrap ( ) ;
973985 peers. values ( ) . filter_map ( |peer_mutex| {
974986 let p = peer_mutex. lock ( ) . unwrap ( ) ;
975987 if !p. handshake_complete ( ) {
976988 return None ;
977989 }
978- Some ( ( p. their_node_id . unwrap ( ) . 0 , p. their_socket_address . clone ( ) ) )
990+ let details = PeerDetails {
991+ // unwrap safety: their_node_id is guaranteed to be `Some` after the handshake
992+ // completed.
993+ counterparty_node_id : p. their_node_id . unwrap ( ) . 0 ,
994+ socket_address : p. their_socket_address . clone ( ) ,
995+ // unwrap safety: their_features is guaranteed to be `Some` after the handshake
996+ // completed.
997+ init_features : p. their_features . clone ( ) . unwrap ( ) ,
998+ is_inbound_connection : p. inbound_connection ,
999+ } ;
1000+ Some ( details)
9791001 } ) . collect ( )
9801002 }
9811003
1004+ /// Returns the [`PeerDetails`] of a connected peer that has completed the initial handshake.
1005+ ///
1006+ /// Will return `None` if the peer is unknown or it hasn't completed the initial handshake.
1007+ pub fn peer_by_node_id ( & self , their_node_id : & PublicKey ) -> Option < PeerDetails > {
1008+ let peers = self . peers . read ( ) . unwrap ( ) ;
1009+ peers. values ( ) . find_map ( |peer_mutex| {
1010+ let p = peer_mutex. lock ( ) . unwrap ( ) ;
1011+ if !p. handshake_complete ( ) {
1012+ return None ;
1013+ }
1014+
1015+ // unwrap safety: their_node_id is guaranteed to be `Some` after the handshake
1016+ // completed.
1017+ let counterparty_node_id = p. their_node_id . unwrap ( ) . 0 ;
1018+
1019+ if counterparty_node_id != * their_node_id {
1020+ return None ;
1021+ }
1022+
1023+ let details = PeerDetails {
1024+ counterparty_node_id,
1025+ socket_address : p. their_socket_address . clone ( ) ,
1026+ // unwrap safety: their_features is guaranteed to be `Some` after the handshake
1027+ // completed.
1028+ init_features : p. their_features . clone ( ) . unwrap ( ) ,
1029+ is_inbound_connection : p. inbound_connection ,
1030+ } ;
1031+ Some ( details)
1032+ } )
1033+ }
1034+
9821035 fn get_ephemeral_key ( & self ) -> SecretKey {
9831036 let mut ephemeral_hash = self . ephemeral_key_midstate . clone ( ) ;
9841037 let counter = self . peer_counter . get_increment ( ) ;
@@ -2746,6 +2799,8 @@ mod tests {
27462799 } ;
27472800 let addr_a = SocketAddress :: TcpIpV4 { addr : [ 127 , 0 , 0 , 1 ] , port : 1000 } ;
27482801 let id_b = peer_b. node_signer . get_node_id ( Recipient :: Node ) . unwrap ( ) ;
2802+ let features_a = peer_a. init_features ( & id_b) ;
2803+ let features_b = peer_b. init_features ( & id_a) ;
27492804 let mut fd_b = FileDescriptor {
27502805 fd : 1 , outbound_data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
27512806 disconnect : Arc :: new ( AtomicBool :: new ( false ) ) ,
@@ -2767,8 +2822,8 @@ mod tests {
27672822 let a_data = fd_a. outbound_data . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
27682823 assert_eq ! ( peer_b. read_event( & mut fd_b, & a_data) . unwrap( ) , false ) ;
27692824
2770- assert ! ( peer_a. get_peer_node_ids( ) . contains( & ( id_b, Some ( addr_b) ) ) ) ;
2771- assert ! ( peer_b. get_peer_node_ids( ) . contains( & ( id_a, Some ( addr_a) ) ) ) ;
2825+ assert ! ( peer_a. get_peer_node_ids( ) . contains( & ( id_b, Some ( addr_b) , features_b ) ) ) ;
2826+ assert ! ( peer_b. get_peer_node_ids( ) . contains( & ( id_a, Some ( addr_a) , features_a ) ) ) ;
27722827
27732828 ( fd_a. clone ( ) , fd_b. clone ( ) )
27742829 }
0 commit comments