Add DHT key-value behaviour (#2937)

* Add DHT key-value behaviour

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Apply suggestions from code review

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Return which key failed to be inserted
This commit is contained in:
Fedor Sakharov
2019-06-26 14:30:39 +03:00
committed by Pierre Krieger
parent 0ddf4a2a00
commit e735853ca3
9 changed files with 181 additions and 14 deletions
+53 -4
View File
@@ -18,10 +18,11 @@ use futures::prelude::*;
use libp2p::core::{Multiaddr, PeerId, ProtocolsHandler, PublicKey};
use libp2p::core::swarm::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction};
use libp2p::core::swarm::PollParameters;
use libp2p::kad::{Kademlia, KademliaOut};
use libp2p::kad::{GetValueResult, Kademlia, KademliaOut, PutValueResult};
use libp2p::multihash::Multihash;
use libp2p::multiaddr::Protocol;
use log::{debug, info, trace, warn};
use std::{cmp, time::Duration};
use std::{cmp, num::NonZeroU8, time::Duration};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_timer::{Delay, clock::Clock};
@@ -81,12 +82,35 @@ impl<TSubstream> DiscoveryBehaviour<TSubstream> {
pub fn add_self_reported_address(&mut self, peer_id: &PeerId, addr: Multiaddr) {
self.kademlia.add_address(peer_id, addr);
}
/// Get a record from the DHT.
pub fn get_value(&mut self, key: &Multihash) {
self.kademlia.get_value(key, NonZeroU8::new(10)
.expect("Casting 10 to NonZeroU8 should succeed; qed"));
}
/// Put a record into the DHT.
pub fn put_value(&mut self, key: Multihash, value: Vec<u8>) {
self.kademlia.put_value(key, value);
}
}
/// Event generated by the `DiscoveryBehaviour`.
pub enum DiscoveryOut {
/// We have discovered a node. Can be called multiple times with the same identity.
Discovered(PeerId),
/// The DHT yeided results for the record request, grouped in (key, value) pairs.
ValueFound(Vec<(Multihash, Vec<u8>)>),
/// The record requested was not found in the DHT.
ValueNotFound(Multihash),
/// The record with a given key was successfully inserted into the DHT.
ValuePut(Multihash),
/// Inserting a value into the DHT failed.
ValuePutFailed(Multihash),
}
impl<TSubstream> NetworkBehaviour for DiscoveryBehaviour<TSubstream>
@@ -175,10 +199,35 @@ where
results");
}
}
KademliaOut::GetValueResult(res) => {
let ev = match res {
GetValueResult::Found { results } => {
let results = results
.into_iter()
.map(|r| (r.key, r.value))
.collect();
DiscoveryOut::ValueFound(results)
}
GetValueResult::NotFound { key, .. } => {
DiscoveryOut::ValueNotFound(key)
}
};
return Async::Ready(NetworkBehaviourAction::GenerateEvent(ev));
}
KademliaOut::PutValueResult(res) => {
let ev = match res {
PutValueResult::Ok{ key, .. } => {
DiscoveryOut::ValuePut(key)
}
PutValueResult::Err { key, .. } => {
DiscoveryOut::ValuePutFailed(key)
}
};
return Async::Ready(NetworkBehaviourAction::GenerateEvent(ev));
}
// We never start any other type of query.
KademliaOut::GetProvidersResult { .. } => {}
KademliaOut::GetValueResult(_) => {}
KademliaOut::PutValueResult(_) => {}
}
},
Async::Ready(NetworkBehaviourAction::DialAddress { address }) =>