Skip to content

Commit c13f033

Browse files
protocols/kad: Check local store on get_providers (#2221)
1 parent d93a5ab commit c13f033

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

protocols/kad/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
- Introduce `KademliaStoreInserts` option, which allows to filter records (see
99
[PR 2163]).
1010

11+
- Check local store when calling `Kademlia::get_providers` (see [PR 2221]).
12+
1113
[PR 2163]: https://github.com/libp2p/rust-libp2p/pull/2163
14+
[PR 2221]: https://github.com/libp2p/rust-libp2p/pull/2163
1215

1316
# 0.31.0 [2021-07-12]
1417

protocols/kad/src/behaviour.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,9 +912,16 @@ where
912912
/// The result of this operation is delivered in a
913913
/// reported via [`KademliaEvent::OutboundQueryCompleted{QueryResult::GetProviders}`].
914914
pub fn get_providers(&mut self, key: record::Key) -> QueryId {
915+
let providers = self
916+
.store
917+
.providers(&key)
918+
.into_iter()
919+
.filter(|p| !p.is_expired(Instant::now()))
920+
.map(|p| p.provider)
921+
.collect();
915922
let info = QueryInfo::GetProviders {
916923
key: key.clone(),
917-
providers: HashSet::new(),
924+
providers,
918925
};
919926
let target = kbucket::Key::new(key);
920927
let peers = self.kbuckets.closest_keys(&target);

protocols/kad/src/behaviour/test.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,3 +1317,51 @@ fn network_behaviour_inject_address_change() {
13171317
kademlia.addresses_of_peer(&remote_peer_id),
13181318
);
13191319
}
1320+
1321+
#[test]
1322+
fn get_providers() {
1323+
fn prop(key: record::Key) {
1324+
let (_, mut single_swarm) = build_node();
1325+
single_swarm
1326+
.behaviour_mut()
1327+
.start_providing(key.clone())
1328+
.expect("could not provide");
1329+
1330+
block_on(async {
1331+
match single_swarm.next().await.unwrap() {
1332+
SwarmEvent::Behaviour(KademliaEvent::OutboundQueryCompleted {
1333+
result: QueryResult::StartProviding(Ok(_)),
1334+
..
1335+
}) => {}
1336+
SwarmEvent::Behaviour(e) => panic!("Unexpected event: {:?}", e),
1337+
_ => {}
1338+
}
1339+
});
1340+
1341+
let query_id = single_swarm.behaviour_mut().get_providers(key.clone());
1342+
1343+
block_on(async {
1344+
match single_swarm.next().await.unwrap() {
1345+
SwarmEvent::Behaviour(KademliaEvent::OutboundQueryCompleted {
1346+
id,
1347+
result:
1348+
QueryResult::GetProviders(Ok(GetProvidersOk {
1349+
key: found_key,
1350+
providers,
1351+
..
1352+
})),
1353+
..
1354+
}) if id == query_id => {
1355+
assert_eq!(key, found_key);
1356+
assert_eq!(
1357+
single_swarm.local_peer_id(),
1358+
providers.iter().next().unwrap()
1359+
);
1360+
}
1361+
SwarmEvent::Behaviour(e) => panic!("Unexpected event: {:?}", e),
1362+
_ => {}
1363+
}
1364+
});
1365+
}
1366+
QuickCheck::new().tests(10).quickcheck(prop as fn(_))
1367+
}

0 commit comments

Comments
 (0)