mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: resolve domains in enode strings (#8188)
Co-authored-by: Serge Radinovich <47865535+sergerad@users.noreply.github.com>
This commit is contained in:
72
Cargo.lock
generated
72
Cargo.lock
generated
@ -140,7 +140,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "alloy-consensus"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/alloy-rs/alloy#4ecb7d86882ece8a9a7a5a892b71a3c198030731"
|
||||
source = "git+https://github.com/alloy-rs/alloy#eaf53556d1ee4ac0e611d6c06e3732a24f1d11ab"
|
||||
dependencies = [
|
||||
"alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy)",
|
||||
"alloy-primitives",
|
||||
@ -165,7 +165,7 @@ dependencies = [
|
||||
"itoa",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"winnow 0.6.9",
|
||||
"winnow 0.6.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -189,7 +189,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "alloy-eips"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/alloy-rs/alloy#4ecb7d86882ece8a9a7a5a892b71a3c198030731"
|
||||
source = "git+https://github.com/alloy-rs/alloy#eaf53556d1ee4ac0e611d6c06e3732a24f1d11ab"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
@ -214,7 +214,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "alloy-genesis"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/alloy-rs/alloy#4ecb7d86882ece8a9a7a5a892b71a3c198030731"
|
||||
source = "git+https://github.com/alloy-rs/alloy#eaf53556d1ee4ac0e611d6c06e3732a24f1d11ab"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-serde 0.1.0 (git+https://github.com/alloy-rs/alloy)",
|
||||
@ -405,7 +405,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "alloy-rpc-types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/alloy-rs/alloy#4ecb7d86882ece8a9a7a5a892b71a3c198030731"
|
||||
source = "git+https://github.com/alloy-rs/alloy#eaf53556d1ee4ac0e611d6c06e3732a24f1d11ab"
|
||||
dependencies = [
|
||||
"alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy)",
|
||||
"alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy)",
|
||||
@ -486,7 +486,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "alloy-serde"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/alloy-rs/alloy#4ecb7d86882ece8a9a7a5a892b71a3c198030731"
|
||||
source = "git+https://github.com/alloy-rs/alloy#eaf53556d1ee4ac0e611d6c06e3732a24f1d11ab"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"serde",
|
||||
@ -579,7 +579,7 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368cae4dc052cad1d8f72eb2ae0c38027116933eeb49213c200a9e9875f208d7"
|
||||
dependencies = [
|
||||
"winnow 0.6.9",
|
||||
"winnow 0.6.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2989,7 +2989,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "foundry-blob-explorers"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/foundry-rs/block-explorers#1b024125d8327595f67f18a60ac29c49056c3a6d"
|
||||
source = "git+https://github.com/foundry-rs/block-explorers#1674a68b073a3637c16f2d3f9700cf6332ffe4a6"
|
||||
dependencies = [
|
||||
"alloy-chains",
|
||||
"alloy-eips 0.1.0 (git+https://github.com/alloy-rs/alloy)",
|
||||
@ -3554,9 +3554,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.28"
|
||||
version = "0.14.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
|
||||
checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@ -3603,7 +3603,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"log",
|
||||
"rustls 0.21.12",
|
||||
"rustls-native-certs 0.6.3",
|
||||
@ -4154,7 +4154,7 @@ dependencies = [
|
||||
"beef",
|
||||
"futures-timer",
|
||||
"futures-util",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"jsonrpsee-types",
|
||||
"parking_lot 0.12.3",
|
||||
"pin-project",
|
||||
@ -4176,7 +4176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ccf93fc4a0bfe05d851d37d7c32b7f370fe94336b52a2f0efc5f1981895c2e5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"hyper-rustls 0.24.2",
|
||||
"jsonrpsee-core",
|
||||
"jsonrpsee-types",
|
||||
@ -4210,7 +4210,7 @@ checksum = "12d8b6a9674422a8572e0b0abb12feeb3f2aeda86528c80d0350c2bd0923ab41"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"jsonrpsee-core",
|
||||
"jsonrpsee-types",
|
||||
"pin-project",
|
||||
@ -5716,9 +5716,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.84"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
|
||||
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -6070,7 +6070,7 @@ dependencies = [
|
||||
"h2",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
@ -6191,6 +6191,7 @@ dependencies = [
|
||||
"reth-evm",
|
||||
"reth-exex",
|
||||
"reth-fs-util",
|
||||
"reth-net-common",
|
||||
"reth-network",
|
||||
"reth-network-api",
|
||||
"reth-network-p2p",
|
||||
@ -7117,6 +7118,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
@ -7160,6 +7162,7 @@ name = "reth-node-builder"
|
||||
version = "0.2.0-beta.8"
|
||||
dependencies = [
|
||||
"aquamarine",
|
||||
"backon",
|
||||
"confy",
|
||||
"eyre",
|
||||
"fdlimit",
|
||||
@ -7212,7 +7215,7 @@ dependencies = [
|
||||
"eyre",
|
||||
"futures",
|
||||
"humantime",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"metrics",
|
||||
"metrics-exporter-prometheus",
|
||||
"metrics-process",
|
||||
@ -7235,6 +7238,7 @@ dependencies = [
|
||||
"reth-net-nat",
|
||||
"reth-network",
|
||||
"reth-network-p2p",
|
||||
"reth-network-types",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-rpc",
|
||||
@ -7316,7 +7320,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"clap",
|
||||
"eyre",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"jsonrpsee",
|
||||
"parking_lot 0.12.3",
|
||||
"reqwest 0.12.4",
|
||||
@ -7557,7 +7561,7 @@ dependencies = [
|
||||
"futures",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"jsonrpsee",
|
||||
"jsonwebtoken 8.3.0",
|
||||
"metrics",
|
||||
@ -7630,7 +7634,7 @@ dependencies = [
|
||||
name = "reth-rpc-builder"
|
||||
version = "0.2.0-beta.8"
|
||||
dependencies = [
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"jsonrpsee",
|
||||
"metrics",
|
||||
"pin-project",
|
||||
@ -7705,7 +7709,7 @@ dependencies = [
|
||||
"assert_matches",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.28",
|
||||
"hyper 0.14.29",
|
||||
"jsonrpsee",
|
||||
"pin-project",
|
||||
"tempfile",
|
||||
@ -8210,9 +8214,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruint"
|
||||
version = "1.12.1"
|
||||
version = "1.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62"
|
||||
checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286"
|
||||
dependencies = [
|
||||
"alloy-rlp",
|
||||
"arbitrary",
|
||||
@ -8235,9 +8239,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruint-macro"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343"
|
||||
checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18"
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
@ -9530,14 +9534,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.13"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba"
|
||||
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.13",
|
||||
"toml_edit 0.22.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -9562,15 +9566,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.13"
|
||||
version = "0.22.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c"
|
||||
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
|
||||
dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.9",
|
||||
"winnow 0.6.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -10451,9 +10455,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.9"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6"
|
||||
checksum = "f217b6745021054125ef5741032a021a9c65f82bee2a8017cca928f1e3179991"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@ -378,6 +378,7 @@ dyn-clone = "1.0.17"
|
||||
sha2 = { version = "0.10", default-features = false }
|
||||
paste = "1.0"
|
||||
url = "2.3"
|
||||
backon = "0.4"
|
||||
|
||||
# metrics
|
||||
metrics = "0.22.0"
|
||||
|
||||
@ -37,6 +37,7 @@ reth-rpc-types-compat.workspace = true
|
||||
reth-rpc-api = { workspace = true, features = ["client"] }
|
||||
reth-network = { workspace = true, features = ["serde"] }
|
||||
reth-network-p2p.workspace = true
|
||||
reth-net-common.workspace = true
|
||||
reth-network-api.workspace = true
|
||||
reth-downloaders.workspace = true
|
||||
reth-tracing.workspace = true
|
||||
@ -104,7 +105,7 @@ aquamarine.workspace = true
|
||||
eyre.workspace = true
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
tempfile.workspace = true
|
||||
backon = "0.4"
|
||||
backon.workspace = true
|
||||
similar-asserts.workspace = true
|
||||
itertools.workspace = true
|
||||
rayon.workspace = true
|
||||
|
||||
@ -88,8 +88,8 @@ impl Command {
|
||||
|
||||
let mut config: Config = confy::load_path(&config_path).unwrap_or_default();
|
||||
|
||||
for &peer in &self.network.trusted_peers {
|
||||
config.peers.trusted_nodes.insert(peer);
|
||||
for peer in &self.network.trusted_peers {
|
||||
config.peers.trusted_nodes.insert(peer.resolve().await?);
|
||||
}
|
||||
|
||||
if config.peers.trusted_nodes.is_empty() && self.network.trusted_only {
|
||||
|
||||
@ -118,9 +118,10 @@ impl Command {
|
||||
let mut config = config;
|
||||
config.peers.trusted_nodes_only = self.network.trusted_only;
|
||||
if !self.network.trusted_peers.is_empty() {
|
||||
self.network.trusted_peers.iter().for_each(|peer| {
|
||||
config.peers.trusted_nodes.insert(*peer);
|
||||
});
|
||||
for peer in &self.network.trusted_peers {
|
||||
let peer = peer.resolve().await?;
|
||||
config.peers.trusted_nodes.insert(peer);
|
||||
}
|
||||
}
|
||||
|
||||
let network_secret_path = self
|
||||
|
||||
5
book/cli/reth/node.md
vendored
5
book/cli/reth/node.md
vendored
@ -126,6 +126,11 @@ Networking:
|
||||
|
||||
Will fall back to a network-specific default if not specified.
|
||||
|
||||
--dns-retries <DNS_RETRIES>
|
||||
Amount of DNS resolution requests retries to perform when peering
|
||||
|
||||
[default: 0]
|
||||
|
||||
--peers-file <FILE>
|
||||
The path to the known peers file. Connected peers are dumped to this file on nodes
|
||||
shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
|
||||
|
||||
5
book/cli/reth/p2p.md
vendored
5
book/cli/reth/p2p.md
vendored
@ -110,6 +110,11 @@ Networking:
|
||||
|
||||
Will fall back to a network-specific default if not specified.
|
||||
|
||||
--dns-retries <DNS_RETRIES>
|
||||
Amount of DNS resolution requests retries to perform when peering
|
||||
|
||||
[default: 0]
|
||||
|
||||
--peers-file <FILE>
|
||||
The path to the known peers file. Connected peers are dumped to this file on nodes
|
||||
shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
|
||||
|
||||
5
book/cli/reth/stage/run.md
vendored
5
book/cli/reth/stage/run.md
vendored
@ -177,6 +177,11 @@ Networking:
|
||||
|
||||
Will fall back to a network-specific default if not specified.
|
||||
|
||||
--dns-retries <DNS_RETRIES>
|
||||
Amount of DNS resolution requests retries to perform when peering
|
||||
|
||||
[default: 0]
|
||||
|
||||
--peers-file <FILE>
|
||||
The path to the known peers file. Connected peers are dumped to this file on nodes
|
||||
shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
|
||||
|
||||
5
book/cli/reth/stage/unwind.md
vendored
5
book/cli/reth/stage/unwind.md
vendored
@ -139,6 +139,11 @@ Networking:
|
||||
|
||||
Will fall back to a network-specific default if not specified.
|
||||
|
||||
--dns-retries <DNS_RETRIES>
|
||||
Amount of DNS resolution requests retries to perform when peering
|
||||
|
||||
[default: 0]
|
||||
|
||||
--peers-file <FILE>
|
||||
The path to the known peers file. Connected peers are dumped to this file on nodes
|
||||
shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
pub mod ban_list;
|
||||
pub mod bandwidth_meter;
|
||||
|
||||
/// Traits related to tokio streams
|
||||
pub mod stream;
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ use reth_dns_discovery::DnsDiscoveryConfig;
|
||||
use reth_eth_wire::{HelloMessage, HelloMessageWithProtocols, Status};
|
||||
use reth_network_types::{pk2id, PeerId};
|
||||
use reth_primitives::{
|
||||
mainnet_nodes, sepolia_nodes, ChainSpec, ForkFilter, Head, NodeRecord, MAINNET,
|
||||
mainnet_nodes, sepolia_nodes, ChainSpec, ForkFilter, Head, TrustedPeer, MAINNET,
|
||||
};
|
||||
use reth_provider::{BlockReader, HeaderProvider};
|
||||
use reth_tasks::{TaskSpawner, TokioTaskExecutor};
|
||||
@ -41,7 +41,7 @@ pub struct NetworkConfig<C> {
|
||||
/// The node's secret key, from which the node's identity is derived.
|
||||
pub secret_key: SecretKey,
|
||||
/// All boot nodes to start network discovery with.
|
||||
pub boot_nodes: HashSet<NodeRecord>,
|
||||
pub boot_nodes: HashSet<TrustedPeer>,
|
||||
/// How to set up discovery over DNS.
|
||||
pub dns_discovery_config: Option<DnsDiscoveryConfig>,
|
||||
/// Address to use for discovery v4.
|
||||
@ -147,7 +147,7 @@ pub struct NetworkConfigBuilder {
|
||||
#[serde(skip)]
|
||||
discovery_v5_builder: Option<reth_discv5::ConfigBuilder>,
|
||||
/// All boot nodes to start network discovery with.
|
||||
boot_nodes: HashSet<NodeRecord>,
|
||||
boot_nodes: HashSet<TrustedPeer>,
|
||||
/// Address to use for discovery
|
||||
discovery_addr: Option<SocketAddr>,
|
||||
/// Listener for incoming connections
|
||||
@ -365,8 +365,8 @@ impl NetworkConfigBuilder {
|
||||
}
|
||||
|
||||
/// Sets the boot nodes.
|
||||
pub fn boot_nodes(mut self, nodes: impl IntoIterator<Item = NodeRecord>) -> Self {
|
||||
self.boot_nodes = nodes.into_iter().collect();
|
||||
pub fn boot_nodes<T: Into<TrustedPeer>>(mut self, nodes: impl IntoIterator<Item = T>) -> Self {
|
||||
self.boot_nodes = nodes.into_iter().map(Into::into).collect();
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
@ -206,9 +206,16 @@ where
|
||||
})?;
|
||||
let listener_address = Arc::new(Mutex::new(incoming.local_address()));
|
||||
|
||||
// resolve boot nodes
|
||||
let mut resolved_boot_nodes = vec![];
|
||||
for record in &boot_nodes {
|
||||
let resolved = record.resolve().await?;
|
||||
resolved_boot_nodes.push(resolved);
|
||||
}
|
||||
|
||||
discovery_v4_config = discovery_v4_config.map(|mut disc_config| {
|
||||
// merge configured boot nodes
|
||||
disc_config.bootstrap_nodes.extend(boot_nodes.clone());
|
||||
disc_config.bootstrap_nodes.extend(resolved_boot_nodes.clone());
|
||||
disc_config.add_eip868_pair("eth", status.forkid);
|
||||
disc_config
|
||||
});
|
||||
|
||||
@ -25,6 +25,7 @@ secp256k1.workspace = true
|
||||
serde_with.workspace = true
|
||||
thiserror.workspace = true
|
||||
url.workspace = true
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
alloy-primitives = { workspace = true, features = ["rand"] }
|
||||
|
||||
@ -2,6 +2,43 @@
|
||||
//!
|
||||
//! This crate manages and converts Ethereum network entities such as node records, peer IDs, and
|
||||
//! Ethereum Node Records (ENRs)
|
||||
//!
|
||||
//! ## An overview of Node Record types
|
||||
//!
|
||||
//! Ethereum uses different types of "node records" to represent peers on the network.
|
||||
//!
|
||||
//! The simplest way to identify a peer is by public key. This is the [`PeerId`] type, which usually
|
||||
//! represents a peer's secp256k1 public key.
|
||||
//!
|
||||
//! A more complete representation of a peer is the [`NodeRecord`] type, which includes the peer's
|
||||
//! IP address, the ports where it is reachable (TCP and UDP), and the peer's public key. This is
|
||||
//! what is returned from discovery v4 queries.
|
||||
//!
|
||||
//! The most comprehensive node record type is the Ethereum Node Record ([`Enr`]), which is a
|
||||
//! signed, versioned record that includes the information from a [`NodeRecord`] along with
|
||||
//! additional metadata. This is the data structure returned from discovery v5 queries.
|
||||
//!
|
||||
//! When we need to deserialize an identifier that could be any of these three types ([`PeerId`],
|
||||
//! [`NodeRecord`], and [`Enr`]), we use the [`AnyNode`] type, which is an enum over the three
|
||||
//! types. [`AnyNode`] is used in reth's `admin_addTrustedPeer` RPC method.
|
||||
//!
|
||||
//! The __final__ type is the [`TrustedPeer`] type, which is similar to a [`NodeRecord`] but may
|
||||
//! include a domain name instead of a direct IP address. It includes a `resolve` method, which can
|
||||
//! be used to resolve the domain name, producing a [`NodeRecord`]. This is useful for adding
|
||||
//! trusted peers at startup, whose IP address may not be static each time the node starts. This is
|
||||
//! common in orchestrated environments like Kubernetes, where there is reliable service discovery,
|
||||
//! but services do not necessarily have static IPs.
|
||||
//!
|
||||
//! In short, the types are as follows:
|
||||
//! - [`PeerId`]: A simple public key identifier.
|
||||
//! - [`NodeRecord`]: A more complete representation of a peer, including IP address and ports.
|
||||
//! - [`Enr`]: An Ethereum Node Record, which is a signed, versioned record that includes additional
|
||||
//! metadata. Useful when interacting with discovery v5, or when custom metadata is required.
|
||||
//! - [`AnyNode`]: An enum over [`PeerId`], [`NodeRecord`], and [`Enr`], useful in deserialization
|
||||
//! when the type of the node record is not known.
|
||||
//! - [`TrustedPeer`]: A [`NodeRecord`] with an optional domain name, which can be resolved to a
|
||||
//! [`NodeRecord`]. Useful for adding trusted peers at startup, whose IP address may not be
|
||||
//! static.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
|
||||
@ -24,6 +61,9 @@ pub type PeerId = B512;
|
||||
pub mod node_record;
|
||||
pub use node_record::{NodeRecord, NodeRecordParseError};
|
||||
|
||||
pub mod trusted_peer;
|
||||
pub use trusted_peer::TrustedPeer;
|
||||
|
||||
/// This tag should be set to indicate to libsecp256k1 that the following bytes denote an
|
||||
/// uncompressed pubkey.
|
||||
///
|
||||
|
||||
300
crates/net/types/src/trusted_peer.rs
Normal file
300
crates/net/types/src/trusted_peer.rs
Normal file
@ -0,0 +1,300 @@
|
||||
//! `NodeRecord` type that uses a domain instead of an IP.
|
||||
|
||||
use std::{
|
||||
fmt::{self, Write},
|
||||
io::Error,
|
||||
net::IpAddr,
|
||||
num::ParseIntError,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use crate::{NodeRecord, PeerId};
|
||||
use secp256k1::{SecretKey, SECP256K1};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
use url::Host;
|
||||
|
||||
/// Represents the node record of a trusted peer. The only difference between this and a
|
||||
/// [`NodeRecord`] is that this does not contain the IP address of the peer, but rather a domain
|
||||
/// __or__ IP address.
|
||||
///
|
||||
/// This is useful when specifying nodes which are in internal infrastructure and may only be
|
||||
/// discoverable reliably using DNS.
|
||||
///
|
||||
/// This should NOT be used for any use case other than in trusted peer lists.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, SerializeDisplay, DeserializeFromStr)]
|
||||
pub struct TrustedPeer {
|
||||
/// The host of a node.
|
||||
pub host: Host,
|
||||
/// TCP port of the port that accepts connections.
|
||||
pub tcp_port: u16,
|
||||
/// UDP discovery port.
|
||||
pub udp_port: u16,
|
||||
/// Public key of the discovery service
|
||||
pub id: PeerId,
|
||||
}
|
||||
|
||||
impl TrustedPeer {
|
||||
/// Derive the [`NodeRecord`] from the secret key and addr
|
||||
pub fn from_secret_key(host: Host, port: u16, sk: &SecretKey) -> Self {
|
||||
let pk = secp256k1::PublicKey::from_secret_key(SECP256K1, sk);
|
||||
let id = PeerId::from_slice(&pk.serialize_uncompressed()[1..]);
|
||||
Self::new(host, port, id)
|
||||
}
|
||||
|
||||
/// Creates a new record from a socket addr and peer id.
|
||||
pub const fn new(host: Host, port: u16, id: PeerId) -> Self {
|
||||
Self { host, tcp_port: port, udp_port: port, id }
|
||||
}
|
||||
|
||||
/// Resolves the host in a [`TrustedPeer`] to an IP address, returning a [`NodeRecord`].
|
||||
pub async fn resolve(&self) -> Result<NodeRecord, Error> {
|
||||
let domain = match self.host.to_owned() {
|
||||
Host::Ipv4(ip) => {
|
||||
let id = self.id;
|
||||
let tcp_port = self.tcp_port;
|
||||
let udp_port = self.udp_port;
|
||||
|
||||
return Ok(NodeRecord { address: ip.into(), id, tcp_port, udp_port })
|
||||
}
|
||||
Host::Ipv6(ip) => {
|
||||
let id = self.id;
|
||||
let tcp_port = self.tcp_port;
|
||||
let udp_port = self.udp_port;
|
||||
|
||||
return Ok(NodeRecord { address: ip.into(), id, tcp_port, udp_port })
|
||||
}
|
||||
Host::Domain(domain) => domain,
|
||||
};
|
||||
|
||||
// Resolve the domain to an IP address
|
||||
let mut ips = tokio::net::lookup_host(format!("{domain}:0")).await?;
|
||||
let ip = ips
|
||||
.next()
|
||||
.ok_or_else(|| Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found"))?;
|
||||
Ok(NodeRecord {
|
||||
address: ip.ip(),
|
||||
id: self.id,
|
||||
tcp_port: self.tcp_port,
|
||||
udp_port: self.udp_port,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TrustedPeer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("enode://")?;
|
||||
alloy_primitives::hex::encode(self.id.as_slice()).fmt(f)?;
|
||||
f.write_char('@')?;
|
||||
self.host.fmt(f)?;
|
||||
f.write_char(':')?;
|
||||
self.tcp_port.fmt(f)?;
|
||||
if self.tcp_port != self.udp_port {
|
||||
f.write_str("?discport=")?;
|
||||
self.udp_port.fmt(f)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Possible error types when parsing a [`NodeRecord`]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum NodeRecordParseError {
|
||||
/// Invalid url
|
||||
#[error("Failed to parse url: {0}")]
|
||||
InvalidUrl(String),
|
||||
/// Invalid id
|
||||
#[error("Failed to parse id")]
|
||||
InvalidId(String),
|
||||
/// Invalid discport
|
||||
#[error("Failed to discport query: {0}")]
|
||||
Discport(ParseIntError),
|
||||
}
|
||||
|
||||
impl FromStr for TrustedPeer {
|
||||
type Err = NodeRecordParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use url::Url;
|
||||
|
||||
// Parse the URL with enode prefix replaced with http.
|
||||
// The enode prefix causes the parser to use parse_opaque() on
|
||||
// the host str which only handles domains and ipv6, not ipv4.
|
||||
let url = Url::parse(s.replace("enode://", "http://").as_str())
|
||||
.map_err(|e| NodeRecordParseError::InvalidUrl(e.to_string()))?;
|
||||
|
||||
let host = url
|
||||
.host()
|
||||
.ok_or_else(|| NodeRecordParseError::InvalidUrl("no host specified".to_string()))?
|
||||
.to_owned();
|
||||
|
||||
let port = url
|
||||
.port()
|
||||
.ok_or_else(|| NodeRecordParseError::InvalidUrl("no port specified".to_string()))?;
|
||||
|
||||
let udp_port = if let Some(discovery_port) = url
|
||||
.query_pairs()
|
||||
.find_map(|(maybe_disc, port)| (maybe_disc.as_ref() == "discport").then_some(port))
|
||||
{
|
||||
discovery_port.parse::<u16>().map_err(NodeRecordParseError::Discport)?
|
||||
} else {
|
||||
port
|
||||
};
|
||||
|
||||
let id = url
|
||||
.username()
|
||||
.parse::<PeerId>()
|
||||
.map_err(|e| NodeRecordParseError::InvalidId(e.to_string()))?;
|
||||
|
||||
Ok(Self { host, id, tcp_port: port, udp_port })
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeRecord> for TrustedPeer {
|
||||
fn from(record: NodeRecord) -> Self {
|
||||
let host = match record.address {
|
||||
IpAddr::V4(ip) => Host::Ipv4(ip),
|
||||
IpAddr::V6(ip) => Host::Ipv6(ip),
|
||||
};
|
||||
|
||||
Self { host, tcp_port: record.tcp_port, udp_port: record.udp_port, id: record.id }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::net::Ipv6Addr;
|
||||
|
||||
#[test]
|
||||
fn test_url_parse() {
|
||||
let url = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301";
|
||||
let node: TrustedPeer = url.parse().unwrap();
|
||||
assert_eq!(node, TrustedPeer {
|
||||
host: Host::Ipv4([10,3,58,6].into()),
|
||||
tcp_port: 30303,
|
||||
udp_port: 30301,
|
||||
id: "6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0".parse().unwrap(),
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_display() {
|
||||
let url = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303";
|
||||
let node: TrustedPeer = url.parse().unwrap();
|
||||
assert_eq!(url, &format!("{node}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_display_discport() {
|
||||
let url = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301";
|
||||
let node: TrustedPeer = url.parse().unwrap();
|
||||
assert_eq!(url, &format!("{node}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_serialize() {
|
||||
let cases = vec![
|
||||
// IPv4
|
||||
(
|
||||
TrustedPeer {
|
||||
host: Host::Ipv4([10, 3, 58, 6].into()),
|
||||
tcp_port: 30303u16,
|
||||
udp_port: 30301u16,
|
||||
id: PeerId::from_str("6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0").unwrap(),
|
||||
},
|
||||
"\"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301\""
|
||||
),
|
||||
// IPv6
|
||||
(
|
||||
TrustedPeer {
|
||||
host: Host::Ipv6(Ipv6Addr::new(0x2001, 0xdb8, 0x3c4d, 0x15, 0x0, 0x0, 0xabcd, 0xef12)),
|
||||
tcp_port: 52150u16,
|
||||
udp_port: 52151u16,
|
||||
id: PeerId::from_str("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439").unwrap(),
|
||||
},
|
||||
"\"enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150?discport=52151\""
|
||||
),
|
||||
// URL
|
||||
(
|
||||
TrustedPeer {
|
||||
host: Host::Domain("my-domain".to_string()),
|
||||
tcp_port: 52150u16,
|
||||
udp_port: 52151u16,
|
||||
id: PeerId::from_str("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439").unwrap(),
|
||||
},
|
||||
"\"enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@my-domain:52150?discport=52151\""
|
||||
),
|
||||
];
|
||||
|
||||
for (node, expected) in cases {
|
||||
let ser = serde_json::to_string::<TrustedPeer>(&node).expect("couldn't serialize");
|
||||
assert_eq!(ser, expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_deserialize() {
|
||||
let cases = vec![
|
||||
// IPv4
|
||||
(
|
||||
"\"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301\"",
|
||||
TrustedPeer {
|
||||
host: Host::Ipv4([10, 3, 58, 6].into()),
|
||||
tcp_port: 30303u16,
|
||||
udp_port: 30301u16,
|
||||
id: PeerId::from_str("6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0").unwrap(),
|
||||
}
|
||||
),
|
||||
// IPv6
|
||||
(
|
||||
"\"enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150?discport=52151\"",
|
||||
TrustedPeer {
|
||||
host: Host::Ipv6(Ipv6Addr::new(0x2001, 0xdb8, 0x3c4d, 0x15, 0x0, 0x0, 0xabcd, 0xef12)),
|
||||
tcp_port: 52150u16,
|
||||
udp_port: 52151u16,
|
||||
id: PeerId::from_str("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439").unwrap(),
|
||||
}
|
||||
),
|
||||
// URL
|
||||
(
|
||||
"\"enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@my-domain:52150?discport=52151\"",
|
||||
TrustedPeer {
|
||||
host: Host::Domain("my-domain".to_string()),
|
||||
tcp_port: 52150u16,
|
||||
udp_port: 52151u16,
|
||||
id: PeerId::from_str("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439").unwrap(),
|
||||
}
|
||||
),
|
||||
];
|
||||
|
||||
for (url, expected) in cases {
|
||||
let node: TrustedPeer = serde_json::from_str(url).expect("couldn't deserialize");
|
||||
assert_eq!(node, expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_resolve_dns_node_record() {
|
||||
// Set up tests
|
||||
let tests = vec![("localhost")];
|
||||
|
||||
// Run tests
|
||||
for domain in tests {
|
||||
// Construct record
|
||||
let rec =
|
||||
TrustedPeer::new(url::Host::Domain(domain.to_owned()), 30300, PeerId::random());
|
||||
|
||||
// Resolve domain and validate
|
||||
let rec = rec.resolve().await.unwrap();
|
||||
match rec.address {
|
||||
std::net::IpAddr::V4(addr) => {
|
||||
assert_eq!(addr, std::net::Ipv4Addr::new(127, 0, 0, 1))
|
||||
}
|
||||
std::net::IpAddr::V6(addr) => {
|
||||
assert_eq!(addr, std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,6 +96,7 @@ procfs = "0.16.0"
|
||||
[dev-dependencies]
|
||||
# test vectors generation
|
||||
proptest.workspace = true
|
||||
reth-network-types.workspace = true
|
||||
|
||||
[features]
|
||||
optimism = [
|
||||
|
||||
@ -17,7 +17,7 @@ use reth_network::{
|
||||
},
|
||||
HelloMessageWithProtocols, NetworkConfigBuilder, SessionsConfig,
|
||||
};
|
||||
use reth_primitives::{mainnet_nodes, ChainSpec, NodeRecord};
|
||||
use reth_primitives::{mainnet_nodes, ChainSpec, TrustedPeer};
|
||||
use secp256k1::SecretKey;
|
||||
use std::{
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
@ -39,7 +39,7 @@ pub struct NetworkArgs {
|
||||
///
|
||||
/// --trusted-peers enode://abcd@192.168.0.1:30303
|
||||
#[arg(long, value_delimiter = ',')]
|
||||
pub trusted_peers: Vec<NodeRecord>,
|
||||
pub trusted_peers: Vec<TrustedPeer>,
|
||||
|
||||
/// Connect to or accept from trusted peers only
|
||||
#[arg(long)]
|
||||
@ -49,7 +49,11 @@ pub struct NetworkArgs {
|
||||
///
|
||||
/// Will fall back to a network-specific default if not specified.
|
||||
#[arg(long, value_delimiter = ',')]
|
||||
pub bootnodes: Option<Vec<NodeRecord>>,
|
||||
pub bootnodes: Option<Vec<TrustedPeer>>,
|
||||
|
||||
/// Amount of DNS resolution requests retries to perform when peering.
|
||||
#[arg(long, default_value_t = 0)]
|
||||
pub dns_retries: usize,
|
||||
|
||||
/// The path to the known peers file. Connected peers are dumped to this file on nodes
|
||||
/// shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
|
||||
@ -125,10 +129,7 @@ impl NetworkArgs {
|
||||
secret_key: SecretKey,
|
||||
default_peers_file: PathBuf,
|
||||
) -> NetworkConfigBuilder {
|
||||
let boot_nodes = self
|
||||
.bootnodes
|
||||
.clone()
|
||||
.unwrap_or_else(|| chain_spec.bootnodes().unwrap_or_else(mainnet_nodes));
|
||||
let chain_bootnodes = chain_spec.bootnodes().unwrap_or_else(mainnet_nodes);
|
||||
let peers_file = self.peers_file.clone().unwrap_or(default_peers_file);
|
||||
|
||||
// Configure peer connections
|
||||
@ -156,7 +157,7 @@ impl NetworkArgs {
|
||||
SessionsConfig::default().with_upscaled_event_buffer(peers_config.max_peers()),
|
||||
)
|
||||
.peer_config(peers_config)
|
||||
.boot_nodes(boot_nodes.clone())
|
||||
.boot_nodes(chain_bootnodes.clone())
|
||||
.chain_spec(chain_spec.clone())
|
||||
.transactions_manager_config(transactions_manager_config)
|
||||
// Configure node identity
|
||||
@ -189,7 +190,7 @@ impl NetworkArgs {
|
||||
} = self.discovery;
|
||||
|
||||
builder
|
||||
.add_unsigned_boot_nodes(boot_nodes.into_iter())
|
||||
.add_unsigned_boot_nodes(chain_bootnodes.into_iter())
|
||||
.lookup_interval(discv5_lookup_interval)
|
||||
.bootstrap_lookup_interval(discv5_bootstrap_lookup_interval)
|
||||
.bootstrap_lookup_countdown(discv5_bootstrap_lookup_countdown)
|
||||
@ -224,6 +225,7 @@ impl Default for NetworkArgs {
|
||||
trusted_peers: vec![],
|
||||
trusted_only: false,
|
||||
bootnodes: None,
|
||||
dns_retries: 0,
|
||||
peers_file: None,
|
||||
identity: P2P_CLIENT_VERSION.to_string(),
|
||||
p2p_secret_key: None,
|
||||
@ -416,6 +418,22 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_retry_strategy_args() {
|
||||
let tests = vec![0, 10];
|
||||
|
||||
for retries in tests {
|
||||
let args = CommandParser::<NetworkArgs>::parse_from([
|
||||
"reth",
|
||||
"--dns-retries",
|
||||
retries.to_string().as_str(),
|
||||
])
|
||||
.args;
|
||||
|
||||
assert_eq!(args.dns_retries, retries);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
#[test]
|
||||
fn network_args_default_sanity_test() {
|
||||
|
||||
@ -58,6 +58,7 @@ eyre.workspace = true
|
||||
fdlimit.workspace = true
|
||||
confy.workspace = true
|
||||
rayon.workspace = true
|
||||
backon.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile.workspace = true
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
//! Helper types that can be used by launchers.
|
||||
|
||||
use backon::{ConstantBuilder, Retryable};
|
||||
use eyre::Context;
|
||||
use rayon::ThreadPoolBuilder;
|
||||
use reth_auto_seal_consensus::MiningMode;
|
||||
@ -56,17 +57,19 @@ impl LaunchContext {
|
||||
/// `config`.
|
||||
///
|
||||
/// Attaches both the `NodeConfig` and the loaded `reth.toml` config to the launch context.
|
||||
pub fn with_loaded_toml_config(
|
||||
pub async fn with_loaded_toml_config(
|
||||
self,
|
||||
config: NodeConfig,
|
||||
) -> eyre::Result<LaunchContextWith<WithConfigs>> {
|
||||
let toml_config = self.load_toml_config(&config)?;
|
||||
let toml_config = self.load_toml_config(&config).await?;
|
||||
Ok(self.with(WithConfigs { config, toml_config }))
|
||||
}
|
||||
|
||||
/// Loads the reth config with the configured `data_dir` and overrides settings according to the
|
||||
/// `config`.
|
||||
pub fn load_toml_config(&self, config: &NodeConfig) -> eyre::Result<reth_config::Config> {
|
||||
///
|
||||
/// This is async because the trusted peers may have to be resolved.
|
||||
pub async fn load_toml_config(&self, config: &NodeConfig) -> eyre::Result<reth_config::Config> {
|
||||
let config_path = config.config.clone().unwrap_or_else(|| self.data_dir.config());
|
||||
|
||||
let mut toml_config = confy::load_path::<reth_config::Config>(&config_path)
|
||||
@ -81,9 +84,16 @@ impl LaunchContext {
|
||||
|
||||
if !config.network.trusted_peers.is_empty() {
|
||||
info!(target: "reth::cli", "Adding trusted nodes");
|
||||
config.network.trusted_peers.iter().for_each(|peer| {
|
||||
toml_config.peers.trusted_nodes.insert(*peer);
|
||||
});
|
||||
|
||||
// resolve trusted peers if they use a domain instead of dns
|
||||
for peer in &config.network.trusted_peers {
|
||||
let backoff = ConstantBuilder::default().with_max_times(config.network.dns_retries);
|
||||
let resolved = (move || { peer.resolve() })
|
||||
.retry(&backoff)
|
||||
.notify(|err, _| warn!(target: "reth::cli", "Error resolving peer domain: {err}. Retrying..."))
|
||||
.await?;
|
||||
toml_config.peers.trusted_nodes.insert(resolved);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(toml_config)
|
||||
|
||||
@ -94,7 +94,7 @@ where
|
||||
let ctx = ctx
|
||||
.with_configured_globals()
|
||||
// load the toml config
|
||||
.with_loaded_toml_config(config)?
|
||||
.with_loaded_toml_config(config).await?
|
||||
// attach the database
|
||||
.attach(database.clone())
|
||||
// ensure certain settings take effect
|
||||
|
||||
@ -73,7 +73,7 @@ pub use integer_list::IntegerList;
|
||||
pub use log::{logs_bloom, Log};
|
||||
pub use net::{
|
||||
goerli_nodes, holesky_nodes, mainnet_nodes, parse_nodes, sepolia_nodes, NodeRecord,
|
||||
NodeRecordParseError, GOERLI_BOOTNODES, HOLESKY_BOOTNODES, MAINNET_BOOTNODES,
|
||||
NodeRecordParseError, TrustedPeer, GOERLI_BOOTNODES, HOLESKY_BOOTNODES, MAINNET_BOOTNODES,
|
||||
SEPOLIA_BOOTNODES,
|
||||
};
|
||||
pub use prune::{
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pub use reth_network_types::{NodeRecord, NodeRecordParseError};
|
||||
pub use reth_network_types::{NodeRecord, NodeRecordParseError, TrustedPeer};
|
||||
|
||||
// Ethereum bootnodes come from <https://github.com/ledgerwatch/erigon/blob/devel/params/bootnodes.go>
|
||||
// OP bootnodes come from <https://github.com/ethereum-optimism/op-geth/blob/optimism/params/bootnodes.go>
|
||||
|
||||
Reference in New Issue
Block a user