use futures::prelude::*;
use libp2p::{
Swarm,
PeerId,
identity,
build_development_transport
};
use libp2p::kad::{Kademlia, KademliaConfig, KademliaEvent, GetClosestPeersError};
use libp2p::kad::record::store::MemoryStore;
use std::env;
use std::time::Duration;
fn main() {
env_logger::init();
let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
let transport = build_development_transport(local_key);
let mut swarm = {
let mut cfg = KademliaConfig::default();
cfg.set_query_timeout(Duration::from_secs(5 * 60));
let store = MemoryStore::new(local_peer_id.clone());
let mut behaviour = Kademlia::with_config(local_peer_id.clone(), store, cfg);
behaviour.add_address(&"QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ".parse().unwrap(), "/ip4/104.131.131.82/tcp/4001".parse().unwrap());
Swarm::new(transport, behaviour, local_peer_id)
};
let to_search: PeerId = if let Some(peer_id) = env::args().nth(1) {
peer_id.parse().expect("Failed to parse peer ID to find")
} else {
identity::Keypair::generate_ed25519().public().into()
};
println!("Searching for the closest peers to {:?}", to_search);
swarm.get_closest_peers(to_search);
tokio::run(futures::future::poll_fn(move || {
loop {
match swarm.poll().expect("Error while polling swarm") {
Async::Ready(Some(KademliaEvent::GetClosestPeersResult(res))) => {
match res {
Ok(ok) => {
if !ok.peers.is_empty() {
println!("Query finished with closest peers: {:#?}", ok.peers);
return Ok(Async::Ready(()));
} else {
panic!("Query finished with no closest peers.");
}
}
Err(GetClosestPeersError::Timeout { peers, .. }) => {
if !peers.is_empty() {
println!("Query timed out with closest peers: {:#?}", peers);
return Ok(Async::Ready(()));
} else {
panic!("Query timed out with no closest peers.");
}
}
}
},
Async::Ready(Some(_)) => {},
Async::Ready(None) | Async::NotReady => break,
}
}
Ok(Async::NotReady)
}));
}