Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge master into discv5.2 #234

Merged
merged 20 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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://github.com/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://github.com/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://github.com/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"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appropriate. always wondering what message to write when calling expect on this with a value > 0.

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
Loading