I am trying to configure rust-libp2p, to use kademlia for peer discovery and to be able to discover more peers after connecting to a bootstrap node.
I was able to achieve what I wanted with js-libp2p but could not with rust-libp2p. The js-libp2p code is as follows:
(async () => {
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [new TCP()],
streamMuxers: [new Mplex()],
connectionEncryption: [new Noise()],
dht: new KadDHT({
kBucketSize: 20,
clientMode: false,
}),
peerDiscovery: [
new Bootstrap({
interval: 60e3,
list: ['/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ']
})
]
})
node.connectionManager.addEventListener('peer:connect', (evt) => {
const connection = evt.detail
node.peerStore.addressBook.add(connection.remotePeer, [connection.remoteAddr])
console.log('Connection established to:', connection.remotePeer.toString())
})
node.addEventListener('peer:discovery', (evt) => {
const peer = evt.detail
console.log('Discovered:', peer.id.toString(), peer.multiaddrs.toString())
})
node.peerStore.addEventListener('peer', (peerId) => {
console.log(`added to peer store: ${JSON.stringify(peerId.detail.id)}`)
})
await node.start()
})();
And when I run it, I see the following in the console:
Discovered: QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ /ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
Discovered: QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ /ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
Connection established to: QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
...<after about 10 seconds of pause>....
Discovered: 12D3KooWHzYS5y4jNuVixHSgH6scDkH4sMajjMsARRxRXtUsJSMt /ip4/127.0.0.1/tcp/4001,/ip6/::1/tcp/4001,/ip4/148.59.59.172/tcp/4001,/ip4/10.20.20.96/udp/4001/quic,/ip4/127.0.0.1/udp/4001/quic,/ip6/::1/udp/4001/quic,/ip4/10.20.20.96/tcp/4001
Discovered: QmNrW6qRFC2tExR7o33XSakfuZXuewv3A77FYEAUCWsSbS /ip4/10.0.68.134/tcp/4001,/ip4/54.211.214.244/udp/4001/quic,/ip4/127.0.0.1/tcp/4001,/ip4/10.0.68.134/udp/4001/quic,/ip6/::1/udp/4001/quic,/ip6/64:ff9b::36d3:d6f4/udp/4001/quic,/ip4/54.211.214.244/udp/1024/quic,/ip4/127.0.0.1/udp/4001/quic,/ip4/54.211.214.244/tcp/4001,/ip6/::1/tcp/4001,/ip6/64:ff9b::36d3:d6f4/tcp/4001
Discovered: 12D3KooWHBvqsc47XpWovZJGmjFWJb414fzz1Vw2v5BnudvmncxZ /ip4/127.0.0.1/udp/30006/quic,/ip4/13.59.159.106/udp/30006/quic,/ip4/13.59.159.106/tcp/30006,/ip4/172.31.11.43/tcp/30006,/ip4/127.0.0.1/tcp/30006,/ip4/172.31.11.43/udp/30006/quic
Discovered: QmeJBm1E2NdNEE4dGK4zu9jo8XdDdnUayRGnjGQKenJ2Ui /ip4/139.178.68.153/tcp/4001,/ip4/139.178.68.153/tcp/4002/ws,/ip4/139.178.68.153/udp/4001/quic,/ip6/2604:1380:45e2:b200::7/tcp/4001,/ip6/2604:1380:45e2:b200::7/tcp/4002/ws,/ip6/2604:1380:45e2:b200::7/udp/4001/quic
...
Which shows, that after establishing connection to QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
, there was a pause, and more peers were discovered.
I tried to replicate this in Rust as follows:
#[derive(NetworkBehaviour)]
#[behaviour(event_process = true)]
struct CustomBehaviour {
mdns: Mdns,
kad: Kademlia<MemoryStore>
}
impl NetworkBehaviourEventProcess<MdnsEvent> for CustomBehaviour {
// Called when `mdns` produces an event.
fn inject_event(&mut self, event: MdnsEvent) {
if let MdnsEvent::Discovered(list) = event {
for (peer_id, multiaddr) in list {
println!("multiaddr {:?}", multiaddr);
println!("peer_id {:?}", peer_id);
}
}
}
}
impl NetworkBehaviourEventProcess<KademliaEvent> for CustomBehaviour {
fn inject_event(&mut self, event: KademliaEvent) {
println!("{:?}", event);
}
}
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
let local_key = identity::Keypair::generate_ed25519();
let peer_id = PeerId::from(local_key.public());
println!("Local peer id: {:?}", peer_id);
let transport = libp2p::development_transport(local_key).await?;
//let behaviour: Behaviour = Ping::new(PingConfig::new().with_keep_alive(true));
let mdnsBehaviour = Mdns::new(MdnsConfig::default()).await?;
let mut kadBehaviour = Kademlia::new(peer_id, MemoryStore::new(peer_id));
let bootaddr = Multiaddr::from_str("/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ")?;
for peer in &BOOTNODES {
kadBehaviour.add_address(&PeerId::from_str(peer)?, bootaddr.clone());
}
let mut swarm = Swarm::new(transport, CustomBehaviour {
mdns: mdnsBehaviour,
kad: kadBehaviour
}, peer_id);
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
if let Some(addr) = std::env::args().nth(1) {
let remote: Multiaddr = addr.parse()?;
swarm.dial(remote)?;
println!("Dialed {}", addr)
}
loop {
match swarm.select_next_some().await {
SwarmEvent::NewListenAddr {address, ..} => println!("Listening on {:?}", address),
_ => ()
}
}
}
and when I run it I get the following in the output:
warning: `scanp2p` (bin "scanp2p") generated 5 warnings
Finished dev [unoptimized + debuginfo] target(s) in 0.44s
Running `target/debug/scanp2p`
Local peer id: PeerId("12D3KooWMXvTUp8dYc4VgW46fhkr5Q1Xe8BdXVnoa6rEanZEMjoJ")
Listening on "/ip4/127.0.0.1/tcp/51372"
Listening on "/ip4/192.168.101.41/tcp/51372"
RoutingUpdated { peer: PeerId("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"), is_new_peer: true, addresses: ["/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"], bucket_range: (Distance(28948022309329048855892746252171976963317496166410141009864396001978282409984), Distance(57896044618658097711785492504343953926634992332820282019728792003956564819967)), old_peer: None }
Showing that it connected to the bootnode but that is where it stopped. Nothing else gets consoled to the logs even after waiting for minutes.
What am I missing in the rust-libp2p
version? What do I need to configure, to enable it to discover more peers after connecting to the bootnode, just like how the js-libp2p version behaved?