mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 01:51:23 +00:00
protocols/kad: Check local store on get_providers (#2221)
This commit is contained in:
@ -8,7 +8,10 @@
|
|||||||
- Introduce `KademliaStoreInserts` option, which allows to filter records (see
|
- Introduce `KademliaStoreInserts` option, which allows to filter records (see
|
||||||
[PR 2163]).
|
[PR 2163]).
|
||||||
|
|
||||||
|
- Check local store when calling `Kademlia::get_providers` (see [PR 2221]).
|
||||||
|
|
||||||
[PR 2163]: https://github.com/libp2p/rust-libp2p/pull/2163
|
[PR 2163]: https://github.com/libp2p/rust-libp2p/pull/2163
|
||||||
|
[PR 2221]: https://github.com/libp2p/rust-libp2p/pull/2163
|
||||||
|
|
||||||
# 0.31.0 [2021-07-12]
|
# 0.31.0 [2021-07-12]
|
||||||
|
|
||||||
|
@ -912,9 +912,16 @@ where
|
|||||||
/// The result of this operation is delivered in a
|
/// The result of this operation is delivered in a
|
||||||
/// reported via [`KademliaEvent::OutboundQueryCompleted{QueryResult::GetProviders}`].
|
/// reported via [`KademliaEvent::OutboundQueryCompleted{QueryResult::GetProviders}`].
|
||||||
pub fn get_providers(&mut self, key: record::Key) -> QueryId {
|
pub fn get_providers(&mut self, key: record::Key) -> QueryId {
|
||||||
|
let providers = self
|
||||||
|
.store
|
||||||
|
.providers(&key)
|
||||||
|
.into_iter()
|
||||||
|
.filter(|p| !p.is_expired(Instant::now()))
|
||||||
|
.map(|p| p.provider)
|
||||||
|
.collect();
|
||||||
let info = QueryInfo::GetProviders {
|
let info = QueryInfo::GetProviders {
|
||||||
key: key.clone(),
|
key: key.clone(),
|
||||||
providers: HashSet::new(),
|
providers,
|
||||||
};
|
};
|
||||||
let target = kbucket::Key::new(key);
|
let target = kbucket::Key::new(key);
|
||||||
let peers = self.kbuckets.closest_keys(&target);
|
let peers = self.kbuckets.closest_keys(&target);
|
||||||
|
@ -1317,3 +1317,51 @@ fn network_behaviour_inject_address_change() {
|
|||||||
kademlia.addresses_of_peer(&remote_peer_id),
|
kademlia.addresses_of_peer(&remote_peer_id),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_providers() {
|
||||||
|
fn prop(key: record::Key) {
|
||||||
|
let (_, mut single_swarm) = build_node();
|
||||||
|
single_swarm
|
||||||
|
.behaviour_mut()
|
||||||
|
.start_providing(key.clone())
|
||||||
|
.expect("could not provide");
|
||||||
|
|
||||||
|
block_on(async {
|
||||||
|
match single_swarm.next().await.unwrap() {
|
||||||
|
SwarmEvent::Behaviour(KademliaEvent::OutboundQueryCompleted {
|
||||||
|
result: QueryResult::StartProviding(Ok(_)),
|
||||||
|
..
|
||||||
|
}) => {}
|
||||||
|
SwarmEvent::Behaviour(e) => panic!("Unexpected event: {:?}", e),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let query_id = single_swarm.behaviour_mut().get_providers(key.clone());
|
||||||
|
|
||||||
|
block_on(async {
|
||||||
|
match single_swarm.next().await.unwrap() {
|
||||||
|
SwarmEvent::Behaviour(KademliaEvent::OutboundQueryCompleted {
|
||||||
|
id,
|
||||||
|
result:
|
||||||
|
QueryResult::GetProviders(Ok(GetProvidersOk {
|
||||||
|
key: found_key,
|
||||||
|
providers,
|
||||||
|
..
|
||||||
|
})),
|
||||||
|
..
|
||||||
|
}) if id == query_id => {
|
||||||
|
assert_eq!(key, found_key);
|
||||||
|
assert_eq!(
|
||||||
|
single_swarm.local_peer_id(),
|
||||||
|
providers.iter().next().unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SwarmEvent::Behaviour(e) => panic!("Unexpected event: {:?}", e),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
QuickCheck::new().tests(10).quickcheck(prop as fn(_))
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user