Skip to content

Commit

Permalink
Merge master into discv5.2 (#234)
Browse files Browse the repository at this point in the history
* Version bump to v0.3.1 (#203)

* fix docs (#204)

* refactor for removing `Discv5` prefix (#206)

* goodbye prefix

* adjust docs

* fix rpc decoding to reject extra data (#208)

* reject extra data

* reduce diff

* expected_responses remains after challenge has been completed (#210)

* Replace `Handler::spawn` with `build_handler()` and `Handler::start()`

* Test the handler's states after the handler has been terminated

* Remove expected response on handle_auth_message()

* Rename variables for readability

* Expose local ENR Arc (#214)

* Use zero ports in tests (#216)

* update dependencies (#219)

* Changing port of ReponseBody::Pong to NonZeroU16 (#220)

* Change `port` from u16 to NonZeroU16

* Fix tests

* Fix test: the PONG port can't be zero

* Fix clippy warnings

* Update 'enr' dependency (#223)

* Add support for concurrent requests to a single peer. (#200)

Co-authored-by: ackintosh <[email protected]>
Co-authored-by: Diva M <[email protected]>
Co-authored-by: Age Manning <[email protected]>

* Adjust some logs (#225)

* remove log for timed out query. This is always informed in the callback

* expand common logs, unify info on startup

* adjust auth header log

* Update src/service.rs

* Appease clippy

* Realised I was wrong. Don't need this log, my bad

* fmt

---------

Co-authored-by: Age Manning <[email protected]>

* Version bump to v0.4.0

* make tracing-subscriber a dev dep (#226)

* Fix warnings and bump libp2p (#232)

* Update session_cache_capacity from usize to NonZeroUsize

since the argument of LruCache::new is NonZeroUsize.

* Fix rustdoc

* cargo fmt

* Fix a merging mistake: lost validation in Message::decode

---------

Co-authored-by: Age Manning <[email protected]>
Co-authored-by: Divma <[email protected]>
Co-authored-by: Jack McPherson <[email protected]>
Co-authored-by: João Oliveira <[email protected]>
Co-authored-by: Milos Stankovic <[email protected]>
Co-authored-by: Nick Gheorghita <[email protected]>
Co-authored-by: Diva M <[email protected]>
  • Loading branch information
8 people authored Feb 21, 2024
1 parent 04f2dc6 commit 088a171
Show file tree
Hide file tree
Showing 26 changed files with 1,549 additions and 611 deletions.
67 changes: 33 additions & 34 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "discv5"
authors = ["Age Manning <[email protected]>"]
edition = "2018"
version = "0.3.0"
version = "0.4.1"
description = "Implementation of the p2p discv5 discovery protocol"
license = "Apache-2.0"
repository = "https:/sigp/discv5"
Expand All @@ -12,43 +12,42 @@ categories = ["network-programming", "asynchronous"]
exclude = [".gitignore", ".github/*"]

[dependencies]
enr = { version = "0.8.1", features = ["k256", "ed25519"] }
tokio = { version = "1.15.0", features = ["net", "sync", "macros", "rt"] }
libp2p-core = { version = "0.40.0", optional = true }
libp2p-identity = { version = "0.2.1", features = ["ed25519", "secp256k1"], optional = true }
zeroize = { version = "1.4.3", features = ["zeroize_derive"] }
futures = "0.3.19"
uint = { version = "0.9.1", default-features = false }
rlp = "0.5.1"
enr = { version = "0.10", features = ["k256", "ed25519"] }
tokio = { version = "1", features = ["net", "sync", "macros", "rt"] }
libp2p = { version = "0.53", features = ["ed25519", "secp256k1"], optional = true }
zeroize = { version = "1", features = ["zeroize_derive"] }
futures = "0.3"
uint = { version = "0.9", default-features = false }
rlp = "0.5"
# This version must be kept up to date do it uses the same dependencies as ENR
hkdf = "0.12.3"
hex = "0.4.3"
fnv = "1.0.7"
arrayvec = "0.7.2"
rand = { version = "0.8.4", package = "rand" }
socket2 = "0.4.4"
smallvec = "1.7.0"
parking_lot = "0.11.2"
lazy_static = "1.4.0"
aes = { version = "0.7.5", features = ["ctr"] }
aes-gcm = "0.9.4"
tracing = { version = "0.1.29", features = ["log"] }
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
lru = {version = "0.7.1", default-features = false }
hashlink = "0.7.0"
delay_map = "0.3.0"
more-asserts = "0.2.2"
derive_more = { version = "0.99.17", default-features = false, features = ["from", "display", "deref", "deref_mut"] }
hkdf = "0.12"
hex = "0.4"
fnv = "1"
arrayvec = "0.7"
rand = { version = "0.8", package = "rand" }
socket2 = "0.4"
smallvec = "1"
parking_lot = "0.11"
lazy_static = "1"
aes = { version = "0.7", features = ["ctr"] }
aes-gcm = "0.9"
tracing = { version = "0.1", features = ["log"] }
lru = { version = "0.12", default-features = false }
hashlink = "0.8"
delay_map = "0.3"
more-asserts = "0.3"
derive_more = { version = "0.99", default-features = false, features = ["from", "display", "deref", "deref_mut"] }

[dev-dependencies]
clap = { version = "4", features = ["derive"] }
if-addrs = "0.10"
quickcheck = "0.9"
rand_07 = { package = "rand", version = "0.7" }
quickcheck = "0.9.2"
tokio = { version = "1.15.0", features = ["full"] }
rand_xorshift = "0.3.0"
rand_core = "0.6.3"
clap = { version = "3.1", features = ["derive"] }
if-addrs = "0.10.1"
rand_core = "0.6"
rand_xorshift = "0.3"
tokio = { version = "1", features = ["full"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

[features]
libp2p = ["libp2p-core", "libp2p-identity"]
libp2p = ["dep:libp2p"]
serde = ["enr/serde"]
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ Status]][Crates Link]
This is a rust implementation of the [Discovery v5](https:/ethereum/devp2p/blob/master/discv5/discv5.md)
peer discovery protocol.

Discovery v5 is a protocol designed for encrypted peer discovery (and topic advertisement tba). Each peer/node
on the network is identified via it's `ENR` ([Ethereum Node
Record](https://eips.ethereum.org/EIPS/eip-778)), which is essentially a signed key-value store
containing the node's public key and optionally IP address and port.
Discovery v5 is a protocol designed for encrypted peer discovery. Each peer/node on the network is
identified via it's `ENR` ([Ethereum Node Record](https://eips.ethereum.org/EIPS/eip-778)), 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
Expand All @@ -37,13 +37,13 @@ For a simple CLI discovery service see [discv5-cli](https:/AgeMannin
A simple example of creating this service is as follows:

```rust
use discv5::{enr, enr::{CombinedKey, NodeId}, TokioExecutor, Discv5, Discv5ConfigBuilder};
use discv5::{enr, enr::{CombinedKey, NodeId}, TokioExecutor, Discv5, ConfigBuilder};
use discv5::socket::ListenConfig;
use std::net::SocketAddr;

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

// build the tokio executor
let mut runtime = tokio::runtime::Builder::new_multi_thread()
Expand All @@ -59,7 +59,7 @@ A simple example of creating this service is as follows:
};

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

// construct the discv5 server
let mut discv5: Discv5 = Discv5::new(enr, enr_key, config).unwrap();
Expand Down
10 changes: 5 additions & 5 deletions examples/custom_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! $ cargo run --example custom_executor <BASE64ENR>
//! ```

use discv5::{enr, enr::CombinedKey, Discv5, Discv5ConfigBuilder, Discv5Event, ListenConfig};
use discv5::{enr, enr::CombinedKey, ConfigBuilder, Discv5, Event, ListenConfig};
use std::net::Ipv4Addr;

fn main() {
Expand All @@ -29,7 +29,7 @@ fn main() {

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

// build the tokio executor
let runtime = tokio::runtime::Builder::new_multi_thread()
Expand All @@ -39,7 +39,7 @@ fn main() {
.unwrap();

// default configuration - uses the current executor
let config = Discv5ConfigBuilder::new(listen_config).build();
let config = ConfigBuilder::new(listen_config).build();

// construct the discv5 server
let mut discv5: Discv5 = Discv5::new(enr, enr_key, config).unwrap();
Expand Down Expand Up @@ -72,10 +72,10 @@ fn main() {

loop {
match event_stream.recv().await {
Some(Discv5Event::SocketUpdated(addr)) => {
Some(Event::SocketUpdated(addr)) => {
println!("Nodes ENR socket address has been updated to: {addr:?}");
}
Some(Discv5Event::Discovered(enr)) => {
Some(Event::Discovered(enr)) => {
println!("A peer has been discovered: {}", enr.node_id());
}
_ => {}
Expand Down
21 changes: 11 additions & 10 deletions examples/find_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use clap::Parser;
use discv5::{
enr,
enr::{k256, CombinedKey},
Discv5, Discv5ConfigBuilder, Discv5Event, ListenConfig,
ConfigBuilder, Discv5, Event, ListenConfig,
};
use std::{
net::{IpAddr, Ipv4Addr, Ipv6Addr},
Expand Down Expand Up @@ -90,7 +90,7 @@ async fn main() {
};

let enr = {
let mut builder = enr::EnrBuilder::new("v4");
let mut builder = enr::Enr::builder();
if let Some(ip4) = args.enr_ip4 {
// if the given address is the UNSPECIFIED address we want to advertise localhost
if ip4.is_unspecified() {
Expand Down Expand Up @@ -120,10 +120,10 @@ async fn main() {
};

// default configuration with packet filtering
// let config = Discv5ConfigBuilder::new(listen_config).enable_packet_filter().build();
// let config = ConfigBuilder::new(listen_config).enable_packet_filter().build();

// default configuration without packet filtering
let config = Discv5ConfigBuilder::new(listen_config).build();
let config = ConfigBuilder::new(listen_config).build();

info!("Node Id: {}", enr.node_id());
if args.enr_ip6.is_some() || args.enr_ip4.is_some() {
Expand Down Expand Up @@ -192,18 +192,19 @@ async fn main() {
continue;
}
match discv5_ev {
Discv5Event::Discovered(enr) => info!("Enr discovered {}", enr),
Discv5Event::EnrAdded { enr, replaced: _ } => info!("Enr added {}", enr),
Discv5Event::NodeInserted { node_id, replaced: _ } => info!("Node inserted {}", node_id),
Discv5Event::SessionEstablished(enr, _) => info!("Session established {}", enr),
Discv5Event::SocketUpdated(addr) => info!("Socket updated {}", addr),
Discv5Event::TalkRequest(_) => info!("Talk request received"),
Event::Discovered(enr) => info!("Enr discovered {}", enr),
Event::EnrAdded { enr, replaced: _ } => info!("Enr added {}", enr),
Event::NodeInserted { node_id, replaced: _ } => info!("Node inserted {}", node_id),
Event::SessionEstablished(enr, _) => info!("Session established {}", enr),
Event::SocketUpdated(addr) => info!("Socket updated {}", addr),
Event::TalkRequest(_) => info!("Talk request received"),
};
}
}
}
}

#[derive(Clone)]
pub enum SocketKind {
Ip4,
Ip6,
Expand Down
6 changes: 3 additions & 3 deletions examples/request_enr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//!
//! This requires the "libp2p" feature.
#[cfg(feature = "libp2p")]
use discv5::Discv5ConfigBuilder;
use discv5::ConfigBuilder;
#[cfg(feature = "libp2p")]
use discv5::ListenConfig;
#[cfg(feature = "libp2p")]
Expand Down Expand Up @@ -43,10 +43,10 @@ async fn main() {
// generate a new enr key
let enr_key = CombinedKey::generate_secp256k1();
// construct a local ENR
let enr = enr::EnrBuilder::new("v4").build(&enr_key).unwrap();
let enr = enr::Enr::empty(&enr_key).unwrap();

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

let multiaddr = std::env::args()
.nth(1)
Expand Down
10 changes: 5 additions & 5 deletions examples/simple_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! $ cargo run --example simple_server -- <ENR-IP> <ENR-PORT> <BASE64ENR>
//! ```

use discv5::{enr, enr::CombinedKey, Discv5, Discv5ConfigBuilder, Discv5Event, ListenConfig};
use discv5::{enr, enr::CombinedKey, ConfigBuilder, Discv5, Event, ListenConfig};
use std::net::Ipv4Addr;

#[tokio::main]
Expand Down Expand Up @@ -46,7 +46,7 @@ async fn main() {

// construct a local ENR
let enr = {
let mut builder = enr::EnrBuilder::new("v4");
let mut builder = enr::Enr::builder();
// if an IP was specified, use it
if let Some(external_address) = address {
builder.ip4(external_address);
Expand All @@ -72,7 +72,7 @@ async fn main() {
}

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

// construct the discv5 server
let mut discv5: Discv5 = Discv5::new(enr, enr_key, config).unwrap();
Expand Down Expand Up @@ -104,10 +104,10 @@ async fn main() {

loop {
match event_stream.recv().await {
Some(Discv5Event::SocketUpdated(addr)) => {
Some(Event::SocketUpdated(addr)) => {
println!("Nodes ENR socket address has been updated to: {addr:?}");
}
Some(Discv5Event::Discovered(enr)) => {
Some(Event::Discovered(enr)) => {
println!("A peer has been discovered: {}", enr.node_id());
}
_ => {}
Expand Down
29 changes: 15 additions & 14 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use crate::{
/// boostrap.
const MIN_SESSIONS_UNREACHABLE_ENR: usize = 10;

use std::{ops::RangeInclusive, time::Duration};
use std::{num::NonZeroUsize, ops::RangeInclusive, time::Duration};

/// Configuration parameters that define the performance of the discovery network.
#[derive(Clone)]
pub struct Discv5Config {
pub struct Config {
/// Whether to enable the incoming packet filter. Default: false.
pub enable_packet_filter: bool,

Expand All @@ -38,7 +38,7 @@ pub struct Discv5Config {
pub session_timeout: Duration,

/// The maximum number of established sessions to maintain. Default: 1000.
pub session_cache_capacity: usize,
pub session_cache_capacity: NonZeroUsize,

/// Updates the local ENR IP and port based on PONG responses from peers. Default: true.
pub enr_update: bool,
Expand Down Expand Up @@ -115,11 +115,11 @@ pub struct Discv5Config {
}

#[derive(Debug)]
pub struct Discv5ConfigBuilder {
config: Discv5Config,
pub struct ConfigBuilder {
config: Config,
}

impl Discv5ConfigBuilder {
impl ConfigBuilder {
pub fn new(listen_config: ListenConfig) -> Self {
// This is only applicable if enable_packet_filter is set.
let filter_rate_limiter = Some(
Expand All @@ -132,15 +132,15 @@ impl Discv5ConfigBuilder {
);

// set default values
let config = Discv5Config {
let config = Config {
enable_packet_filter: false,
request_timeout: Duration::from_secs(1),
vote_duration: Duration::from_secs(30),
query_peer_timeout: Duration::from_secs(2),
query_timeout: Duration::from_secs(60),
request_retries: 1,
session_timeout: Duration::from_secs(86400),
session_cache_capacity: 1000,
session_cache_capacity: NonZeroUsize::new(1000).expect("infallible"),
enr_update: true,
max_nodes_response: 16,
enr_peer_update_min: 10,
Expand All @@ -161,7 +161,7 @@ impl Discv5ConfigBuilder {
listen_config,
};

Discv5ConfigBuilder { config }
ConfigBuilder { config }
}

/// Whether to enable the incoming packet filter.
Expand Down Expand Up @@ -211,7 +211,8 @@ impl Discv5ConfigBuilder {

/// The maximum number of established sessions to maintain.
pub fn session_cache_capacity(&mut self, capacity: usize) -> &mut Self {
self.config.session_cache_capacity = capacity;
self.config.session_cache_capacity =
NonZeroUsize::new(capacity).expect("session_cache_capacity must be greater than 0");
self
}

Expand Down Expand Up @@ -335,7 +336,7 @@ impl Discv5ConfigBuilder {
self
}

pub fn build(&mut self) -> Discv5Config {
pub fn build(&mut self) -> Config {
// If an executor is not provided, assume a current tokio runtime is running.
if self.config.executor.is_none() {
self.config.executor = Some(Box::<crate::executor::TokioExecutor>::default());
Expand All @@ -350,17 +351,17 @@ impl Discv5ConfigBuilder {
}
}

impl std::fmt::Debug for Discv5Config {
impl std::fmt::Debug for Config {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Discv5Config")
f.debug_struct("Config")
.field("filter_enabled", &self.enable_packet_filter)
.field("request_timeout", &self.request_timeout)
.field("vote_duration", &self.vote_duration)
.field("query_timeout", &self.query_timeout)
.field("query_peer_timeout", &self.query_peer_timeout)
.field("request_retries", &self.request_retries)
.field("session_timeout", &self.session_timeout)
.field("session_cache_capacity", &self.session_cache_capacity)
.field("session_cache_capacity", &self.session_cache_capacity.get())
.field("enr_update", &self.enr_update)
.field("query_parallelism", &self.query_parallelism)
.field("report_discovered_peers", &self.report_discovered_peers)
Expand Down
Loading

0 comments on commit 088a171

Please sign in to comment.