Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: do not try to discovery peers for full buckets #2572

Open
wants to merge 1 commit into
base: rc-2024.12.1-hotfix2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading