Skip to content

Commit

Permalink
feat/improve-automatic-bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
stormshield-frb committed Jun 18, 2024
1 parent 0b1733d commit 3229558
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
4 changes: 4 additions & 0 deletions protocols/kad/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
See [PR 5317](https://github.com/libp2p/rust-libp2p/pull/5317).
- Use `web-time` instead of `instant`.
See [PR 5347](https://github.com/libp2p/rust-libp2p/pull/5347).
- Improve automatic bootstrap triggering conditions:
trigger when the routing table is updated and we have less that `K_VALUE` peers in it,
trigger when a new listen address is discovered and we have no connected peers.
See [PR 5474](https://github.com/libp2p/rust-libp2p/pull/5474).

## 0.45.3

Expand Down
22 changes: 20 additions & 2 deletions protocols/kad/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,13 @@ where
};
match entry.insert(addresses.clone(), status) {
kbucket::InsertResult::Inserted => {
self.bootstrap_status.on_new_peer_in_routing_table();
if self.kbuckets().count() < K_VALUE.get() {
// A new peer has been inserted in the routing table and the routing
// table is currently small (less that `K_VALUE` peers are present).
// We initiate a bootstrap to fill it up.
self.bootstrap_status.trigger();
}

self.queued_events.push_back(ToSwarm::GenerateEvent(
Event::RoutingUpdated {
peer: *peer,
Expand Down Expand Up @@ -1334,7 +1340,13 @@ where
let addresses = Addresses::new(a);
match entry.insert(addresses.clone(), new_status) {
kbucket::InsertResult::Inserted => {
self.bootstrap_status.on_new_peer_in_routing_table();
if self.kbuckets().count() < K_VALUE.get() {
// A new peer has been inserted in the routing table and the routing
// table is currently small (less that `K_VALUE` peers are present).
// We initiate a bootstrap to fill it up.
self.bootstrap_status.trigger();
}

let event = Event::RoutingUpdated {
peer,
is_new_peer: true,
Expand Down Expand Up @@ -2628,6 +2640,12 @@ where
}
FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure),
FromSwarm::AddressChange(address_change) => self.on_address_change(address_change),
FromSwarm::NewListenAddr(_) if self.connected_peers.is_empty() => {
// A new listen addr was just discovered and we have no connected peers,
// it can mean that our network interfaces were not up but they are now
// so it might be a good idea to trigger a bootstrap.
self.bootstrap_status.trigger();
}
_ => {}
}
}
Expand Down
17 changes: 9 additions & 8 deletions protocols/kad/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ impl Status {
}
}

pub(crate) fn on_new_peer_in_routing_table(&mut self) {
/// Trigger a bootstrap now or after the configured `automatic_throttle` if configured.
pub(crate) fn trigger(&mut self) {
// Registering `self.throttle_timer` means scheduling a bootstrap.
// A bootstrap will be triggered when `self.throttle_timer` finishes.
// A `throttle_timer` is useful to not trigger a batch of bootstraps when a
Expand Down Expand Up @@ -197,7 +198,7 @@ mod tests {
"bootstrap to not be triggered immediately because periodic bootstrap is in ~1s"
);

status.on_new_peer_in_routing_table(); // Connected to a new peer though!
status.trigger(); // Connected to a new peer though!
assert!(
status.next().now_or_never().is_some(),
"bootstrap to be triggered immediately because we connected to a new peer"
Expand All @@ -222,7 +223,7 @@ mod tests {
"bootstrap to not be triggered immediately because periodic bootstrap is in ~1s"
);

status.on_new_peer_in_routing_table(); // Connected to a new peer though!
status.trigger(); // Connected to a new peer though!
assert!(
status.next().now_or_never().is_none(),
"bootstrap to not be triggered immediately because throttle is 5ms"
Expand All @@ -243,7 +244,7 @@ mod tests {
// User manually triggered a bootstrap
do_bootstrap(&mut status);

status.on_new_peer_in_routing_table(); // Connected to a new peer though!
status.trigger(); // Connected to a new peer though!

assert!(
status.next().now_or_never().is_some(),
Expand All @@ -256,7 +257,7 @@ mod tests {
) {
let mut status = Status::new(Some(MS_100), Some(MS_5));

status.on_new_peer_in_routing_table();
status.trigger();

let start = Instant::now();
await_and_do_bootstrap(&mut status).await;
Expand All @@ -276,7 +277,7 @@ mod tests {
) {
let mut status = Status::new(None, Some(Duration::ZERO));

status.on_new_peer_in_routing_table();
status.trigger();

status.next().await;
}
Expand All @@ -300,10 +301,10 @@ mod tests {
) {
let mut status = Status::new(None, Some(MS_100));

status.on_new_peer_in_routing_table();
status.trigger();
for _ in 0..10 {
Delay::new(MS_100 / 2).await;
status.on_new_peer_in_routing_table(); // should reset throttle_timer
status.trigger(); // should reset throttle_timer
}
assert!(
status.next().now_or_never().is_none(),
Expand Down

0 comments on commit 3229558

Please sign in to comment.