protocols/kad: Implement S-Kademlia's lookup over disjoint paths v2 (#1473)

The extension paper S-Kademlia includes a proposal for lookups over
disjoint paths. Within vanilla Kademlia, queries keep track of the
closest nodes in a single bucket. Any adversary along the path can thus
influence all future paths, in case they can come up with the
next-closest (not overall closest) hops. S-Kademlia tries to solve the
attack above by querying over disjoint paths using multiple buckets.

To adjust the libp2p Kademlia implementation accordingly this change-set
introduces an additional peers iterator: `ClosestDisjointPeersIter`.
This new iterator wraps around a set of `ClosestPeersIter`
`ClosestDisjointPeersIter` enforces that each of the `ClosestPeersIter`
explore disjoint paths by having each peer instantly return that was
queried by a different iterator before.
This commit is contained in:
Max Inden
2020-06-19 12:22:26 +02:00
committed by GitHub
parent 00fc223487
commit 9dd2d662e9
10 changed files with 1432 additions and 120 deletions

View File

@ -33,13 +33,14 @@ use async_std::{io, task};
use futures::prelude::*;
use libp2p::kad::record::store::MemoryStore;
use libp2p::kad::{
record::Key,
Kademlia,
KademliaEvent,
PeerRecord,
PutRecordOk,
QueryResult,
Quorum,
Record
Record,
record::Key,
};
use libp2p::{
NetworkBehaviour,
@ -86,7 +87,7 @@ fn main() -> Result<(), Box<dyn Error>> {
match message {
KademliaEvent::QueryResult { result, .. } => match result {
QueryResult::GetRecord(Ok(ok)) => {
for Record { key, value, .. } in ok.records {
for PeerRecord { record: Record { key, value, .. }, ..} in ok.records {
println!(
"Got record {:?} {:?}",
std::str::from_utf8(key.as_ref()).unwrap(),