Skip to content

Commit 4f14d81

Browse files
committed
Introduce PeerManager::list_peers and peer_by_node_id
.. returning `PeerDetails` rather than tuples of peer-associated values. Previously, we wouldn't offer any way to retrieve the features a peer provided in their `Init` message. Here, we allow to retrieve them via a new `PeerDetails` struct, side-by-side with `SocketAddress`es and a bool indicating the direction of the peer connection.
1 parent cd84757 commit 4f14d81

File tree

2 files changed

+72
-17
lines changed

2 files changed

+72
-17
lines changed

fuzz/src/full_stack.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -737,9 +737,9 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
737737
},
738738
// 15, 16, 17, 18 is above
739739
19 => {
740-
let mut list = loss_detector.handler.get_peer_node_ids();
741-
list.sort_by_key(|v| v.0);
742-
if let Some((id, _)) = list.get(0) {
740+
let mut list = loss_detector.handler.list_peers();
741+
list.sort_by_key(|v| v.counterparty_node_id);
742+
if let Some((id, _, _)) = list.get(0) {
743743
loss_detector.handler.disconnect_by_node_id(*id);
744744
}
745745
},

lightning/src/ln/peer_handler.rs

+69-14
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)