From b0a749548dad4ae9afc65760b7fdce877919cf06 Mon Sep 17 00:00:00 2001 From: Pierre Krieger <pierre.krieger1708@gmail.com> Date: Tue, 11 Feb 2020 12:22:25 +0100 Subject: [PATCH] Pause Kademlia if too many connections (#4828) * Pause Kademlia if too many connections * Fix test * Update client/network/src/discovery.rs Co-Authored-By: Toralf Wittner <tw@dtex.org> * Change the limit Co-authored-by: Toralf Wittner <tw@dtex.org> --- substrate/client/network/src/behaviour.rs | 4 +++- substrate/client/network/src/discovery.rs | 26 ++++++++++++++++++----- substrate/client/network/src/service.rs | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/substrate/client/network/src/behaviour.rs b/substrate/client/network/src/behaviour.rs index 8b903cec351..a1f54654b3e 100644 --- a/substrate/client/network/src/behaviour.rs +++ b/substrate/client/network/src/behaviour.rs @@ -65,6 +65,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Behaviour<B, S, H> { known_addresses: Vec<(PeerId, Multiaddr)>, enable_mdns: bool, allow_private_ipv4: bool, + discovery_only_if_under_num: u64, ) -> Self { Behaviour { substrate, @@ -73,7 +74,8 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Behaviour<B, S, H> { local_public_key, known_addresses, enable_mdns, - allow_private_ipv4 + allow_private_ipv4, + discovery_only_if_under_num, ).await, events: Vec::new(), } diff --git a/substrate/client/network/src/discovery.rs b/substrate/client/network/src/discovery.rs index de49913b265..2da69e18944 100644 --- a/substrate/client/network/src/discovery.rs +++ b/substrate/client/network/src/discovery.rs @@ -87,6 +87,8 @@ pub struct DiscoveryBehaviour<TSubstream> { /// If false, `addresses_of_peer` won't return any private IPv4 address, except for the ones /// stored in `user_defined`. allow_private_ipv4: bool, + /// Number of active connections over which we interrupt the discovery process. + discovery_only_if_under_num: u64, } impl<TSubstream> DiscoveryBehaviour<TSubstream> { @@ -98,6 +100,7 @@ impl<TSubstream> DiscoveryBehaviour<TSubstream> { user_defined: Vec<(PeerId, Multiaddr)>, enable_mdns: bool, allow_private_ipv4: bool, + discovery_only_if_under_num: u64, ) -> Self { if enable_mdns { #[cfg(target_os = "unknown")] @@ -120,6 +123,7 @@ impl<TSubstream> DiscoveryBehaviour<TSubstream> { local_peer_id: local_public_key.into_peer_id(), num_connections: 0, allow_private_ipv4, + discovery_only_if_under_num, #[cfg(not(target_os = "unknown"))] mdns: if enable_mdns { match Mdns::new() { @@ -331,11 +335,19 @@ where // Poll the stream that fires when we need to start a random Kademlia query. while let Poll::Ready(_) = self.next_kad_random_query.poll_unpin(cx) { - let random_peer_id = PeerId::random(); - debug!(target: "sub-libp2p", "Libp2p <= Starting random Kademlia request for \ - {:?}", random_peer_id); + if self.num_connections < self.discovery_only_if_under_num { + let random_peer_id = PeerId::random(); + debug!(target: "sub-libp2p", "Libp2p <= Starting random Kademlia request for \ + {:?}", random_peer_id); - self.kademlia.get_closest_peers(random_peer_id); + self.kademlia.get_closest_peers(random_peer_id); + } else { + debug!( + target: "sub-libp2p", + "Kademlia paused due to high number of connections ({})", + self.num_connections + ); + } // Schedule the next random query with exponentially increasing delay, // capped at 60 seconds. @@ -435,6 +447,10 @@ where NetworkBehaviourAction::GenerateEvent(event) => { match event { MdnsEvent::Discovered(list) => { + if self.num_connections >= self.discovery_only_if_under_num { + continue; + } + self.discoveries.extend(list.into_iter().map(|(peer_id, _)| peer_id)); if let Some(peer_id) = self.discoveries.pop_front() { let ev = DiscoveryOut::Discovered(peer_id); @@ -502,7 +518,7 @@ mod tests { let user_defined = user_defined.clone(); let keypair_public = keypair.public(); async move { - DiscoveryBehaviour::new(keypair_public, user_defined, false, true).await + DiscoveryBehaviour::new(keypair_public, user_defined, false, true, 50).await } }); let mut swarm = Swarm::new(transport, behaviour, keypair.public().into_peer_id()); diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs index e3eaf6c31d5..b4281112f61 100644 --- a/substrate/client/network/src/service.rs +++ b/substrate/client/network/src/service.rs @@ -232,6 +232,7 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> NetworkWorker TransportConfig::MemoryOnly => false, TransportConfig::Normal { allow_private_ipv4, .. } => allow_private_ipv4, }, + u64::from(params.network_config.out_peers) + 15, )); let (transport, bandwidth) = { let (config_mem, config_wasm) = match params.network_config.transport { -- GitLab