Skip to content

Commit

Permalink
fix(kad): correctly handle NoKnownPeers error when bootstrap
Browse files Browse the repository at this point in the history
After testing `master`, we encountered a bug due to #4838 when doing automatic or periodic bootstrap if the node has no known peers.

Since it failed immediately, I though there was no need to call the `bootstrap_status.on_started` method. But not doing so never resets the periodic timer inside `bootstrap_status` resulting in getting stuck to try to bootstrap every time `poll` is called on `kad::Behaviour`.

Pull-Request: #5349.
  • Loading branch information
stormshield-frb authored Jun 18, 2024
1 parent 0b1733d commit 32e917f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
2 changes: 2 additions & 0 deletions protocols/kad/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
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).
- Correctly handle the `NoKnownPeers` error on automatic bootstrap.
See [PR 5349](https://github.com/libp2p/rust-libp2p/pull/5349).

## 0.45.3

Expand Down
1 change: 1 addition & 0 deletions protocols/kad/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ where
};
let peers = self.kbuckets.closest_keys(&local_key).collect::<Vec<_>>();
if peers.is_empty() {
self.bootstrap_status.reset_timers();
Err(NoKnownPeers())
} else {
self.bootstrap_status.on_started();
Expand Down
18 changes: 11 additions & 7 deletions protocols/kad/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,23 @@ impl Status {
}
}

pub(crate) fn reset_timers(&mut self) {
// Canceling the `throttle_timer` if any and resetting the `delay` if any.
self.throttle_timer = None;

if let Some((interval, delay)) = self.interval_and_delay.as_mut() {
delay.reset(*interval);
}
}

pub(crate) fn on_started(&mut self) {
// No periodic or automatic bootstrap will be triggered as long as
// `self.current_bootstrap_requests > 0` but the user could still manually
// trigger a bootstrap.
self.current_bootstrap_requests += 1;

// Canceling the `throttle_timer` if any since a bootstrap request is being triggered right now.
self.throttle_timer = None;

// Resetting the `delay` if any since a bootstrap request is being triggered right now.
if let Some((interval, delay)) = self.interval_and_delay.as_mut() {
delay.reset(*interval);
}
// Resetting the Status timers since a bootstrap request is being triggered right now.
self.reset_timers();
}

pub(crate) fn on_finish(&mut self) {
Expand Down

0 comments on commit 32e917f

Please sign in to comment.