From a79b7e811b6b9de0fc118479c7b6cb66741217b4 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Fri, 28 Feb 2025 15:11:53 +0100 Subject: [PATCH] Add discovery related options to the CLI --- Cargo.lock | 1 + Cargo.toml | 1 + anchor/client/Cargo.toml | 1 + anchor/client/src/cli.rs | 93 +++++++++++++++++++++++++++++++-- anchor/client/src/config.rs | 37 ++++++++----- anchor/network/src/discovery.rs | 6 ++- 6 files changed, 120 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26c2a65e9..dcfcb41ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1823,6 +1823,7 @@ dependencies = [ "http_metrics", "hyper 1.6.0", "message_sender", + "multiaddr", "network", "openssl", "parking_lot", diff --git a/Cargo.toml b/Cargo.toml index 57f2e8919..91d96a36f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,6 +95,7 @@ futures = "0.3.30" hex = "0.4.3" hyper = "1.4" indexmap = "2.7.0" +multiaddr = "0.18.2" num_cpus = "1" openssl = "0.10.68" parking_lot = "0.12" diff --git a/anchor/client/Cargo.toml b/anchor/client/Cargo.toml index be64517f4..e95e33011 100644 --- a/anchor/client/Cargo.toml +++ b/anchor/client/Cargo.toml @@ -23,6 +23,7 @@ http_api = { workspace = true } http_metrics = { workspace = true } hyper = { workspace = true } message_sender = { workspace = true } +multiaddr = { workspace = true } network = { workspace = true } openssl = { workspace = true } parking_lot = { workspace = true } diff --git a/anchor/client/src/cli.rs b/anchor/client/src/cli.rs index b847b75d2..3adc07280 100644 --- a/anchor/client/src/cli.rs +++ b/anchor/client/src/cli.rs @@ -5,7 +5,8 @@ use serde::{Deserialize, Serialize}; use strum::Display; // use clap_utils::{get_color_style, FLAG_HEADER}; use ethereum_hashing::have_sha_extensions; -use std::net::IpAddr; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::num::NonZeroU16; use std::path::PathBuf; use std::sync::LazyLock; use version::VERSION; @@ -329,6 +330,7 @@ pub struct Anchor { requires = "metrics" )] pub metrics_port: Option, + // TODO: Metrics CORS Origin #[clap( long, @@ -339,14 +341,99 @@ pub struct Anchor { help_heading = FLAG_HEADER )] help: Option, + #[clap( long, global = true, value_delimiter = ',', - help = "One or more comma-delimited base64-encoded ENR's to bootstrap the p2p network", + help = "One or more comma-delimited ENRs or Multiaddrs to bootstrap the p2p network", + display_order = 0 + )] + pub boot_nodes: Vec, + + #[clap( + long, + value_name = "ADDRESS", + global = true, + help = "The IPv4 address to broadcast to other peers on how to reach \ + this node. Set this only if you are sure other nodes can connect to your \ + local node on this address. This will update the `ip4` ENR field accordingly.", + display_order = 0 + )] + pub enr_address: Option, + + #[clap( + long, + value_name = "ADDRESS", + global = true, + help = "The IPv6 address to broadcast to other peers on how to reach \ + this node. Set this only if you are sure other nodes can connect to your \ + local node on this address. This will update the `ip6` ENR field accordingly.", + display_order = 0 + )] + pub enr_address6: Option, + + #[clap( + long, + value_name = "PORT", + global = true, + help = "The UDP4 port of the local ENR. Set this only if you are sure other nodes \ + can connect to your local node on this port over IPv4.", + display_order = 0 + )] + pub enr_udp_port: Option, + + #[clap( + long, + value_name = "PORT", + global = true, + help = "The TCP4 port of the local ENR. Set this only if you are sure other nodes \ + can connect to your local node on this port over IPv4. The --port flag is \ + used if this is not set.", + display_order = 0 + )] + pub enr_tcp_port: Option, + + #[clap( + long, + value_name = "PORT", + global = true, + help = "The quic UDP4 port that will be set on the local ENR. Set this only if you are sure other nodes \ + can connect to your local node on this port over IPv4.", + display_order = 0 + )] + pub enr_quic_port: Option, + + #[clap( + long, + value_name = "PORT", + global = true, + help = "The UDP6 port of the local ENR. Set this only if you are sure other nodes \ + can connect to your local node on this port over IPv6.", + display_order = 0 + )] + pub enr_udp6_port: Option, + + #[clap( + long, + value_name = "PORT", + global = true, + help = "The TCP6 port of the local ENR. Set this only if you are sure other nodes \ + can connect to your local node on this port over IPv6. The --port6 flag is \ + used if this is not set.", + display_order = 0 + )] + pub enr_tcp6_port: Option, + + #[clap( + long, + value_name = "PORT", + global = true, + help = "The quic UDP6 port that will be set on the local ENR. Set this only if you are sure other nodes \ + can connect to your local node on this port over IPv6.", display_order = 0 )] - pub boot_nodes_enr: Vec, + pub enr_quic6_port: Option, } pub fn get_color_style() -> Styles { diff --git a/anchor/client/src/config.rs b/anchor/client/src/config.rs index a25b8cfa7..8435b53fe 100644 --- a/anchor/client/src/config.rs +++ b/anchor/client/src/config.rs @@ -2,6 +2,7 @@ // use clap_utils::{flags::DISABLE_MALLOC_TUNING_FLAG, parse_optional, parse_required}; use crate::cli::Anchor; +use multiaddr::{Multiaddr, Protocol}; use network::{ListenAddr, ListenAddress}; use sensitive_url::SensitiveUrl; use ssv_network_config::SsvNetworkConfig; @@ -139,28 +140,28 @@ pub fn from_cli(cli_args: &Anchor) -> Result { /* * Network related */ + config.network.network_dir = config.data_dir.join("network"); config.network.listen_addresses = parse_listening_addresses(cli_args)?; - for addr in cli_args.boot_nodes_enr.clone() { + for addr in cli_args.boot_nodes.clone() { match addr.parse() { Ok(enr) => config.network.boot_nodes_enr.push(enr), - Err(err) => { - error!(enr = addr, err, "Failed to parse boot node ENR, skipping"); + Err(_) => { // parsing as ENR failed, try as Multiaddr - // let multi: Multiaddr = addr - // .parse() - // .map_err(|_| format!("Not valid as ENR nor Multiaddr: {}", addr))?; - // if !multi.iter().any(|proto| matches!(proto, Protocol::Udp(_))) { - // slog::error!(log, "Missing UDP in Multiaddr {}", multi.to_string()); - // } - // if !multi.iter().any(|proto| matches!(proto, Protocol::P2p(_))) { - // slog::error!(log, "Missing P2P in Multiaddr {}", multi.to_string()); - // } - // multiaddrs.push(multi); + let multi: Multiaddr = addr + .parse() + .map_err(|_| format!("Not valid as ENR nor Multiaddr: {}", addr))?; + if !multi.iter().any(|proto| matches!(proto, Protocol::Udp(_))) { + error!(addr = multi.to_string(), "Missing UDP in Multiaddr"); + } + if !multi.iter().any(|proto| matches!(proto, Protocol::P2p(_))) { + error!(addr = multi.to_string(), "Missing P2P in Multiaddr"); + } + config.network.boot_nodes_multiaddr.push(multi); } } } - if cli_args.boot_nodes_enr.is_empty() { + if cli_args.boot_nodes.is_empty() { config.network.boot_nodes_enr = config .ssv_network .ssv_boot_nodes @@ -168,6 +169,14 @@ pub fn from_cli(cli_args: &Anchor) -> Result { .unwrap_or_default(); } + config.network.enr_address = (cli_args.enr_address, cli_args.enr_address6); + config.network.enr_tcp4_port = cli_args.enr_tcp_port; + config.network.enr_udp4_port = cli_args.enr_udp_port; + config.network.enr_quic4_port = cli_args.enr_quic_port; + config.network.enr_tcp6_port = cli_args.enr_tcp6_port; + config.network.enr_udp6_port = cli_args.enr_udp6_port; + config.network.enr_quic6_port = cli_args.enr_quic6_port; + config.beacon_nodes_tls_certs = cli_args.beacon_nodes_tls_certs.clone(); config.execution_nodes_tls_certs = cli_args.execution_nodes_tls_certs.clone(); diff --git a/anchor/network/src/discovery.rs b/anchor/network/src/discovery.rs index 42d5d9958..bc12fa414 100644 --- a/anchor/network/src/discovery.rs +++ b/anchor/network/src/discovery.rs @@ -24,7 +24,7 @@ use lighthouse_network::discovery::enr_ext::{QUIC6_ENR_KEY, QUIC_ENR_KEY}; use lighthouse_network::discovery::DiscoveredPeers; use lighthouse_network::CombinedKeyExt; use tokio::sync::mpsc; -use tracing::{debug, error, trace, warn}; +use tracing::{debug, error, info, trace, warn}; use crate::Config; use lighthouse_network::EnrExt; @@ -156,6 +156,8 @@ impl Discovery { let enr = build_enr(&enr_key, network_config).map_err(EnrBuild)?; + info!(%enr, "Created local ENR"); + let mut discv5 = Discv5::::new(enr, enr_key, discv5_config) .map_err(|e| Discv5Init(e.to_string()))?; @@ -196,7 +198,7 @@ impl Discovery { }; if !network_config.boot_nodes_multiaddr.is_empty() { - // TODO info!(log, "Contacting Multiaddr boot-nodes for their ENR"); + info!("Contacting Multiaddr boot-nodes for their ENR"); } // get futures for requesting the Enrs associated to these multiaddr and wait for their