From 7d160f51b73c83b7a4de2884a6544e8e34d31f83 Mon Sep 17 00:00:00 2001 From: Mykhailo Kremniov Date: Tue, 9 Jan 2024 19:26:46 +0200 Subject: [PATCH] Don't evict peers that have a block in-flight --- p2p/p2p-test-utils/src/lib.rs | 13 + p2p/src/peer_manager/mod.rs | 15 +- p2p/src/peer_manager/peer_context.rs | 4 + .../peerdb/address_tables/table.rs | 26 +- p2p/src/peer_manager/peerdb/mod.rs | 15 + p2p/src/peer_manager/peers_eviction/mod.rs | 70 +++- p2p/src/peer_manager/peers_eviction/tests.rs | 314 +++++++++++++++-- p2p/src/peer_manager/tests/addresses.rs | 4 +- p2p/src/peer_manager/tests/connections.rs | 27 +- p2p/src/peer_manager/tests/eviction.rs | 316 ++++++++++++++++++ p2p/src/peer_manager/tests/mod.rs | 1 + p2p/src/peer_manager/tests/utils.rs | 48 ++- p2p/src/peer_manager_event.rs | 8 +- p2p/src/sync/mod.rs | 3 +- p2p/src/sync/{types.rs => peer_activity.rs} | 4 +- p2p/src/sync/peer_v2/block_manager.rs | 48 ++- p2p/src/sync/sync_status.rs | 31 ++ p2p/src/sync/tests/block_response.rs | 25 +- p2p/src/sync/tests/helpers/mod.rs | 89 ++++- p2p/src/sync/tests/helpers/test_node_group.rs | 5 +- 20 files changed, 945 insertions(+), 121 deletions(-) create mode 100644 p2p/src/peer_manager/tests/eviction.rs rename p2p/src/sync/{types.rs => peer_activity.rs} (92%) create mode 100644 p2p/src/sync/sync_status.rs diff --git a/p2p/p2p-test-utils/src/lib.rs b/p2p/p2p-test-utils/src/lib.rs index da94327676..ed2a08f7ce 100644 --- a/p2p/p2p-test-utils/src/lib.rs +++ b/p2p/p2p-test-utils/src/lib.rs @@ -31,6 +31,7 @@ use logging::log; use mempool::{MempoolConfig, MempoolHandle}; use subsystem::{ManagerJoinHandle, ShutdownTrigger}; use test_utils::mock_time_getter::mocked_time_getter_milliseconds; +use tokio::sync::mpsc; use utils::atomics::SeqCstAtomicU64; use crate::panic_handling::get_panic_notification; @@ -219,3 +220,15 @@ macro_rules! expect_no_recv { $crate::expect_no_future_val!($receiver.recv()) }; } + +pub async fn wait_for_recv(receiver: &mut mpsc::UnboundedReceiver, value: &T) { + let wait_loop = async { + loop { + if receiver.recv().await.unwrap() == *value { + break; + } + } + }; + + expect_future_val!(wait_loop); +} diff --git a/p2p/src/peer_manager/mod.rs b/p2p/src/peer_manager/mod.rs index 587bcc8461..5298443fe1 100644 --- a/p2p/src/peer_manager/mod.rs +++ b/p2p/src/peer_manager/mod.rs @@ -66,6 +66,7 @@ use crate::{ ConnectivityService, NetworkingService, }, peer_manager_event::PeerDisconnectionDbAction, + sync::sync_status::PeerBlockSyncStatus, types::{ peer_address::{PeerAddress, PeerAddressIp4, PeerAddressIp6}, peer_id::PeerId, @@ -833,6 +834,7 @@ where if let Some(peer_id) = peers_eviction::select_for_eviction_block_relay( self.eviction_candidates(PeerRole::OutboundBlockRelay), &self.p2p_config.peer_manager_config, + self.time_getter.get_time(), ) { log::info!("block relay peer {peer_id} is selected for eviction"); self.disconnect(peer_id, PeerDisconnectionDbAction::Keep, None); @@ -844,6 +846,7 @@ where if let Some(peer_id) = peers_eviction::select_for_eviction_full_relay( self.eviction_candidates(PeerRole::OutboundFullRelay), &self.p2p_config.peer_manager_config, + self.time_getter.get_time(), ) { log::info!("full relay peer {peer_id} is selected for eviction"); self.disconnect(peer_id, PeerDisconnectionDbAction::Keep, None); @@ -943,6 +946,7 @@ where discovered_own_address, last_tip_block_time: None, last_tx_time: None, + block_sync_status: PeerBlockSyncStatus::new(), }; Self::send_own_address_to_peer(&mut self.peer_connectivity_handle, &peer); @@ -1250,7 +1254,7 @@ where // TODO: in bitcoin they also try to create an extra outbound full relay connection // to an address in a reachable network in which there are no outbound full relay or // manual connections (see CConnman::MaybePickPreferredNetwork for reference). - // See the TODO section of https://github.com/mintlayer/mintlayer-core/issues/832 + // See https://github.com/mintlayer/mintlayer-core/issues/1433 for address in &new_full_relay_conn_addresses { let addr_group = AddressGroup::from_peer_address(&address.as_peer_address()); @@ -1495,6 +1499,15 @@ where peer.last_tx_time = Some(self.time_getter.get_time()); } } + PeerManagerEvent::PeerBlockSyncStatusUpdate { + peer_id, + new_status: status, + } => { + if let Some(peer) = self.peers.get_mut(&peer_id) { + log::debug!("Block sync status update received from peer {peer_id}, new status is {status:?}"); + peer.block_sync_status = status; + } + } PeerManagerEvent::GetPeerCount(response_sender) => { response_sender.send(self.active_peer_count()); } diff --git a/p2p/src/peer_manager/peer_context.rs b/p2p/src/peer_manager/peer_context.rs index b7d29d6ee1..d8a012a739 100644 --- a/p2p/src/peer_manager/peer_context.rs +++ b/p2p/src/peer_manager/peer_context.rs @@ -21,6 +21,7 @@ use utils::{bloom_filters::rolling_bloom_filter::RollingBloomFilter, set_flag::S use crate::{ net::types::{PeerInfo, PeerRole}, + sync::sync_status::PeerBlockSyncStatus, utils::rate_limiter::RateLimiter, }; @@ -75,4 +76,7 @@ pub struct PeerContext { pub last_tip_block_time: Option