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 = [
|
||||
"beacon_node",
|
||||
"clap",
|
||||
"discv5",
|
||||
"eth2_libp2p",
|
||||
"eth2_ssz",
|
||||
"eth2_testnet_config",
|
||||
"futures 0.3.5",
|
||||
"hex 0.4.2",
|
||||
"log 0.4.11",
|
||||
"logging",
|
||||
"slog",
|
||||
@ -550,6 +552,7 @@ dependencies = [
|
||||
"slog-term",
|
||||
"sloggers",
|
||||
"tokio 0.2.22",
|
||||
"types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1242,9 +1245,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "discv5"
|
||||
version = "0.1.0-alpha.11"
|
||||
version = "0.1.0-alpha.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c68cb1b942aadd3bb3a13620c4d831c0aa49eda988cf8bcccfdfdc7ef69504a7"
|
||||
checksum = "65a5e4a22a4c1d7142f54ac068b8c6252610ed0ebf00264f39eccee7f88fe4b9"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"arrayvec",
|
||||
|
@ -32,7 +32,7 @@ snap = "1.0.0"
|
||||
void = "1.0.2"
|
||||
tokio-io-timeout = "0.4.0"
|
||||
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"
|
||||
environment = { path = "../../lighthouse/environment" }
|
||||
rand = "0.7.3"
|
||||
|
@ -8,6 +8,9 @@ edition = "2018"
|
||||
beacon_node = { path = "../beacon_node" }
|
||||
clap = "2.33.0"
|
||||
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"
|
||||
sloggers = "1.0.1"
|
||||
tokio = "0.2.21"
|
||||
@ -18,4 +21,4 @@ slog-async = "2.5.0"
|
||||
slog-scope = "4.3.0"
|
||||
slog-stdlog = "4.0.0"
|
||||
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 discv5::{enr::CombinedKey, Enr};
|
||||
use eth2_libp2p::discv5::{enr::CombinedKey, Enr};
|
||||
use eth2_libp2p::{
|
||||
discovery::{create_enr_builder_from_config, use_or_load_enr},
|
||||
load_private_key, CombinedKeyExt, NetworkConfig,
|
||||
};
|
||||
use eth2_testnet_config::Eth2TestnetConfig;
|
||||
use ssz::Encode;
|
||||
use std::convert::TryFrom;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use types::EthSpec;
|
||||
|
||||
/// A set of configuration parameters for the bootnode, established from CLI arguments.
|
||||
pub struct BootNodeConfig {
|
||||
pub struct BootNodeConfig<T: EthSpec> {
|
||||
pub listen_socket: SocketAddr,
|
||||
// TODO: Generalise to multiaddr
|
||||
pub boot_nodes: Vec<Enr>,
|
||||
pub local_enr: Enr,
|
||||
pub local_key: CombinedKey,
|
||||
pub auto_update: bool,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
|
||||
impl<T: EthSpec> TryFrom<&ArgMatches<'_>> for BootNodeConfig<T> {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(matches: &ArgMatches<'_>) -> Result<Self, Self::Error> {
|
||||
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 logger = slog_scope::logger();
|
||||
|
||||
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 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)?;
|
||||
|
||||
let boot_nodes = {
|
||||
if let Some(boot_nodes) = matches.value_of("boot-nodes") {
|
||||
boot_nodes
|
||||
.split(',')
|
||||
.map(|enr| enr.parse().map_err(|_| format!("Invalid ENR: {}", enr)))
|
||||
.collect::<Result<Vec<Enr>, _>>()?
|
||||
// build the enr_fork_id and add it to the local_enr if it exists
|
||||
if let Some(config) = eth2_testnet_config.as_ref() {
|
||||
let spec = config
|
||||
.yaml_config
|
||||
.as_ref()
|
||||
.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 {
|
||||
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");
|
||||
|
||||
@ -62,6 +131,7 @@ impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
|
||||
local_enr,
|
||||
local_key,
|
||||
auto_update,
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ mod config;
|
||||
mod server;
|
||||
pub use cli::cli_app;
|
||||
use config::BootNodeConfig;
|
||||
use types::EthSpec;
|
||||
|
||||
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 _log_guard = slog_stdlog::init_with_level(debug_level).unwrap();
|
||||
|
||||
let log = slog_scope::logger();
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
let mut runtime = tokio::runtime::Builder::new()
|
||||
.threaded_scheduler()
|
||||
@ -60,7 +67,7 @@ fn main(matches: &ArgMatches<'_>, log: slog::Logger) -> Result<(), String> {
|
||||
.map_err(|e| format!("Failed to build runtime: {}", e))?;
|
||||
|
||||
// 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
|
||||
runtime.block_on(server::run(config, log));
|
||||
|
@ -1,16 +1,25 @@
|
||||
//! The main bootnode server execution.
|
||||
|
||||
use super::BootNodeConfig;
|
||||
use discv5::{Discv5, Discv5ConfigBuilder, Discv5Event};
|
||||
use eth2_libp2p::EnrExt;
|
||||
use eth2_libp2p::{
|
||||
discv5::{enr::NodeId, Discv5, Discv5ConfigBuilder, Discv5Event},
|
||||
EnrExt, Eth2Enr,
|
||||
};
|
||||
use futures::prelude::*;
|
||||
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
|
||||
|
||||
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());
|
||||
|
||||
@ -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 !discv5.table_entries_id().is_empty() {
|
||||
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
|
||||
|
@ -19,4 +19,4 @@ serde_yaml = "0.8.11"
|
||||
types = { path = "../../consensus/types"}
|
||||
enr = { version = "0.1.0", features = ["libsecp256k1", "ed25519"] }
|
||||
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"
|
||||
lazy_static = "1.4.0"
|
||||
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