@@ -431,6 +431,26 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
431
431
fn disconnect_socket ( & mut self ) ;
432
432
}
433
433
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
+
434
454
/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
435
455
/// generate no further read_event/write_buffer_space_avail/socket_disconnected calls for the
436
456
/// descriptor.
@@ -958,27 +978,60 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
958
978
}
959
979
}
960
980
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 > {
972
984
let peers = self . peers . read ( ) . unwrap ( ) ;
973
985
peers. values ( ) . filter_map ( |peer_mutex| {
974
986
let p = peer_mutex. lock ( ) . unwrap ( ) ;
975
987
if !p. handshake_complete ( ) {
976
988
return None ;
977
989
}
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)
979
1001
} ) . collect ( )
980
1002
}
981
1003
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
+
982
1035
fn get_ephemeral_key ( & self ) -> SecretKey {
983
1036
let mut ephemeral_hash = self . ephemeral_key_midstate . clone ( ) ;
984
1037
let counter = self . peer_counter . get_increment ( ) ;
@@ -2746,6 +2799,8 @@ mod tests {
2746
2799
} ;
2747
2800
let addr_a = SocketAddress :: TcpIpV4 { addr : [ 127 , 0 , 0 , 1 ] , port : 1000 } ;
2748
2801
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) ;
2749
2804
let mut fd_b = FileDescriptor {
2750
2805
fd : 1 , outbound_data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
2751
2806
disconnect : Arc :: new ( AtomicBool :: new ( false ) ) ,
@@ -2767,8 +2822,8 @@ mod tests {
2767
2822
let a_data = fd_a. outbound_data . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
2768
2823
assert_eq ! ( peer_b. read_event( & mut fd_b, & a_data) . unwrap( ) , false ) ;
2769
2824
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 ) ) ) ;
2772
2827
2773
2828
( fd_a. clone ( ) , fd_b. clone ( ) )
2774
2829
}
0 commit comments