#peer-to-peer #libp2p #networking #discovery #discv5


Implementation of the p2p discv5 discovery protocol

26 releases

0.1.0-beta.13 Dec 22, 2021
0.1.0-beta.11 Oct 14, 2021
0.1.0-beta.8 Jul 21, 2021
0.1.0-beta.3 Feb 3, 2021
0.1.0-alpha.7 Jul 21, 2020

#230 in Network programming

Download history 1556/week @ 2022-01-24 1073/week @ 2022-01-31 1445/week @ 2022-02-07 1087/week @ 2022-02-14 1408/week @ 2022-02-21 2079/week @ 2022-02-28 1554/week @ 2022-03-07 1567/week @ 2022-03-14 1065/week @ 2022-03-21 1006/week @ 2022-03-28 1115/week @ 2022-04-04 775/week @ 2022-04-11 261/week @ 2022-04-18 215/week @ 2022-04-25 687/week @ 2022-05-02 663/week @ 2022-05-09

1,921 downloads per month
Used in discv5-cli

MIT license

10K SLoC


Build Status Doc Status Crates Status

Documentation at docs.rs


This is a rust implementation of the Discovery v5 peer discovery protocol.

Discovery v5 is a protocol designed for encrypted peer discovery and topic advertisement. Each peer/node on the network is identified via it's ENR (Ethereum Node Record), which is essentially a signed key-value store containing the node's public key and optionally IP address and port.

Discv5 employs a kademlia-like routing table to store and manage discovered peers and topics. The protocol allows for external IP discovery in NAT environments through regular PING/PONG's with discovered nodes. Nodes return the external IP address that they have received and a simple majority is chosen as our external IP address. If an external IP address is updated, this is produced as an event to notify the swarm (if one is used for this behaviour).

For a simple CLI discovery service see discv5-cli


A simple example of creating this service is as follows:

   use discv5::{enr, enr::{CombinedKey, NodeId}, TokioExecutor, Discv5, Discv5ConfigBuilder};
   use std::net::SocketAddr;

   // listening address and port
   let listen_addr = "".parse::<SocketAddr>().unwrap();

   // construct a local ENR
   let enr_key = CombinedKey::generate_secp256k1();
   let enr = enr::EnrBuilder::new("v4").build(&enr_key).unwrap();

   // build the tokio executor
   let mut runtime = tokio::runtime::Builder::new_multi_thread()

   // default configuration
   let config = Discv5ConfigBuilder::new().build();

   // construct the discv5 server
   let mut discv5 = Discv5::new(enr, enr_key, config).unwrap();

   // In order to bootstrap the routing table an external ENR should be added
   // This can be done via add_enr. I.e.:
   // discv5.add_enr(<ENR>)

   // start the discv5 server

   // run a find_node query
   runtime.block_on(async {
      let found_nodes = discv5.find_node(NodeId::random()).await.unwrap();
      println!("Found nodes: {:?}", found_nodes);


~412K SLoC