diff --git a/crates/node/core/src/args/mod.rs b/crates/node/core/src/args/mod.rs index 3703d4144f0..6d6fbbd0078 100644 --- a/crates/node/core/src/args/mod.rs +++ b/crates/node/core/src/args/mod.rs @@ -2,7 +2,7 @@ /// NetworkArg struct for configuring the network mod network; -pub use network::{DefaultNetworkArgs, DiscoveryArgs, NetworkArgs}; +pub use network::{DefaultDiscoveryArgs, DefaultNetworkArgs, DiscoveryArgs, NetworkArgs}; /// RpcServerArg struct for configuring the RPC mod rpc_server; diff --git a/crates/node/core/src/args/network.rs b/crates/node/core/src/args/network.rs index 614bcf30259..b682633805e 100644 --- a/crates/node/core/src/args/network.rs +++ b/crates/node/core/src/args/network.rs @@ -11,7 +11,10 @@ use std::{ }; use crate::version::version_metadata; -use clap::Args; +use clap::{ + builder::{OsStr, Resettable}, + Args, +}; use reth_chainspec::EthChainSpec; use reth_cli_util::{get_secret_key, load_secret_key::SecretKeyError}; use reth_config::Config; @@ -569,15 +572,8 @@ impl NetworkArgs { let rlpx_socket = (addr, self.port).into(); self.discovery.apply_to_builder(builder, rlpx_socket, chain_bootnodes) }) - .listener_addr(SocketAddr::new( - addr, // set discovery port based on instance number - self.port, - )) - .discovery_addr(SocketAddr::new( - self.discovery.addr, - // set discovery port based on instance number - self.discovery.port, - )) + .listener_addr(SocketAddr::new(addr, self.port)) + .discovery_addr(SocketAddr::new(self.discovery.addr, self.discovery.port)) .disable_tx_gossip(self.disable_tx_gossip) .required_block_hashes(self.required_block_hashes.clone()) .eth_max_message_size_opt(self.eth_max_message_size.map(NonZeroUsize::get)) @@ -727,19 +723,172 @@ impl Default for NetworkArgs { } } +/// Global static discovery defaults +static DISCOVERY_DEFAULTS: OnceLock = OnceLock::new(); + +/// Default values for discovery CLI arguments that can be customized. +#[derive(Debug, Clone, Copy)] +pub struct DefaultDiscoveryArgs { + /// Default for `--disable-discovery`. + pub disable_discovery: bool, + /// Default for `--disable-dns-discovery`. + pub disable_dns_discovery: bool, + /// Default for `--disable-discv4-discovery`. + pub disable_discv4_discovery: bool, + /// Default for `--disable-discv5-discovery`. + pub disable_discv5_discovery: bool, + /// Default for `--disable-nat`. + pub disable_nat: bool, + /// Default UDP address for devp2p discovery v4. + pub addr: IpAddr, + /// Default UDP port for devp2p discovery v4. + pub port: u16, + /// Default UDP IPv4 address for devp2p discovery v5. + pub discv5_addr: Option, + /// Default UDP IPv6 address for devp2p discovery v5. + pub discv5_addr_ipv6: Option, + /// Default UDP IPv4 port for devp2p discovery v5. + pub discv5_port: Option, + /// Default UDP IPv6 port for devp2p discovery v5. + pub discv5_port_ipv6: Option, + /// Default discv5 periodic lookup interval (seconds). + pub discv5_lookup_interval: u64, + /// Default discv5 bootstrap lookup interval (seconds). + pub discv5_bootstrap_lookup_interval: u64, + /// Default discv5 bootstrap lookup countdown. + pub discv5_bootstrap_lookup_countdown: u64, +} + +impl DefaultDiscoveryArgs { + /// Initialize the global discovery defaults with this configuration. + pub fn try_init(self) -> Result<(), Self> { + DISCOVERY_DEFAULTS.set(self) + } + + /// Get a reference to the global discovery defaults. + pub fn get_global() -> &'static Self { + DISCOVERY_DEFAULTS.get_or_init(Self::default) + } + + /// Set the default for `--disable-discovery`. + pub const fn with_disable_discovery(mut self, disable: bool) -> Self { + self.disable_discovery = disable; + self + } + + /// Set the default for `--disable-dns-discovery`. + pub const fn with_disable_dns_discovery(mut self, disable: bool) -> Self { + self.disable_dns_discovery = disable; + self + } + + /// Set the default for `--disable-discv4-discovery`. + pub const fn with_disable_discv4_discovery(mut self, disable: bool) -> Self { + self.disable_discv4_discovery = disable; + self + } + + /// Set the default for `--disable-discv5-discovery`. + pub const fn with_disable_discv5_discovery(mut self, disable: bool) -> Self { + self.disable_discv5_discovery = disable; + self + } + + /// Set the default for `--disable-nat`. + pub const fn with_disable_nat(mut self, disable: bool) -> Self { + self.disable_nat = disable; + self + } + + /// Set the default discovery v4 address. + pub const fn with_addr(mut self, addr: IpAddr) -> Self { + self.addr = addr; + self + } + + /// Set the default discovery v4 port. + pub const fn with_port(mut self, port: u16) -> Self { + self.port = port; + self + } + + /// Set the default discovery v5 IPv4 address. + pub fn with_discv5_addr(mut self, addr: impl Into>) -> Self { + self.discv5_addr = addr.into(); + self + } + + /// Set the default discovery v5 IPv6 address. + pub fn with_discv5_addr_ipv6(mut self, addr: impl Into>) -> Self { + self.discv5_addr_ipv6 = addr.into(); + self + } + + /// Set the default discovery V5 port. + pub fn with_discv5_port(mut self, port: impl Into>) -> Self { + self.discv5_port = port.into(); + self + } + + /// Set the default discovery v5 IPv6 port. + pub fn with_discv5_port_ipv6(mut self, port: impl Into>) -> Self { + self.discv5_port_ipv6 = port.into(); + self + } + + /// Set the default discv5 periodic lookup interval (seconds). + pub const fn with_discv5_lookup_interval(mut self, interval: u64) -> Self { + self.discv5_lookup_interval = interval; + self + } + + /// Set the default discv5 bootstrap lookup interval (seconds). + pub const fn with_discv5_bootstrap_lookup_interval(mut self, interval: u64) -> Self { + self.discv5_bootstrap_lookup_interval = interval; + self + } + + /// Set the default discv5 bootstrap lookup countdown. + pub const fn with_discv5_bootstrap_lookup_countdown(mut self, countdown: u64) -> Self { + self.discv5_bootstrap_lookup_countdown = countdown; + self + } +} + +impl Default for DefaultDiscoveryArgs { + fn default() -> Self { + Self { + disable_discovery: false, + disable_dns_discovery: false, + disable_discv4_discovery: false, + disable_discv5_discovery: false, + disable_nat: false, + addr: DEFAULT_DISCOVERY_ADDR, + port: DEFAULT_DISCOVERY_PORT, + discv5_addr: None, + discv5_addr_ipv6: None, + discv5_port: Some(DEFAULT_DISCOVERY_V5_PORT), + discv5_port_ipv6: Some(DEFAULT_DISCOVERY_V5_PORT), + discv5_lookup_interval: DEFAULT_SECONDS_LOOKUP_INTERVAL, + discv5_bootstrap_lookup_interval: DEFAULT_SECONDS_BOOTSTRAP_LOOKUP_INTERVAL, + discv5_bootstrap_lookup_countdown: DEFAULT_COUNT_BOOTSTRAP_LOOKUPS, + } + } +} + /// Arguments to setup discovery #[derive(Debug, Clone, Args, PartialEq, Eq)] pub struct DiscoveryArgs { /// Disable the discovery service. - #[arg(short, long, default_value_if("dev", "true", "true"))] + #[arg(short, long, default_value_if("dev", "true", "true"), default_value_t = DefaultDiscoveryArgs::get_global().disable_discovery)] pub disable_discovery: bool, /// Disable the DNS discovery. - #[arg(long, conflicts_with = "disable_discovery")] + #[arg(long, conflicts_with = "disable_discovery", default_value_t = DefaultDiscoveryArgs::get_global().disable_dns_discovery)] pub disable_dns_discovery: bool, /// Disable Discv4 discovery. - #[arg(long, conflicts_with = "disable_discovery")] + #[arg(long, conflicts_with = "disable_discovery", default_value_t = DefaultDiscoveryArgs::get_global().disable_discv4_discovery)] pub disable_discv4_discovery: bool, /// Enable Discv5 discovery. @@ -750,57 +899,57 @@ pub struct DiscoveryArgs { pub enable_discv5_discovery: bool, /// Disable Discv5 discovery. - #[arg(long, conflicts_with = "disable_discovery")] + #[arg(long, conflicts_with = "disable_discovery", default_value_t = DefaultDiscoveryArgs::get_global().disable_discv5_discovery)] pub disable_discv5_discovery: bool, /// Disable Nat discovery. - #[arg(long, conflicts_with = "disable_discovery")] + #[arg(long, conflicts_with = "disable_discovery", default_value_t = DefaultDiscoveryArgs::get_global().disable_nat)] pub disable_nat: bool, /// The UDP address to use for devp2p peer discovery version 4. - #[arg(id = "discovery.addr", long = "discovery.addr", value_name = "DISCOVERY_ADDR", default_value_t = DEFAULT_DISCOVERY_ADDR)] + #[arg(id = "discovery.addr", long = "discovery.addr", value_name = "DISCOVERY_ADDR", default_value_t = DefaultDiscoveryArgs::get_global().addr)] pub addr: IpAddr, /// The UDP port to use for devp2p peer discovery version 4. - #[arg(id = "discovery.port", long = "discovery.port", value_name = "DISCOVERY_PORT", default_value_t = DEFAULT_DISCOVERY_PORT)] + #[arg(id = "discovery.port", long = "discovery.port", value_name = "DISCOVERY_PORT", default_value_t = DefaultDiscoveryArgs::get_global().port)] pub port: u16, /// The UDP IPv4 address to use for devp2p peer discovery version 5. Overwritten by `RLPx` /// address, if it's also IPv4. - #[arg(id = "discovery.v5.addr", long = "discovery.v5.addr", value_name = "DISCOVERY_V5_ADDR", default_value = None)] + #[arg(id = "discovery.v5.addr", long = "discovery.v5.addr", value_name = "DISCOVERY_V5_ADDR", default_value = Resettable::from(DefaultDiscoveryArgs::get_global().discv5_addr.map(|a| OsStr::from(a.to_string()))))] pub discv5_addr: Option, /// The UDP IPv6 address to use for devp2p peer discovery version 5. Overwritten by `RLPx` /// address, if it's also IPv6. - #[arg(id = "discovery.v5.addr.ipv6", long = "discovery.v5.addr.ipv6", value_name = "DISCOVERY_V5_ADDR_IPV6", default_value = None)] + #[arg(id = "discovery.v5.addr.ipv6", long = "discovery.v5.addr.ipv6", value_name = "DISCOVERY_V5_ADDR_IPV6", default_value = Resettable::from(DefaultDiscoveryArgs::get_global().discv5_addr_ipv6.map(|a| OsStr::from(a.to_string()))))] pub discv5_addr_ipv6: Option, /// The UDP IPv4 port to use for devp2p peer discovery version 5. Not used unless `--addr` is /// IPv4, or `--discovery.v5.addr` is set. - #[arg(id = "discovery.v5.port", long = "discovery.v5.port", value_name = "DISCOVERY_V5_PORT", - default_value_t = DEFAULT_DISCOVERY_V5_PORT)] - pub discv5_port: u16, + #[arg(id = "discovery.v5.port", long = "discovery.v5.port", value_name = "DISCOVERY_V5_PORT", default_value = Resettable::from(DefaultDiscoveryArgs::get_global().discv5_port.map(|p| OsStr::from(p.to_string()))))] + pub discv5_port: Option, /// The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is /// IPv6, or `--discovery.addr.ipv6` is set. - #[arg(id = "discovery.v5.port.ipv6", long = "discovery.v5.port.ipv6", value_name = "DISCOVERY_V5_PORT_IPV6", - default_value_t = DEFAULT_DISCOVERY_V5_PORT)] - pub discv5_port_ipv6: u16, + /// + /// If not provided, discovery V5 defaults to same port as discovery V4 (--discovery.port). + #[arg(id = "discovery.v5.port.ipv6", long = "discovery.v5.port.ipv6", value_name = "DISCOVERY_V5_PORT_IPV6", default_value = Resettable::from(DefaultDiscoveryArgs::get_global().discv5_port_ipv6.map(|p| OsStr::from(p.to_string()))))] + pub discv5_port_ipv6: Option, /// The interval in seconds at which to carry out periodic lookup queries, for the whole /// run of the program. - #[arg(id = "discovery.v5.lookup-interval", long = "discovery.v5.lookup-interval", value_name = "DISCOVERY_V5_LOOKUP_INTERVAL", default_value_t = DEFAULT_SECONDS_LOOKUP_INTERVAL)] + #[arg(id = "discovery.v5.lookup-interval", long = "discovery.v5.lookup-interval", value_name = "DISCOVERY_V5_LOOKUP_INTERVAL", default_value_t = DefaultDiscoveryArgs::get_global().discv5_lookup_interval)] pub discv5_lookup_interval: u64, /// The interval in seconds at which to carry out boost lookup queries, for a fixed number of /// times, at bootstrap. #[arg(id = "discovery.v5.bootstrap.lookup-interval", long = "discovery.v5.bootstrap.lookup-interval", value_name = "DISCOVERY_V5_BOOTSTRAP_LOOKUP_INTERVAL", - default_value_t = DEFAULT_SECONDS_BOOTSTRAP_LOOKUP_INTERVAL)] + default_value_t = DefaultDiscoveryArgs::get_global().discv5_bootstrap_lookup_interval)] pub discv5_bootstrap_lookup_interval: u64, /// The number of times to carry out boost lookup queries at bootstrap. #[arg(id = "discovery.v5.bootstrap.lookup-countdown", long = "discovery.v5.bootstrap.lookup-countdown", value_name = "DISCOVERY_V5_BOOTSTRAP_LOOKUP_COUNTDOWN", - default_value_t = DEFAULT_COUNT_BOOTSTRAP_LOOKUPS)] + default_value_t = DefaultDiscoveryArgs::get_global().discv5_bootstrap_lookup_countdown)] pub discv5_bootstrap_lookup_countdown: u64, } @@ -850,6 +999,7 @@ impl DiscoveryArgs { discv5_lookup_interval, discv5_bootstrap_lookup_interval, discv5_bootstrap_lookup_countdown, + port, .. } = self; @@ -867,8 +1017,9 @@ impl DiscoveryArgs { let mut discv5_config_builder = reth_discv5::discv5::ConfigBuilder::new(ListenConfig::from_two_sockets( - discv5_addr_ipv4.map(|addr| SocketAddrV4::new(addr, *discv5_port)), - discv5_addr_ipv6.map(|addr| SocketAddrV6::new(addr, *discv5_port_ipv6, 0, 0)), + discv5_addr_ipv4.map(|addr| SocketAddrV4::new(addr, discv5_port.unwrap_or(*port))), + discv5_addr_ipv6 + .map(|addr| SocketAddrV6::new(addr, discv5_port_ipv6.unwrap_or(*port), 0, 0)), )); if has_discv5_addr_args || self.disable_nat { @@ -898,14 +1049,14 @@ impl DiscoveryArgs { /// discovery binds to the sockets. pub const fn with_unused_discovery_port(mut self) -> Self { self.port = 0; - self.discv5_port = 0; - self.discv5_port_ipv6 = 0; + self.discv5_port = Some(0); + self.discv5_port_ipv6 = Some(0); self } /// Set the discovery V5 port - pub const fn with_discv5_port(mut self, port: u16) -> Self { - self.discv5_port = port; + pub fn with_discv5_port(mut self, port: impl Into>) -> Self { + self.discv5_port = port.into(); self } @@ -917,29 +1068,45 @@ impl DiscoveryArgs { pub fn adjust_instance_ports(&mut self, instance: u16) { debug_assert_ne!(instance, 0, "instance must be non-zero"); self.port += instance - 1; - self.discv5_port += instance - 1; - self.discv5_port_ipv6 += instance - 1; + self.discv5_port = self.discv5_port.map(|port| port + instance - 1); + self.discv5_port_ipv6 = self.discv5_port_ipv6.map(|port| port + instance - 1); } } impl Default for DiscoveryArgs { fn default() -> Self { + let DefaultDiscoveryArgs { + disable_discovery, + disable_dns_discovery, + disable_discv4_discovery, + disable_discv5_discovery, + disable_nat, + addr, + port, + discv5_addr, + discv5_addr_ipv6, + discv5_port, + discv5_port_ipv6, + discv5_lookup_interval, + discv5_bootstrap_lookup_interval, + discv5_bootstrap_lookup_countdown, + } = *DefaultDiscoveryArgs::get_global(); Self { - disable_discovery: false, - disable_dns_discovery: false, - disable_discv4_discovery: false, + disable_discovery, + disable_dns_discovery, + disable_discv4_discovery, enable_discv5_discovery: false, - disable_discv5_discovery: false, - disable_nat: false, - addr: DEFAULT_DISCOVERY_ADDR, - port: DEFAULT_DISCOVERY_PORT, - discv5_addr: None, - discv5_addr_ipv6: None, - discv5_port: DEFAULT_DISCOVERY_V5_PORT, - discv5_port_ipv6: DEFAULT_DISCOVERY_V5_PORT, - discv5_lookup_interval: DEFAULT_SECONDS_LOOKUP_INTERVAL, - discv5_bootstrap_lookup_interval: DEFAULT_SECONDS_BOOTSTRAP_LOOKUP_INTERVAL, - discv5_bootstrap_lookup_countdown: DEFAULT_COUNT_BOOTSTRAP_LOOKUPS, + disable_discv5_discovery, + disable_nat, + addr, + port, + discv5_addr, + discv5_addr_ipv6, + discv5_port, + discv5_port_ipv6, + discv5_lookup_interval, + discv5_bootstrap_lookup_interval, + discv5_bootstrap_lookup_countdown, } } } diff --git a/docs/vocs/docs/pages/cli/reth/node.mdx b/docs/vocs/docs/pages/cli/reth/node.mdx index 4e88bde832d..3d5a60beb57 100644 --- a/docs/vocs/docs/pages/cli/reth/node.mdx +++ b/docs/vocs/docs/pages/cli/reth/node.mdx @@ -115,7 +115,9 @@ Networking: [default: 9200] --discovery.v5.port.ipv6 - The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set + The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set. + + If not provided, discovery V5 defaults to same port as discovery V4 (--discovery.port). [default: 9200] diff --git a/docs/vocs/docs/pages/cli/reth/p2p/body.mdx b/docs/vocs/docs/pages/cli/reth/p2p/body.mdx index a12a5741da6..f55534e616a 100644 --- a/docs/vocs/docs/pages/cli/reth/p2p/body.mdx +++ b/docs/vocs/docs/pages/cli/reth/p2p/body.mdx @@ -55,7 +55,9 @@ Networking: [default: 9200] --discovery.v5.port.ipv6 - The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set + The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set. + + If not provided, discovery V5 defaults to same port as discovery V4 (--discovery.port). [default: 9200] diff --git a/docs/vocs/docs/pages/cli/reth/p2p/header.mdx b/docs/vocs/docs/pages/cli/reth/p2p/header.mdx index da60a42d03d..33f17e8e80a 100644 --- a/docs/vocs/docs/pages/cli/reth/p2p/header.mdx +++ b/docs/vocs/docs/pages/cli/reth/p2p/header.mdx @@ -55,7 +55,9 @@ Networking: [default: 9200] --discovery.v5.port.ipv6 - The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set + The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set. + + If not provided, discovery V5 defaults to same port as discovery V4 (--discovery.port). [default: 9200] diff --git a/docs/vocs/docs/pages/cli/reth/stage/run.mdx b/docs/vocs/docs/pages/cli/reth/stage/run.mdx index 667c4cb2c45..8d4e7411e68 100644 --- a/docs/vocs/docs/pages/cli/reth/stage/run.mdx +++ b/docs/vocs/docs/pages/cli/reth/stage/run.mdx @@ -208,7 +208,9 @@ Networking: [default: 9200] --discovery.v5.port.ipv6 - The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set + The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set. + + If not provided, discovery V5 defaults to same port as discovery V4 (--discovery.port). [default: 9200]