From 8442c69bba2869af8187ffaf079e27445d11ade0 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 17 Feb 2025 17:29:59 -0300 Subject: [PATCH 1/4] extend getpeerinfo --- .../src/methods/get_block_template_rpcs.rs | 3 +- .../types/peer_info.rs | 15 ++++++++ .../snapshots/get_peer_info@mainnet_10.snap | 3 +- .../snapshots/get_peer_info@testnet_10.snap | 3 +- zebra-rpc/src/methods/tests/vectors.rs | 36 +++++++++++++++---- 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/zebra-rpc/src/methods/get_block_template_rpcs.rs b/zebra-rpc/src/methods/get_block_template_rpcs.rs index 809fafac69e..edc4ee27024 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs.rs @@ -1101,10 +1101,11 @@ where async fn get_peer_info(&self) -> Result> { let address_book = self.address_book.clone(); + Ok(address_book .recently_live_peers(chrono::Utc::now()) .into_iter() - .map(PeerInfo::from) + .map(|meta_addr| PeerInfo::new(meta_addr, meta_addr.is_inbound())) .collect()) } diff --git a/zebra-rpc/src/methods/get_block_template_rpcs/types/peer_info.rs b/zebra-rpc/src/methods/get_block_template_rpcs/types/peer_info.rs index fe59df482fc..735a8308eae 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs/types/peer_info.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs/types/peer_info.rs @@ -7,12 +7,26 @@ use zebra_network::{types::MetaAddr, PeerSocketAddr}; pub struct PeerInfo { /// The IP address and port of the peer pub addr: PeerSocketAddr, + + /// Inbound (true) or Outbound (false) + pub inbound: bool, +} + +impl PeerInfo { + /// Create a new `PeerInfo` from a `MetaAddr` + pub fn new(meta_addr: MetaAddr, inbound: bool) -> Self { + Self { + addr: meta_addr.addr(), + inbound, + } + } } impl From for PeerInfo { fn from(meta_addr: MetaAddr) -> Self { Self { addr: meta_addr.addr(), + inbound: meta_addr.is_inbound(), } } } @@ -21,6 +35,7 @@ impl Default for PeerInfo { fn default() -> Self { Self { addr: PeerSocketAddr::unspecified(), + inbound: false, } } } diff --git a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@mainnet_10.snap b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@mainnet_10.snap index 71d1375eb0e..651e1f005ee 100644 --- a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@mainnet_10.snap +++ b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@mainnet_10.snap @@ -4,6 +4,7 @@ expression: get_peer_info --- [ { - "addr": "127.0.0.1:8233" + "addr": "127.0.0.1:8233", + "inbound": false } ] diff --git a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@testnet_10.snap b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@testnet_10.snap index e9ad3a7f930..62a290aebed 100644 --- a/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@testnet_10.snap +++ b/zebra-rpc/src/methods/tests/snapshot/snapshots/get_peer_info@testnet_10.snap @@ -4,6 +4,7 @@ expression: get_peer_info --- [ { - "addr": "127.0.0.1:18233" + "addr": "127.0.0.1:18233", + "inbound": false } ] diff --git a/zebra-rpc/src/methods/tests/vectors.rs b/zebra-rpc/src/methods/tests/vectors.rs index a25b399c697..5d37b887b3b 100644 --- a/zebra-rpc/src/methods/tests/vectors.rs +++ b/zebra-rpc/src/methods/tests/vectors.rs @@ -1288,7 +1288,7 @@ async fn rpc_getblockcount_empty_state() { #[tokio::test(flavor = "multi_thread")] async fn rpc_getpeerinfo() { use zebra_chain::chain_sync_status::MockSyncStatus; - use zebra_network::address_book_peers::MockAddressBookPeers; + use zebra_network::{address_book_peers::MockAddressBookPeers, types::PeerServices}; let _init_guard = zebra_test::init(); let network = Mainnet; @@ -1311,7 +1311,7 @@ async fn rpc_getpeerinfo() { ) .await; - let mock_peer_address = zebra_network::types::MetaAddr::new_initial_peer( + let outbound_mock_peer_address = zebra_network::types::MetaAddr::new_initial_peer( std::net::SocketAddr::new( std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), network.default_port(), @@ -1323,7 +1323,22 @@ async fn rpc_getpeerinfo() { zebra_chain::serialization::DateTime32::now(), ); - let mock_address_book = MockAddressBookPeers::new(vec![mock_peer_address]); + let inbound_mock_peer_address = zebra_network::types::MetaAddr::new_connected( + std::net::SocketAddr::new( + std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), + 44444, + ) + .into(), + &PeerServices::NODE_NETWORK, + true, + ) + .into_new_meta_addr( + std::time::Instant::now(), + zebra_chain::serialization::DateTime32::now(), + ); + + let mock_address_book = + MockAddressBookPeers::new(vec![outbound_mock_peer_address, inbound_mock_peer_address]); // Init RPC let get_block_template_rpc = get_block_template_rpcs::GetBlockTemplateRpcImpl::new( @@ -1344,12 +1359,21 @@ async fn rpc_getpeerinfo() { .await .expect("We should have an array of addresses"); + let mut res_iter = get_peer_info.into_iter(); + // Check for the outbound peer + assert_eq!( + res_iter + .next() + .expect("there should be a mock peer address"), + outbound_mock_peer_address.into() + ); + + // Check for the inbound peer assert_eq!( - get_peer_info - .into_iter() + res_iter .next() .expect("there should be a mock peer address"), - mock_peer_address.into() + inbound_mock_peer_address.into() ); mempool.expect_no_requests().await; From f01cd3eecf26138f277c6859ddabbf7bcbcce6c5 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 17 Feb 2025 18:21:09 -0300 Subject: [PATCH 2/4] add and use `currently_live_peers()` --- zebra-network/src/address_book.rs | 16 ++++++++++++++++ zebra-network/src/address_book_peers.rs | 3 +++ zebra-network/src/address_book_peers/mock.rs | 10 +++++++++- .../src/methods/get_block_template_rpcs.rs | 2 +- .../tests/snapshot/get_block_template_rpcs.rs | 17 ++++++++++------- zebra-rpc/src/methods/tests/vectors.rs | 6 ++++-- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/zebra-network/src/address_book.rs b/zebra-network/src/address_book.rs index c30ac30943c..6f33e164636 100644 --- a/zebra-network/src/address_book.rs +++ b/zebra-network/src/address_book.rs @@ -819,6 +819,16 @@ impl AddressBookPeers for AddressBook { .cloned() .collect() } + + fn currently_live_peers(&self, now: chrono::DateTime) -> Vec { + let _guard = self.span.enter(); + + self.by_addr + .descending_values() + .filter(|peer| peer.has_connection_recently_responded(now)) + .cloned() + .collect() + } } impl AddressBookPeers for Arc> { @@ -827,6 +837,12 @@ impl AddressBookPeers for Arc> { .expect("panic in a previous thread that was holding the mutex") .recently_live_peers(now) } + + fn currently_live_peers(&self, now: chrono::DateTime) -> Vec { + self.lock() + .expect("panic in a previous thread that was holding the mutex") + .currently_live_peers(now) + } } impl Extend for AddressBook { diff --git a/zebra-network/src/address_book_peers.rs b/zebra-network/src/address_book_peers.rs index 3082680504a..8b763c209d4 100644 --- a/zebra-network/src/address_book_peers.rs +++ b/zebra-network/src/address_book_peers.rs @@ -14,4 +14,7 @@ pub use mock::MockAddressBookPeers; pub trait AddressBookPeers { /// Return an Vec of peers we've seen recently, in reconnection attempt order. fn recently_live_peers(&self, now: chrono::DateTime) -> Vec; + + /// Return an Vec of peers that are likely to be live, in reconnection attempt order. + fn currently_live_peers(&self, now: chrono::DateTime) -> Vec; } diff --git a/zebra-network/src/address_book_peers/mock.rs b/zebra-network/src/address_book_peers/mock.rs index 58253530f76..260d330233a 100644 --- a/zebra-network/src/address_book_peers/mock.rs +++ b/zebra-network/src/address_book_peers/mock.rs @@ -7,13 +7,17 @@ use crate::{meta_addr::MetaAddr, AddressBookPeers}; pub struct MockAddressBookPeers { /// Return value for mock `recently_live_peers` method. recently_live_peers: Vec, + + /// Return value for mock `currently_live_peers` method. + currently_live_peers: Vec, } impl MockAddressBookPeers { /// Creates a new [`MockAddressBookPeers`] - pub fn new(recently_live_peers: Vec) -> Self { + pub fn new(recently_live_peers: Vec, currently_live_peers: Vec) -> Self { Self { recently_live_peers, + currently_live_peers, } } } @@ -22,4 +26,8 @@ impl AddressBookPeers for MockAddressBookPeers { fn recently_live_peers(&self, _now: chrono::DateTime) -> Vec { self.recently_live_peers.clone() } + + fn currently_live_peers(&self, _now: chrono::DateTime) -> Vec { + self.currently_live_peers.clone() + } } diff --git a/zebra-rpc/src/methods/get_block_template_rpcs.rs b/zebra-rpc/src/methods/get_block_template_rpcs.rs index edc4ee27024..9d22c4b2e6b 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs.rs @@ -1103,7 +1103,7 @@ where let address_book = self.address_book.clone(); Ok(address_book - .recently_live_peers(chrono::Utc::now()) + .currently_live_peers(chrono::Utc::now()) .into_iter() .map(|meta_addr| PeerInfo::new(meta_addr, meta_addr.is_inbound())) .collect()) diff --git a/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs b/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs index ec6d2fe4870..19d5d1fe1bf 100644 --- a/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs @@ -132,14 +132,17 @@ pub async fn test_responses( mock_chain_tip_sender.send_best_tip_hash(fake_tip_hash); mock_chain_tip_sender.send_estimated_distance_to_network_chain_tip(Some(0)); - let mock_address_book = MockAddressBookPeers::new(vec![MetaAddr::new_initial_peer( - SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - network.default_port(), + let mock_address_book = MockAddressBookPeers::new( + vec![], + vec![MetaAddr::new_initial_peer( + SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + network.default_port(), + ) + .into(), ) - .into(), - ) - .into_new_meta_addr(Instant::now(), DateTime32::now())]); + .into_new_meta_addr(Instant::now(), DateTime32::now())], + ); // get an rpc instance with continuous blockchain state let get_block_template_rpc = GetBlockTemplateRpcImpl::new( diff --git a/zebra-rpc/src/methods/tests/vectors.rs b/zebra-rpc/src/methods/tests/vectors.rs index 5d37b887b3b..03f19471d3e 100644 --- a/zebra-rpc/src/methods/tests/vectors.rs +++ b/zebra-rpc/src/methods/tests/vectors.rs @@ -1337,8 +1337,10 @@ async fn rpc_getpeerinfo() { zebra_chain::serialization::DateTime32::now(), ); - let mock_address_book = - MockAddressBookPeers::new(vec![outbound_mock_peer_address, inbound_mock_peer_address]); + let mock_address_book = MockAddressBookPeers::new( + vec![], + vec![outbound_mock_peer_address, inbound_mock_peer_address], + ); // Init RPC let get_block_template_rpc = get_block_template_rpcs::GetBlockTemplateRpcImpl::new( From d90e639fd5a86b82feb8ef7021adeaa3733cc23f Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Sat, 22 Feb 2025 09:25:46 -0300 Subject: [PATCH 3/4] remove `currently_live_peers` and just use filtered `recently_live_peers` instead --- zebra-network/src/address_book.rs | 16 ---------- zebra-network/src/address_book_peers.rs | 3 -- zebra-network/src/address_book_peers/mock.rs | 10 +------ .../src/methods/get_block_template_rpcs.rs | 3 +- .../tests/snapshot/get_block_template_rpcs.rs | 24 ++++++++------- zebra-rpc/src/methods/tests/vectors.rs | 29 ++++++++++++++++--- 6 files changed, 41 insertions(+), 44 deletions(-) diff --git a/zebra-network/src/address_book.rs b/zebra-network/src/address_book.rs index 6f33e164636..c30ac30943c 100644 --- a/zebra-network/src/address_book.rs +++ b/zebra-network/src/address_book.rs @@ -819,16 +819,6 @@ impl AddressBookPeers for AddressBook { .cloned() .collect() } - - fn currently_live_peers(&self, now: chrono::DateTime) -> Vec { - let _guard = self.span.enter(); - - self.by_addr - .descending_values() - .filter(|peer| peer.has_connection_recently_responded(now)) - .cloned() - .collect() - } } impl AddressBookPeers for Arc> { @@ -837,12 +827,6 @@ impl AddressBookPeers for Arc> { .expect("panic in a previous thread that was holding the mutex") .recently_live_peers(now) } - - fn currently_live_peers(&self, now: chrono::DateTime) -> Vec { - self.lock() - .expect("panic in a previous thread that was holding the mutex") - .currently_live_peers(now) - } } impl Extend for AddressBook { diff --git a/zebra-network/src/address_book_peers.rs b/zebra-network/src/address_book_peers.rs index 8b763c209d4..3082680504a 100644 --- a/zebra-network/src/address_book_peers.rs +++ b/zebra-network/src/address_book_peers.rs @@ -14,7 +14,4 @@ pub use mock::MockAddressBookPeers; pub trait AddressBookPeers { /// Return an Vec of peers we've seen recently, in reconnection attempt order. fn recently_live_peers(&self, now: chrono::DateTime) -> Vec; - - /// Return an Vec of peers that are likely to be live, in reconnection attempt order. - fn currently_live_peers(&self, now: chrono::DateTime) -> Vec; } diff --git a/zebra-network/src/address_book_peers/mock.rs b/zebra-network/src/address_book_peers/mock.rs index 260d330233a..58253530f76 100644 --- a/zebra-network/src/address_book_peers/mock.rs +++ b/zebra-network/src/address_book_peers/mock.rs @@ -7,17 +7,13 @@ use crate::{meta_addr::MetaAddr, AddressBookPeers}; pub struct MockAddressBookPeers { /// Return value for mock `recently_live_peers` method. recently_live_peers: Vec, - - /// Return value for mock `currently_live_peers` method. - currently_live_peers: Vec, } impl MockAddressBookPeers { /// Creates a new [`MockAddressBookPeers`] - pub fn new(recently_live_peers: Vec, currently_live_peers: Vec) -> Self { + pub fn new(recently_live_peers: Vec) -> Self { Self { recently_live_peers, - currently_live_peers, } } } @@ -26,8 +22,4 @@ impl AddressBookPeers for MockAddressBookPeers { fn recently_live_peers(&self, _now: chrono::DateTime) -> Vec { self.recently_live_peers.clone() } - - fn currently_live_peers(&self, _now: chrono::DateTime) -> Vec { - self.currently_live_peers.clone() - } } diff --git a/zebra-rpc/src/methods/get_block_template_rpcs.rs b/zebra-rpc/src/methods/get_block_template_rpcs.rs index 9d22c4b2e6b..0073ee052e9 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs.rs @@ -1103,8 +1103,9 @@ where let address_book = self.address_book.clone(); Ok(address_book - .currently_live_peers(chrono::Utc::now()) + .recently_live_peers(chrono::Utc::now()) .into_iter() + .filter(|meta_addr| meta_addr.has_connection_recently_responded(chrono::Utc::now())) .map(|meta_addr| PeerInfo::new(meta_addr, meta_addr.is_inbound())) .collect()) } diff --git a/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs b/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs index 19d5d1fe1bf..df6cfbacea9 100644 --- a/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/tests/snapshot/get_block_template_rpcs.rs @@ -25,7 +25,10 @@ use zebra_chain::{ transparent, work::difficulty::{CompactDifficulty, ParameterDifficulty as _}, }; -use zebra_network::{address_book_peers::MockAddressBookPeers, types::MetaAddr}; +use zebra_network::{ + address_book_peers::MockAddressBookPeers, + types::{MetaAddr, PeerServices}, +}; use zebra_node_services::mempool; use zebra_state::{GetBlockTemplateChainInfo, ReadRequest, ReadResponse}; @@ -132,17 +135,16 @@ pub async fn test_responses( mock_chain_tip_sender.send_best_tip_hash(fake_tip_hash); mock_chain_tip_sender.send_estimated_distance_to_network_chain_tip(Some(0)); - let mock_address_book = MockAddressBookPeers::new( - vec![], - vec![MetaAddr::new_initial_peer( - SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - network.default_port(), - ) - .into(), + let mock_address_book = MockAddressBookPeers::new(vec![MetaAddr::new_connected( + SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + network.default_port(), ) - .into_new_meta_addr(Instant::now(), DateTime32::now())], - ); + .into(), + &PeerServices::NODE_NETWORK, + false, + ) + .into_new_meta_addr(Instant::now(), DateTime32::now())]); // get an rpc instance with continuous blockchain state let get_block_template_rpc = GetBlockTemplateRpcImpl::new( diff --git a/zebra-rpc/src/methods/tests/vectors.rs b/zebra-rpc/src/methods/tests/vectors.rs index 03f19471d3e..a0d0d1a3040 100644 --- a/zebra-rpc/src/methods/tests/vectors.rs +++ b/zebra-rpc/src/methods/tests/vectors.rs @@ -1311,18 +1311,22 @@ async fn rpc_getpeerinfo() { ) .await; - let outbound_mock_peer_address = zebra_network::types::MetaAddr::new_initial_peer( + // Add a connected outbound peer + let outbound_mock_peer_address = zebra_network::types::MetaAddr::new_connected( std::net::SocketAddr::new( std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), network.default_port(), ) .into(), + &PeerServices::NODE_NETWORK, + false, ) .into_new_meta_addr( std::time::Instant::now(), zebra_chain::serialization::DateTime32::now(), ); + // Add a connected inbound peer let inbound_mock_peer_address = zebra_network::types::MetaAddr::new_connected( std::net::SocketAddr::new( std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), @@ -1337,11 +1341,25 @@ async fn rpc_getpeerinfo() { zebra_chain::serialization::DateTime32::now(), ); - let mock_address_book = MockAddressBookPeers::new( - vec![], - vec![outbound_mock_peer_address, inbound_mock_peer_address], + // Add a peer that is not connected and will not be displayed in the RPC output + let not_connected_mock_peer_adderess = zebra_network::types::MetaAddr::new_initial_peer( + std::net::SocketAddr::new( + std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), + 55555, + ) + .into(), + ) + .into_new_meta_addr( + std::time::Instant::now(), + zebra_chain::serialization::DateTime32::now(), ); + let mock_address_book = MockAddressBookPeers::new(vec![ + outbound_mock_peer_address, + inbound_mock_peer_address, + not_connected_mock_peer_adderess, + ]); + // Init RPC let get_block_template_rpc = get_block_template_rpcs::GetBlockTemplateRpcImpl::new( &network, @@ -1361,6 +1379,9 @@ async fn rpc_getpeerinfo() { .await .expect("We should have an array of addresses"); + // Response of lenght should be 2. We have 2 connected peers and 1 unconnected peer in the address book. + assert_eq!(get_peer_info.len(), 2); + let mut res_iter = get_peer_info.into_iter(); // Check for the outbound peer assert_eq!( From c5a15e64a1fc52c758896495db2331698117eabf Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Sat, 22 Feb 2025 10:33:13 -0300 Subject: [PATCH 4/4] fix codespell --- zebra-rpc/src/methods/tests/vectors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra-rpc/src/methods/tests/vectors.rs b/zebra-rpc/src/methods/tests/vectors.rs index aa070fbe65f..682fe7be3ba 100644 --- a/zebra-rpc/src/methods/tests/vectors.rs +++ b/zebra-rpc/src/methods/tests/vectors.rs @@ -1434,7 +1434,7 @@ async fn rpc_getpeerinfo() { .await .expect("We should have an array of addresses"); - // Response of lenght should be 2. We have 2 connected peers and 1 unconnected peer in the address book. + // Response of length should be 2. We have 2 connected peers and 1 unconnected peer in the address book. assert_eq!(get_peer_info.len(), 2); let mut res_iter = get_peer_info.into_iter();