Skip to content

Commit 84c617f

Browse files
nazar-pcjxs
andauthored
feat(kad): add Behavior::find_closest_local_peers() (#5645)
## Description Fixes #5626 ## Notes & open questions This is the nicest way I came up with, I decided to leave `get_closest_local_peers` as is since it does return all peers, not just `replication_factor` peers. Looking at #2436 it is not clear if @folex really needed all peers returned or it just happened that way. I'm also happy to change proposed API to return all peers if that is preferred by others. It is very unfortunate that `&mut self` is needed for this, I created #5644 that if resolved will allow to have `&self` instead. ## Change checklist - [x] I have performed a self-review of my own code - [x] I have made corresponding changes to the documentation - [ ] I have added tests that prove my fix is effective or that my feature works - [x] A changelog entry has been made in the appropriate crates Co-authored-by: João Oliveira <[email protected]>
1 parent 6cb116e commit 84c617f

File tree

3 files changed

+32
-23
lines changed

3 files changed

+32
-23
lines changed

protocols/kad/CHANGELOG.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
## 0.47.0
22

3-
- Expose a kad query facility allowing specify num_results dynamicly.
3+
- Expose a kad query facility allowing specify num_results dynamicaly.
44
See [PR 5555](https://github.com/libp2p/rust-libp2p/pull/5555).
55
- Add `mode` getter on `Behaviour`.
66
See [PR 5573](https://github.com/libp2p/rust-libp2p/pull/5573).
7-
7+
- Add `Behavior::find_closest_local_peers()`.
8+
See [PR 5645](https://github.com/libp2p/rust-libp2p/pull/5645).
89

910
## 0.46.2
1011

protocols/kad/src/behaviour.rs

+28-20
Original file line numberDiff line numberDiff line change
@@ -771,14 +771,32 @@ where
771771
self.queries.add_iter_closest(target, peer_keys, info)
772772
}
773773

774-
/// Returns closest peers to the given key; takes peers from local routing table only.
774+
/// Returns all peers ordered by distance to the given key; takes peers from local routing table
775+
/// only.
775776
pub fn get_closest_local_peers<'a, K: Clone>(
776777
&'a mut self,
777778
key: &'a kbucket::Key<K>,
778779
) -> impl Iterator<Item = kbucket::Key<PeerId>> + 'a {
779780
self.kbuckets.closest_keys(key)
780781
}
781782

783+
/// Finds the closest peers to a `key` in the context of a request by the `source` peer, such
784+
/// that the `source` peer is never included in the result.
785+
///
786+
/// Takes peers from local routing table only. Only returns number of peers equal to configured
787+
/// replication factor.
788+
pub fn find_closest_local_peers<'a, K: Clone>(
789+
&'a mut self,
790+
key: &'a kbucket::Key<K>,
791+
source: &'a PeerId,
792+
) -> impl Iterator<Item = KadPeer> + 'a {
793+
self.kbuckets
794+
.closest(key)
795+
.filter(move |e| e.node.key.preimage() != source)
796+
.take(self.queries.config().replication_factor.get())
797+
.map(KadPeer::from)
798+
}
799+
782800
/// Performs a lookup for a record in the DHT.
783801
///
784802
/// The result of this operation is delivered in a
@@ -1212,22 +1230,6 @@ where
12121230
}
12131231
}
12141232

1215-
/// Finds the closest peers to a `target` in the context of a request by
1216-
/// the `source` peer, such that the `source` peer is never included in the
1217-
/// result.
1218-
fn find_closest<T: Clone>(
1219-
&mut self,
1220-
target: &kbucket::Key<T>,
1221-
source: &PeerId,
1222-
) -> Vec<KadPeer> {
1223-
self.kbuckets
1224-
.closest(target)
1225-
.filter(|e| e.node.key.preimage() != source)
1226-
.take(self.queries.config().replication_factor.get())
1227-
.map(KadPeer::from)
1228-
.collect()
1229-
}
1230-
12311233
/// Collects all peers who are known to be providers of the value for a given `Multihash`.
12321234
fn provider_peers(&mut self, key: &record::Key, source: &PeerId) -> Vec<KadPeer> {
12331235
let kbuckets = &mut self.kbuckets;
@@ -2300,7 +2302,9 @@ where
23002302
}
23012303

23022304
HandlerEvent::FindNodeReq { key, request_id } => {
2303-
let closer_peers = self.find_closest(&kbucket::Key::new(key), &source);
2305+
let closer_peers = self
2306+
.find_closest_local_peers(&kbucket::Key::new(key), &source)
2307+
.collect::<Vec<_>>();
23042308

23052309
self.queued_events
23062310
.push_back(ToSwarm::GenerateEvent(Event::InboundRequest {
@@ -2328,7 +2332,9 @@ where
23282332

23292333
HandlerEvent::GetProvidersReq { key, request_id } => {
23302334
let provider_peers = self.provider_peers(&key, &source);
2331-
let closer_peers = self.find_closest(&kbucket::Key::new(key), &source);
2335+
let closer_peers = self
2336+
.find_closest_local_peers(&kbucket::Key::new(key), &source)
2337+
.collect::<Vec<_>>();
23322338

23332339
self.queued_events
23342340
.push_back(ToSwarm::GenerateEvent(Event::InboundRequest {
@@ -2422,7 +2428,9 @@ where
24222428
None => None,
24232429
};
24242430

2425-
let closer_peers = self.find_closest(&kbucket::Key::new(key), &source);
2431+
let closer_peers = self
2432+
.find_closest_local_peers(&kbucket::Key::new(key), &source)
2433+
.collect::<Vec<_>>();
24262434

24272435
self.queued_events
24282436
.push_back(ToSwarm::GenerateEvent(Event::InboundRequest {

protocols/kad/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub use behaviour::{
6969
pub use kbucket::{
7070
Distance as KBucketDistance, EntryView, KBucketRef, Key as KBucketKey, NodeStatus,
7171
};
72-
pub use protocol::ConnectionType;
72+
pub use protocol::{ConnectionType, KadPeer};
7373
pub use query::QueryId;
7474
pub use record::{store, Key as RecordKey, ProviderRecord, Record};
7575

0 commit comments

Comments
 (0)