Update boot-node and discovery (#1682)
* Improve boot_node and upgrade discovery * Clippy lints
This commit is contained in:
parent
ae28773965
commit
13cb642f39
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -538,9 +538,11 @@ version = "0.2.12"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"beacon_node",
|
"beacon_node",
|
||||||
"clap",
|
"clap",
|
||||||
"discv5",
|
|
||||||
"eth2_libp2p",
|
"eth2_libp2p",
|
||||||
|
"eth2_ssz",
|
||||||
|
"eth2_testnet_config",
|
||||||
"futures 0.3.5",
|
"futures 0.3.5",
|
||||||
|
"hex 0.4.2",
|
||||||
"log 0.4.11",
|
"log 0.4.11",
|
||||||
"logging",
|
"logging",
|
||||||
"slog",
|
"slog",
|
||||||
@ -550,6 +552,7 @@ dependencies = [
|
|||||||
"slog-term",
|
"slog-term",
|
||||||
"sloggers",
|
"sloggers",
|
||||||
"tokio 0.2.22",
|
"tokio 0.2.22",
|
||||||
|
"types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1242,9 +1245,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "discv5"
|
name = "discv5"
|
||||||
version = "0.1.0-alpha.11"
|
version = "0.1.0-alpha.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c68cb1b942aadd3bb3a13620c4d831c0aa49eda988cf8bcccfdfdc7ef69504a7"
|
checksum = "65a5e4a22a4c1d7142f54ac068b8c6252610ed0ebf00264f39eccee7f88fe4b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
@ -32,7 +32,7 @@ snap = "1.0.0"
|
|||||||
void = "1.0.2"
|
void = "1.0.2"
|
||||||
tokio-io-timeout = "0.4.0"
|
tokio-io-timeout = "0.4.0"
|
||||||
tokio-util = { version = "0.3.1", features = ["codec", "compat"] }
|
tokio-util = { version = "0.3.1", features = ["codec", "compat"] }
|
||||||
discv5 = { version = "0.1.0-alpha.10", features = ["libp2p"] }
|
discv5 = { version = "0.1.0-alpha.12", features = ["libp2p"] }
|
||||||
tiny-keccak = "2.0.2"
|
tiny-keccak = "2.0.2"
|
||||||
environment = { path = "../../lighthouse/environment" }
|
environment = { path = "../../lighthouse/environment" }
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
|
@ -8,6 +8,9 @@ edition = "2018"
|
|||||||
beacon_node = { path = "../beacon_node" }
|
beacon_node = { path = "../beacon_node" }
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
eth2_libp2p = { path = "../beacon_node/eth2_libp2p" }
|
eth2_libp2p = { path = "../beacon_node/eth2_libp2p" }
|
||||||
|
types = { path = "../consensus/types" }
|
||||||
|
eth2_testnet_config = { path = "../common/eth2_testnet_config" }
|
||||||
|
eth2_ssz = { path = "../consensus/ssz" }
|
||||||
slog = "2.5.2"
|
slog = "2.5.2"
|
||||||
sloggers = "1.0.1"
|
sloggers = "1.0.1"
|
||||||
tokio = "0.2.21"
|
tokio = "0.2.21"
|
||||||
@ -18,4 +21,4 @@ slog-async = "2.5.0"
|
|||||||
slog-scope = "4.3.0"
|
slog-scope = "4.3.0"
|
||||||
slog-stdlog = "4.0.0"
|
slog-stdlog = "4.0.0"
|
||||||
futures = "0.3.5"
|
futures = "0.3.5"
|
||||||
discv5 = "0.1.0-alpha.5"
|
hex = "0.4.2"
|
||||||
|
@ -1,34 +1,81 @@
|
|||||||
use beacon_node::{get_data_dir, set_network_config};
|
use beacon_node::{get_data_dir, get_eth2_testnet_config, set_network_config};
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use discv5::{enr::CombinedKey, Enr};
|
use eth2_libp2p::discv5::{enr::CombinedKey, Enr};
|
||||||
use eth2_libp2p::{
|
use eth2_libp2p::{
|
||||||
discovery::{create_enr_builder_from_config, use_or_load_enr},
|
discovery::{create_enr_builder_from_config, use_or_load_enr},
|
||||||
load_private_key, CombinedKeyExt, NetworkConfig,
|
load_private_key, CombinedKeyExt, NetworkConfig,
|
||||||
};
|
};
|
||||||
|
use eth2_testnet_config::Eth2TestnetConfig;
|
||||||
|
use ssz::Encode;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
use types::EthSpec;
|
||||||
|
|
||||||
/// A set of configuration parameters for the bootnode, established from CLI arguments.
|
/// A set of configuration parameters for the bootnode, established from CLI arguments.
|
||||||
pub struct BootNodeConfig {
|
pub struct BootNodeConfig<T: EthSpec> {
|
||||||
pub listen_socket: SocketAddr,
|
pub listen_socket: SocketAddr,
|
||||||
// TODO: Generalise to multiaddr
|
// TODO: Generalise to multiaddr
|
||||||
pub boot_nodes: Vec<Enr>,
|
pub boot_nodes: Vec<Enr>,
|
||||||
pub local_enr: Enr,
|
pub local_enr: Enr,
|
||||||
pub local_key: CombinedKey,
|
pub local_key: CombinedKey,
|
||||||
pub auto_update: bool,
|
pub auto_update: bool,
|
||||||
|
phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
|
impl<T: EthSpec> TryFrom<&ArgMatches<'_>> for BootNodeConfig<T> {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
fn try_from(matches: &ArgMatches<'_>) -> Result<Self, Self::Error> {
|
fn try_from(matches: &ArgMatches<'_>) -> Result<Self, Self::Error> {
|
||||||
let data_dir = get_data_dir(matches);
|
let data_dir = get_data_dir(matches);
|
||||||
|
|
||||||
|
// Try and grab testnet config from input CLI params
|
||||||
|
let eth2_testnet_config: Option<Eth2TestnetConfig<T>> = {
|
||||||
|
if matches.is_present("testnet") {
|
||||||
|
Some(get_eth2_testnet_config(&matches)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try and obtain bootnodes
|
||||||
|
|
||||||
|
let boot_nodes = {
|
||||||
|
let mut boot_nodes = Vec::new();
|
||||||
|
|
||||||
|
if let Some(testnet_config) = eth2_testnet_config.as_ref() {
|
||||||
|
if let Some(enr) = &testnet_config.boot_enr {
|
||||||
|
boot_nodes.extend_from_slice(enr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(nodes) = matches.value_of("boot-nodes") {
|
||||||
|
boot_nodes.extend_from_slice(
|
||||||
|
&nodes
|
||||||
|
.split(',')
|
||||||
|
.map(|enr| enr.parse().map_err(|_| format!("Invalid ENR: {}", enr)))
|
||||||
|
.collect::<Result<Vec<Enr>, _>>()?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_nodes
|
||||||
|
};
|
||||||
|
|
||||||
let mut network_config = NetworkConfig::default();
|
let mut network_config = NetworkConfig::default();
|
||||||
|
|
||||||
let logger = slog_scope::logger();
|
let logger = slog_scope::logger();
|
||||||
|
|
||||||
set_network_config(&mut network_config, matches, &data_dir, &logger, true)?;
|
set_network_config(&mut network_config, matches, &data_dir, &logger, true)?;
|
||||||
|
// default to the standard port
|
||||||
|
if !matches.is_present("enr-udp-port") {
|
||||||
|
network_config.enr_udp_port = Some(
|
||||||
|
matches
|
||||||
|
.value_of("port")
|
||||||
|
.expect("Value required")
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| "Invalid port number")?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let private_key = load_private_key(&network_config, &logger);
|
let private_key = load_private_key(&network_config, &logger);
|
||||||
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
||||||
@ -39,16 +86,38 @@ impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
|
|||||||
|
|
||||||
use_or_load_enr(&local_key, &mut local_enr, &network_config, &logger)?;
|
use_or_load_enr(&local_key, &mut local_enr, &network_config, &logger)?;
|
||||||
|
|
||||||
let boot_nodes = {
|
// build the enr_fork_id and add it to the local_enr if it exists
|
||||||
if let Some(boot_nodes) = matches.value_of("boot-nodes") {
|
if let Some(config) = eth2_testnet_config.as_ref() {
|
||||||
boot_nodes
|
let spec = config
|
||||||
.split(',')
|
.yaml_config
|
||||||
.map(|enr| enr.parse().map_err(|_| format!("Invalid ENR: {}", enr)))
|
.as_ref()
|
||||||
.collect::<Result<Vec<Enr>, _>>()?
|
.ok_or_else(|| "The testnet directory must contain a spec config".to_string())?
|
||||||
|
.apply_to_chain_spec::<T>(&T::default_spec())
|
||||||
|
.ok_or_else(|| "The loaded config is not compatible with the current spec")?;
|
||||||
|
|
||||||
|
if let Some(genesis_state) = config.genesis_state.as_ref() {
|
||||||
|
slog::info!(logger, "Genesis state found"; "root" => genesis_state.canonical_root().to_string());
|
||||||
|
let enr_fork = spec.enr_fork_id(
|
||||||
|
types::Slot::from(0u64),
|
||||||
|
genesis_state.genesis_validators_root,
|
||||||
|
);
|
||||||
|
|
||||||
|
// add to the local_enr
|
||||||
|
if let Err(e) = local_enr.insert("eth2", enr_fork.as_ssz_bytes(), &local_key) {
|
||||||
|
slog::warn!(logger, "Could not update eth2 field"; "error" => ?e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
slog::warn!(
|
||||||
|
logger,
|
||||||
|
"No genesis state provided. No Eth2 field added to the ENR"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
|
slog::warn!(
|
||||||
|
logger,
|
||||||
|
"No testnet config provided. Not setting an eth2 field"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let auto_update = matches.is_present("enable-enr_auto_update");
|
let auto_update = matches.is_present("enable-enr_auto_update");
|
||||||
|
|
||||||
@ -62,6 +131,7 @@ impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
|
|||||||
local_enr,
|
local_enr,
|
||||||
local_key,
|
local_key,
|
||||||
auto_update,
|
auto_update,
|
||||||
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ mod config;
|
|||||||
mod server;
|
mod server;
|
||||||
pub use cli::cli_app;
|
pub use cli::cli_app;
|
||||||
use config::BootNodeConfig;
|
use config::BootNodeConfig;
|
||||||
|
use types::EthSpec;
|
||||||
|
|
||||||
const LOG_CHANNEL_SIZE: usize = 2048;
|
const LOG_CHANNEL_SIZE: usize = 2048;
|
||||||
|
|
||||||
@ -45,13 +46,19 @@ pub fn run(matches: &ArgMatches<'_>, debug_level: String) {
|
|||||||
let _scope_guard = slog_scope::set_global_logger(logger);
|
let _scope_guard = slog_scope::set_global_logger(logger);
|
||||||
let _log_guard = slog_stdlog::init_with_level(debug_level).unwrap();
|
let _log_guard = slog_stdlog::init_with_level(debug_level).unwrap();
|
||||||
|
|
||||||
|
let log = slog_scope::logger();
|
||||||
// Run the main function emitting any errors
|
// Run the main function emitting any errors
|
||||||
if let Err(e) = main(matches, slog_scope::logger()) {
|
if let Err(e) = match matches.value_of("spec") {
|
||||||
|
Some("minimal") => main::<types::MinimalEthSpec>(matches, log),
|
||||||
|
Some("mainnet") => main::<types::MainnetEthSpec>(matches, log),
|
||||||
|
Some("interop") => main::<types::InteropEthSpec>(matches, log),
|
||||||
|
spec => unreachable!("Unknown spec configuration: {:?}", spec),
|
||||||
|
} {
|
||||||
slog::crit!(slog_scope::logger(), "{}", e);
|
slog::crit!(slog_scope::logger(), "{}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main(matches: &ArgMatches<'_>, log: slog::Logger) -> Result<(), String> {
|
fn main<T: EthSpec>(matches: &ArgMatches<'_>, log: slog::Logger) -> Result<(), String> {
|
||||||
// Builds a custom executor for the bootnode
|
// Builds a custom executor for the bootnode
|
||||||
let mut runtime = tokio::runtime::Builder::new()
|
let mut runtime = tokio::runtime::Builder::new()
|
||||||
.threaded_scheduler()
|
.threaded_scheduler()
|
||||||
@ -60,7 +67,7 @@ fn main(matches: &ArgMatches<'_>, log: slog::Logger) -> Result<(), String> {
|
|||||||
.map_err(|e| format!("Failed to build runtime: {}", e))?;
|
.map_err(|e| format!("Failed to build runtime: {}", e))?;
|
||||||
|
|
||||||
// parse the CLI args into a useable config
|
// parse the CLI args into a useable config
|
||||||
let config = BootNodeConfig::try_from(matches)?;
|
let config: BootNodeConfig<T> = BootNodeConfig::try_from(matches)?;
|
||||||
|
|
||||||
// Run the boot node
|
// Run the boot node
|
||||||
runtime.block_on(server::run(config, log));
|
runtime.block_on(server::run(config, log));
|
||||||
|
@ -1,16 +1,25 @@
|
|||||||
//! The main bootnode server execution.
|
//! The main bootnode server execution.
|
||||||
|
|
||||||
use super::BootNodeConfig;
|
use super::BootNodeConfig;
|
||||||
use discv5::{Discv5, Discv5ConfigBuilder, Discv5Event};
|
use eth2_libp2p::{
|
||||||
use eth2_libp2p::EnrExt;
|
discv5::{enr::NodeId, Discv5, Discv5ConfigBuilder, Discv5Event},
|
||||||
|
EnrExt, Eth2Enr,
|
||||||
|
};
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use slog::info;
|
use slog::info;
|
||||||
|
use types::EthSpec;
|
||||||
|
|
||||||
pub async fn run(config: BootNodeConfig, log: slog::Logger) {
|
pub async fn run<T: EthSpec>(config: BootNodeConfig<T>, log: slog::Logger) {
|
||||||
// Print out useful information about the generated ENR
|
// Print out useful information about the generated ENR
|
||||||
|
|
||||||
let enr_socket = config.local_enr.udp_socket().expect("Enr has a UDP socket");
|
let enr_socket = config.local_enr.udp_socket().expect("Enr has a UDP socket");
|
||||||
info!(log, "Configuration parameters"; "listening_address" => format!("{}:{}", config.listen_socket.ip(), config.listen_socket.port()), "broadcast_address" => format!("{}:{}",enr_socket.ip(), enr_socket.port()));
|
let eth2_field = config
|
||||||
|
.local_enr
|
||||||
|
.eth2()
|
||||||
|
.map(|fork_id| hex::encode(fork_id.fork_digest))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
info!(log, "Configuration parameters"; "listening_address" => format!("{}:{}", config.listen_socket.ip(), config.listen_socket.port()), "broadcast_address" => format!("{}:{}",enr_socket.ip(), enr_socket.port()), "eth2" => eth2_field);
|
||||||
|
|
||||||
info!(log, "Identity established"; "peer_id" => config.local_enr.peer_id().to_string(), "node_id" => config.local_enr.node_id().to_string());
|
info!(log, "Identity established"; "peer_id" => config.local_enr.peer_id().to_string(), "node_id" => config.local_enr.node_id().to_string());
|
||||||
|
|
||||||
@ -51,7 +60,7 @@ pub async fn run(config: BootNodeConfig, log: slog::Logger) {
|
|||||||
// if there are peers in the local routing table, establish a session by running a query
|
// if there are peers in the local routing table, establish a session by running a query
|
||||||
if !discv5.table_entries_id().is_empty() {
|
if !discv5.table_entries_id().is_empty() {
|
||||||
info!(log, "Executing bootstrap query...");
|
info!(log, "Executing bootstrap query...");
|
||||||
let _ = discv5.find_node(discv5::enr::NodeId::random()).await;
|
let _ = discv5.find_node(NodeId::random()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// respond with metrics every 10 seconds
|
// respond with metrics every 10 seconds
|
||||||
|
@ -19,4 +19,4 @@ serde_yaml = "0.8.11"
|
|||||||
types = { path = "../../consensus/types"}
|
types = { path = "../../consensus/types"}
|
||||||
enr = { version = "0.1.0", features = ["libsecp256k1", "ed25519"] }
|
enr = { version = "0.1.0", features = ["libsecp256k1", "ed25519"] }
|
||||||
eth2_ssz = "0.1.2"
|
eth2_ssz = "0.1.2"
|
||||||
eth2_config = { path = "../eth2_config"}
|
eth2_config = { path = "../eth2_config"}
|
||||||
|
@ -21,4 +21,4 @@ slog-json = "2.3.0"
|
|||||||
exit-future = "0.2.0"
|
exit-future = "0.2.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
lighthouse_metrics = { path = "../../common/lighthouse_metrics" }
|
lighthouse_metrics = { path = "../../common/lighthouse_metrics" }
|
||||||
discv5 = { version = "0.1.0-alpha.10", features = ["libp2p"] }
|
discv5 = { version = "0.1.0-alpha.12", features = ["libp2p"] }
|
||||||
|
Loading…
Reference in New Issue
Block a user