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

chore(node): rename continuous bootstrap to network discover #2467

Merged
merged 1 commit into from
Nov 27, 2024
Merged
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
85 changes: 44 additions & 41 deletions sn_networking/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,37 @@ use tokio::time::Duration;

use crate::target_arch::{interval, Instant, Interval};

/// The default interval at which NetworkDiscovery is triggered. The interval is increased as more peers are added to the
/// routing table.
pub(crate) const BOOTSTRAP_INTERVAL: Duration = Duration::from_secs(10);
/// The default interval at which NetworkDiscovery is triggered.
/// The interval is increased as more peers are added to the routing table.
pub(crate) const NETWORK_DISCOVER_INTERVAL: Duration = Duration::from_secs(10);

/// Every BOOTSTRAP_CONNECTED_PEERS_STEP connected peer, we step up the BOOTSTRAP_INTERVAL to slow down bootstrapping
/// process
const BOOTSTRAP_CONNECTED_PEERS_STEP: u32 = 5;
/// Every NETWORK_DISCOVER_CONNECTED_PEERS_STEP connected peer,
/// we step up the NETWORK_DISCOVER_INTERVAL to slow down process.
const NETWORK_DISCOVER_CONNECTED_PEERS_STEP: u32 = 5;

/// If the previously added peer has been before LAST_PEER_ADDED_TIME_LIMIT, then we should slowdown the bootstrapping
/// process. This is to make sure we don't flood the network with `FindNode` msgs.
/// Slow down the process if the previously added peer has been before LAST_PEER_ADDED_TIME_LIMIT.
/// This is to make sure we don't flood the network with `FindNode` msgs.
const LAST_PEER_ADDED_TIME_LIMIT: Duration = Duration::from_secs(180);

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

/// The bootstrap interval to use if we haven't added any new peers in a while.
/// 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;

impl SwarmDriver {
/// This functions triggers network discovery based on when the last peer was added to the RT and the number of
/// peers in RT. The function also returns a new bootstrap interval that is proportional to the number of
/// peers in RT, so more peers in RT, the longer the interval.
pub(crate) async fn run_bootstrap_continuously(
/// This functions triggers network discovery based on when the last peer was added to the RT
/// and the number of peers in RT. The function also returns a new interval that is proportional
/// to the number of peers in RT, so more peers in RT, the longer the interval.
pub(crate) async fn run_network_discover_continuously(
&mut self,
current_bootstrap_interval: Duration,
current_interval: Duration,
) -> Option<Interval> {
let (should_bootstrap, new_interval) = self
let (should_discover, new_interval) = self
.bootstrap
.should_we_bootstrap(self.peers_in_rt as u32, current_bootstrap_interval)
.should_we_discover(self.peers_in_rt as u32, current_interval)
.await;
if should_bootstrap {
if should_discover {
self.trigger_network_discovery();
}
new_interval
Expand Down Expand Up @@ -71,32 +71,33 @@ impl SwarmDriver {
}

/// Tracks and helps with the continuous kad::bootstrapping process
pub(crate) struct ContinuousBootstrap {
pub(crate) struct ContinuousNetworkDiscover {
initial_bootstrap_done: bool,
last_peer_added_instant: Instant,
last_bootstrap_triggered: Option<Instant>,
last_network_discover_triggered: Option<Instant>,
}

impl ContinuousBootstrap {
impl ContinuousNetworkDiscover {
pub(crate) fn new() -> Self {
Self {
initial_bootstrap_done: false,
last_peer_added_instant: Instant::now(),
last_bootstrap_triggered: None,
last_network_discover_triggered: None,
}
}

/// The Kademlia Bootstrap request has been sent successfully.
pub(crate) fn initiated(&mut self) {
self.last_bootstrap_triggered = Some(Instant::now());
self.last_network_discover_triggered = Some(Instant::now());
}

/// Notify about a newly added peer to the RT. This will help with slowing down the bootstrap process.
/// Notify about a newly added peer to the RT. This will help with slowing down the process.
/// Returns `true` if we have to perform the initial bootstrapping.
pub(crate) fn notify_new_peer(&mut self) -> bool {
self.last_peer_added_instant = Instant::now();
// true to kick off the initial bootstrapping. `run_bootstrap_continuously` might kick of so soon that we might
// not have a single peer in the RT and we'd not perform any bootstrapping for a while.
// true to kick off the initial bootstrapping.
// `run_network_discover_continuously` might kick of so soon that we might
// not have a single peer in the RT and we'd not perform any network discovery for a while.
if !self.initial_bootstrap_done {
self.initial_bootstrap_done = true;
true
Expand All @@ -106,22 +107,24 @@ impl ContinuousBootstrap {
}

/// Returns `true` if we should carry out the Kademlia Bootstrap process immediately.
/// Also optionally returns the new interval to re-bootstrap.
/// Also optionally returns the new interval for network discovery.
#[cfg_attr(target_arch = "wasm32", allow(clippy::unused_async))]
pub(crate) async fn should_we_bootstrap(
pub(crate) async fn should_we_discover(
&self,
peers_in_rt: u32,
current_interval: Duration,
) -> (bool, Option<Interval>) {
let is_ongoing = if let Some(last_bootstrap_triggered) = self.last_bootstrap_triggered {
last_bootstrap_triggered.elapsed() < LAST_BOOTSTRAP_TRIGGERED_TIME_LIMIT
let is_ongoing = if let Some(last_network_discover_triggered) =
self.last_network_discover_triggered
{
last_network_discover_triggered.elapsed() < LAST_NETWORK_DISCOVER_TRIGGERED_TIME_LIMIT
} else {
false
};
let should_bootstrap = !is_ongoing && peers_in_rt >= 1;
let should_network_discover = !is_ongoing && peers_in_rt >= 1;

// if it has been a while (LAST_PEER_ADDED_TIME_LIMIT) since we have added a new peer to our RT, then, slowdown
// the bootstrapping process.
// if it has been a while (LAST_PEER_ADDED_TIME_LIMIT) since we have added a new peer,
// slowdown the network discovery process.
// Don't slow down if we haven't even added one peer to our RT.
if self.last_peer_added_instant.elapsed() > LAST_PEER_ADDED_TIME_LIMIT && peers_in_rt != 0 {
// To avoid a heart beat like cpu usage due to the 1K candidates generation,
Expand All @@ -132,7 +135,7 @@ impl ContinuousBootstrap {
let no_peer_added_slowdown_interval_duration =
Duration::from_secs(no_peer_added_slowdown_interval);
info!(
"It has been {LAST_PEER_ADDED_TIME_LIMIT:?} since we last added a peer to RT. Slowing down the continuous bootstrapping process. Old interval: {current_interval:?}, New interval: {no_peer_added_slowdown_interval_duration:?}"
"It has been {LAST_PEER_ADDED_TIME_LIMIT:?} since we last added a peer to RT. Slowing down the continuous network discovery process. Old interval: {current_interval:?}, New interval: {no_peer_added_slowdown_interval_duration:?}"
);

// `Interval` ticks immediately for Tokio, but not for `wasmtimer`, which is used for wasm32.
Expand All @@ -141,15 +144,15 @@ impl ContinuousBootstrap {
#[cfg(not(target_arch = "wasm32"))]
new_interval.tick().await;

return (should_bootstrap, Some(new_interval));
return (should_network_discover, Some(new_interval));
}

// increment bootstrap_interval in steps of BOOTSTRAP_INTERVAL every BOOTSTRAP_CONNECTED_PEERS_STEP
let step = peers_in_rt / BOOTSTRAP_CONNECTED_PEERS_STEP;
// increment network_discover_interval in steps of NETWORK_DISCOVER_INTERVAL every NETWORK_DISCOVER_CONNECTED_PEERS_STEP
let step = peers_in_rt / NETWORK_DISCOVER_CONNECTED_PEERS_STEP;
let step = std::cmp::max(1, step);
let new_interval = BOOTSTRAP_INTERVAL * step;
let new_interval = NETWORK_DISCOVER_INTERVAL * step;
let new_interval = if new_interval > current_interval {
info!("More peers have been added to our RT!. Slowing down the continuous bootstrapping process. Old interval: {current_interval:?}, New interval: {new_interval:?}");
info!("More peers have been added to our RT!. Slowing down the continuous network discovery process. Old interval: {current_interval:?}, New interval: {new_interval:?}");

// `Interval` ticks immediately for Tokio, but not for `wasmtimer`, which is used for wasm32.
#[cfg_attr(target_arch = "wasm32", allow(unused_mut))]
Expand All @@ -161,6 +164,6 @@ impl ContinuousBootstrap {
} else {
None
};
(should_bootstrap, new_interval)
(should_network_discover, new_interval)
}
}
14 changes: 7 additions & 7 deletions sn_networking/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// permissions and limitations relating to use of the SAFE Network Software.

use crate::{
bootstrap::{ContinuousBootstrap, BOOTSTRAP_INTERVAL},
bootstrap::{ContinuousNetworkDiscover, NETWORK_DISCOVER_INTERVAL},
circular_vec::CircularVec,
cmd::{LocalSwarmCmd, NetworkSwarmCmd},
error::{NetworkError, Result},
Expand Down Expand Up @@ -688,7 +688,7 @@ impl NetworkBuilder {

let swarm = Swarm::new(transport, behaviour, peer_id, swarm_config);

let bootstrap = ContinuousBootstrap::new();
let bootstrap = ContinuousNetworkDiscover::new();
let replication_fetcher = ReplicationFetcher::new(peer_id, network_event_sender.clone());
let mut relay_manager = RelayManager::new(peer_id);
if !is_client {
Expand Down Expand Up @@ -798,7 +798,7 @@ pub struct SwarmDriver {
#[cfg(feature = "open-metrics")]
pub(crate) close_group: Vec<PeerId>,
pub(crate) peers_in_rt: usize,
pub(crate) bootstrap: ContinuousBootstrap,
pub(crate) bootstrap: ContinuousNetworkDiscover,
pub(crate) external_address_manager: ExternalAddressManager,
pub(crate) relay_manager: RelayManager,
/// The peers that are closer to our PeerId. Includes self.
Expand Down Expand Up @@ -852,7 +852,7 @@ impl SwarmDriver {
/// and command receiver messages, ensuring efficient handling of multiple
/// asynchronous tasks.
pub async fn run(mut self) {
let mut bootstrap_interval = interval(BOOTSTRAP_INTERVAL);
let mut network_discover_interval = interval(NETWORK_DISCOVER_INTERVAL);
let mut set_farthest_record_interval = interval(CLOSET_RECORD_CHECK_INTERVAL);
let mut relay_manager_reservation_interval = interval(RELAY_MANAGER_RESERVATION_INTERVAL);

Expand Down Expand Up @@ -915,9 +915,9 @@ impl SwarmDriver {
// thereafter we can check our intervals

// runs every bootstrap_interval time
_ = bootstrap_interval.tick() => {
if let Some(new_interval) = self.run_bootstrap_continuously(bootstrap_interval.period()).await {
bootstrap_interval = new_interval;
_ = network_discover_interval.tick() => {
if let Some(new_interval) = self.run_network_discover_continuously(network_discover_interval.period()).await {
network_discover_interval = new_interval;
}
}
_ = set_farthest_record_interval.tick() => {
Expand Down
Loading