diff --git a/zebra-network/src/peer_set/candidate_set.rs b/zebra-network/src/peer_set/candidate_set.rs index eb02c464..9458bbea 100644 --- a/zebra-network/src/peer_set/candidate_set.rs +++ b/zebra-network/src/peer_set/candidate_set.rs @@ -368,7 +368,8 @@ where /// Zebra resists distributed denial of service attacks by making sure that /// new peer connections are initiated at least /// [`MIN_OUTBOUND_PEER_CONNECTION_INTERVAL`][constants::MIN_OUTBOUND_PEER_CONNECTION_INTERVAL] - /// apart. + /// apart. If `next()` has recently provided a peer, then its future will sleep + /// until the rate-limit has passed. /// /// [`Responded`]: crate::PeerAddrState::Responded pub async fn next(&mut self) -> Option { diff --git a/zebra-network/src/peer_set/initialize.rs b/zebra-network/src/peer_set/initialize.rs index 30404ac6..6b2ae33e 100644 --- a/zebra-network/src/peer_set/initialize.rs +++ b/zebra-network/src/peer_set/initialize.rs @@ -870,6 +870,12 @@ where // Spawn each handshake or crawl into an independent task, so handshakes can make // progress while crawls are running. + // + // # Concurrency + // + // The peer crawler must be able to make progress even if some handshakes are + // rate-limited. So the async mutex and next peer timeout are awaited inside the + // spawned task. let handshake_or_crawl_handle = tokio::spawn( async move { // Try to get the next available peer for a handshake.