From 9324fa13bb1ad712680596a6bff6f2a0b395e2f4 Mon Sep 17 00:00:00 2001 From: qima Date: Mon, 27 Nov 2023 22:15:53 +0800 Subject: [PATCH] fix(kad): close progress whenever closer in range --- Cargo.lock | 2 +- Cargo.toml | 2 +- protocols/kad/CHANGELOG.md | 4 ++++ protocols/kad/Cargo.toml | 2 +- protocols/kad/src/query/peers/closest.rs | 25 +++++++++++++++++------- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 168ffb2034cd..18000145d366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2721,7 +2721,7 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.45.2" +version = "0.45.3" dependencies = [ "arrayvec", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 1dce34011c8e..2b9d5a2b4eda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ libp2p-floodsub = { version = "0.44.0", path = "protocols/floodsub" } libp2p-gossipsub = { version = "0.46.1", path = "protocols/gossipsub" } libp2p-identify = { version = "0.44.1", path = "protocols/identify" } libp2p-identity = { version = "0.2.8" } -libp2p-kad = { version = "0.45.2", path = "protocols/kad" } +libp2p-kad = { version = "0.45.3", path = "protocols/kad" } libp2p-mdns = { version = "0.45.1", path = "protocols/mdns" } libp2p-memory-connection-limits = { version = "0.2.0", path = "misc/memory-connection-limits" } libp2p-metrics = { version = "0.14.1", path = "misc/metrics" } diff --git a/protocols/kad/CHANGELOG.md b/protocols/kad/CHANGELOG.md index 4740e4b1f958..196cad3ceacf 100644 --- a/protocols/kad/CHANGELOG.md +++ b/protocols/kad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.45.3 +- Close progress whenever closer in range, instead of having to be the closest. + See [PR 4596](https://github.com/libp2p/rust-libp2p/pull/4934). + ## 0.45.2 - Ensure `Multiaddr` handled and returned by `Behaviour` are `/p2p` terminated. diff --git a/protocols/kad/Cargo.toml b/protocols/kad/Cargo.toml index 1e4c788cf003..f4ad83972b42 100644 --- a/protocols/kad/Cargo.toml +++ b/protocols/kad/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-kad" edition = "2021" rust-version = { workspace = true } description = "Kademlia protocol for libp2p" -version = "0.45.2" +version = "0.45.3" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/protocols/kad/src/query/peers/closest.rs b/protocols/kad/src/query/peers/closest.rs index 01155b7f0106..18300b5ba717 100644 --- a/protocols/kad/src/query/peers/closest.rs +++ b/protocols/kad/src/query/peers/closest.rs @@ -175,6 +175,17 @@ impl ClosestPeersIter { }, } + let mut cur_range = distance; + let mut index = 0; + for (dist, _state) in self.closest_peers.iter() { + if index < self.config.num_results.get() { + index += 1; + cur_range = *dist; + } else { + break; + } + } + let num_closest = self.closest_peers.len(); let mut progress = false; @@ -187,11 +198,10 @@ impl ClosestPeersIter { state: PeerState::NotContacted, }; self.closest_peers.entry(distance).or_insert(peer); - // The iterator makes progress if the new peer is either closer to the target - // than any peer seen so far (i.e. is the first entry), or the iterator did - // not yet accumulate enough closest peers. - progress = self.closest_peers.keys().next() == Some(&distance) - || num_closest < self.config.num_results.get(); + // The iterator makes progress if either any of the new peer is among the `num_results` + // closest peers to the target seen so far, + // or the iterator did not yet accumulate enough closest peers. + progress = distance < cur_range || num_closest < self.config.num_results.get(); } // Update the iterator state. @@ -316,8 +326,9 @@ impl ClosestPeersIter { if let Some(ref mut cnt) = result_counter { *cnt += 1; // If `num_results` successful results have been delivered for the - // closest peers, the iterator is done. - if *cnt >= self.config.num_results.get() { + // closest peers, AND there is no `waiting on result` peer so far, + // the iterator is done. + if *cnt >= self.config.num_results.get() && result_counter.is_some() { self.state = State::Finished; return PeersIterState::Finished; }