mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 02:12:33 +00:00
Lighthouse bootnode (#1265)
* Initial bootnode structure * Add boot_node subcommand * Add bootnode subcommand * fmt corrections * Extend help message * Move boot_node crate * Update discv5 dep * Improve logging and boot-node logging Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
102
boot_node/src/config.rs
Normal file
102
boot_node/src/config.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use clap::ArgMatches;
|
||||
use discv5::{enr::CombinedKey, Enr};
|
||||
use std::convert::TryFrom;
|
||||
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
|
||||
|
||||
/// A set of configuration parameters for the bootnode, established from CLI arguments.
|
||||
pub struct BootNodeConfig {
|
||||
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,
|
||||
}
|
||||
|
||||
impl TryFrom<&ArgMatches<'_>> for BootNodeConfig {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(matches: &ArgMatches<'_>) -> Result<Self, Self::Error> {
|
||||
let listen_address = matches
|
||||
.value_of("listen-address")
|
||||
.expect("required parameter")
|
||||
.parse::<IpAddr>()
|
||||
.map_err(|_| format!("Invalid listening address"))?;
|
||||
|
||||
let listen_port = matches
|
||||
.value_of("port")
|
||||
.expect("required parameter")
|
||||
.parse::<u16>()
|
||||
.map_err(|_| format!("Invalid listening port"))?;
|
||||
|
||||
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>, _>>()?
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
};
|
||||
|
||||
let enr_port = {
|
||||
if let Some(port) = matches.value_of("boot-node-enr-port") {
|
||||
port.parse::<u16>()
|
||||
.map_err(|_| format!("Invalid ENR port"))?
|
||||
} else {
|
||||
listen_port
|
||||
}
|
||||
};
|
||||
|
||||
let enr_address = {
|
||||
let address_string = matches
|
||||
.value_of("boot-node-enr-address")
|
||||
.expect("required parameter");
|
||||
resolve_address(address_string.into(), enr_port)?
|
||||
};
|
||||
|
||||
let auto_update = matches.is_present("enable-enr_auto_update");
|
||||
|
||||
// the address to listen on
|
||||
let listen_socket = SocketAddr::new(listen_address.into(), enr_port);
|
||||
|
||||
// Generate a new key and build a new ENR
|
||||
let local_key = CombinedKey::generate_secp256k1();
|
||||
let local_enr = discv5::enr::EnrBuilder::new("v4")
|
||||
.ip(enr_address)
|
||||
.udp(enr_port)
|
||||
.build(&local_key)
|
||||
.map_err(|e| format!("Failed to build ENR: {:?}", e))?;
|
||||
|
||||
Ok(BootNodeConfig {
|
||||
listen_socket,
|
||||
boot_nodes,
|
||||
local_enr,
|
||||
local_key,
|
||||
auto_update,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves an IP/DNS string to an IpAddr.
|
||||
fn resolve_address(address_string: String, port: u16) -> Result<IpAddr, String> {
|
||||
match address_string.parse::<IpAddr>() {
|
||||
Ok(addr) => Ok(addr), // valid IpAddr
|
||||
Err(_) => {
|
||||
let mut addr = address_string.clone();
|
||||
// Appending enr-port to the dns hostname to appease `to_socket_addrs()` parsing.
|
||||
addr.push_str(&format!(":{}", port.to_string()));
|
||||
// `to_socket_addr()` does the dns resolution
|
||||
// Note: `to_socket_addrs()` is a blocking call
|
||||
addr.to_socket_addrs()
|
||||
.map(|mut resolved_addrs|
|
||||
// Pick the first ip from the list of resolved addresses
|
||||
resolved_addrs
|
||||
.next()
|
||||
.map(|a| a.ip())
|
||||
.ok_or_else(|| format!("Resolved dns addr contains no entries")))
|
||||
.map_err(|_| format!("Failed to parse enr-address: {}", address_string))?
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user