Skip to content

Commit

Permalink
feat: do not try to discovery peers for full buckets
Browse files Browse the repository at this point in the history
  • Loading branch information
RolandSherwin authored and jacderida committed Jan 6, 2025
1 parent 70154a0 commit 6ec9478
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
27 changes: 25 additions & 2 deletions ant-networking/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// permissions and limitations relating to use of the SAFE Network Software.

use crate::{driver::PendingGetClosestType, SwarmDriver};
use libp2p::kad::K_VALUE;
use rand::{rngs::OsRng, Rng};
use tokio::time::Duration;

Expand All @@ -25,7 +26,7 @@ const NETWORK_DISCOVER_CONNECTED_PEERS_STEP: u32 = 5;
const LAST_PEER_ADDED_TIME_LIMIT: Duration = Duration::from_secs(180);

/// A minimum interval to prevent network discovery got triggered too often
const LAST_NETWORK_DISCOVER_TRIGGERED_TIME_LIMIT: Duration = Duration::from_secs(30);
const LAST_NETWORK_DISCOVER_TRIGGERED_TIME_LIMIT: Duration = Duration::from_secs(90);

/// The network discovery interval to use if we haven't added any new peers in a while.
const NO_PEER_ADDED_SLOWDOWN_INTERVAL_MAX_S: u64 = 600;
Expand All @@ -50,8 +51,30 @@ impl SwarmDriver {

pub(crate) fn trigger_network_discovery(&mut self) {
let now = Instant::now();

// Find the farthest bucket that is not full. This is used to skip refreshing the RT of farthest full buckets.
let mut farthest_unfilled_bucket = 0;
for kbucket in self.swarm.behaviour_mut().kademlia.kbuckets() {
let Some(ilog2) = kbucket.range().0.ilog2() else {
continue;
};
if kbucket.num_entries() < K_VALUE.get() && ilog2 > farthest_unfilled_bucket {
farthest_unfilled_bucket = ilog2;
}
}
let farthest_unfilled_bucket = if farthest_unfilled_bucket == 0 {
None
} else {
Some(farthest_unfilled_bucket)
};

let addrs = self.network_discovery.candidates(farthest_unfilled_bucket);
info!(
"Triggering network discovery with {} candidates. Farthest non full bucket: {farthest_unfilled_bucket:?}",
addrs.len()
);
// Fetches the candidates and also generates new candidates
for addr in self.network_discovery.candidates() {
for addr in addrs {
// The query_id is tracked here. This is to update the candidate list of network_discovery with the newly
// found closest peers. It may fill up the candidate list of closer buckets which are harder to generate.
let query_id = self
Expand Down
14 changes: 11 additions & 3 deletions ant-networking/src/network_discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,22 @@ impl NetworkDiscovery {
}

/// Returns one random candidate per bucket. Also tries to refresh the candidate list.
/// Todo: Limit the candidates to return. Favor the closest buckets.
pub(crate) fn candidates(&mut self) -> Vec<&NetworkAddress> {
/// Set the farthest_bucket to get candidates that are closer than or equal to the farthest_bucket.
pub(crate) fn candidates(&mut self, farthest_bucket: Option<u32>) -> Vec<&NetworkAddress> {
self.try_refresh_candidates();

let mut rng = thread_rng();
let mut op = Vec::with_capacity(self.candidates.len());

let candidates = self.candidates.values().filter_map(|candidates| {
let candidates = self.candidates.iter().filter_map(|(ilog2, candidates)| {
if let Some(farthest_bucket) = farthest_bucket {
if *ilog2 > farthest_bucket {
debug!(
"Skipping candidates for ilog2: {ilog2} as it is greater than farthest_bucket: {farthest_bucket}"
);
return None;
}
}
// get a random index each time
let random_index = rng.gen::<usize>() % candidates.len();
candidates.get(random_index)
Expand Down

0 comments on commit 6ec9478

Please sign in to comment.