mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 16:55:46 +00:00
Refactor beacon node CLI
This commit is contained in:
@@ -35,3 +35,4 @@ futures = "0.1.29"
|
|||||||
environment = { path = "../lighthouse/environment" }
|
environment = { path = "../lighthouse/environment" }
|
||||||
genesis = { path = "genesis" }
|
genesis = { path = "genesis" }
|
||||||
eth2_testnet = { path = "../eth2/utils/eth2_testnet" }
|
eth2_testnet = { path = "../eth2/utils/eth2_testnet" }
|
||||||
|
eth2-libp2p = { path = "./eth2-libp2p" }
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ impl Default for ClientGenesis {
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub data_dir: PathBuf,
|
pub data_dir: PathBuf,
|
||||||
pub db_type: String,
|
pub db_type: String,
|
||||||
db_name: String,
|
pub db_name: String,
|
||||||
freezer_db_path: Option<PathBuf>,
|
pub freezer_db_path: Option<PathBuf>,
|
||||||
pub log_file: PathBuf,
|
pub log_file: PathBuf,
|
||||||
pub spec_constants: String,
|
pub spec_constants: String,
|
||||||
/// If true, the node will use co-ordinated junk for eth1 values.
|
/// If true, the node will use co-ordinated junk for eth1 values.
|
||||||
@@ -69,7 +69,7 @@ impl Default for Config {
|
|||||||
db_name: "chain_db".to_string(),
|
db_name: "chain_db".to_string(),
|
||||||
freezer_db_path: None,
|
freezer_db_path: None,
|
||||||
genesis: <_>::default(),
|
genesis: <_>::default(),
|
||||||
network: NetworkConfig::new(),
|
network: NetworkConfig::default(),
|
||||||
rest_api: <_>::default(),
|
rest_api: <_>::default(),
|
||||||
websocket_server: <_>::default(),
|
websocket_server: <_>::default(),
|
||||||
spec_constants: TESTNET_SPEC_CONSTANTS.into(),
|
spec_constants: TESTNET_SPEC_CONSTANTS.into(),
|
||||||
@@ -135,26 +135,6 @@ impl Config {
|
|||||||
.ok_or_else(|| "Unable to locate user home directory".to_string())?;
|
.ok_or_else(|| "Unable to locate user home directory".to_string())?;
|
||||||
ensure_dir_exists(path)
|
ensure_dir_exists(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the following arguments to `self`, replacing values if they are specified in `args`.
|
|
||||||
///
|
|
||||||
/// Returns an error if arguments are obviously invalid. May succeed even if some values are
|
|
||||||
/// invalid.
|
|
||||||
pub fn apply_cli_args(&mut self, args: &ArgMatches, _log: &slog::Logger) -> Result<(), String> {
|
|
||||||
if let Some(dir) = args.value_of("datadir") {
|
|
||||||
self.data_dir = PathBuf::from(dir);
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(freezer_dir) = args.value_of("freezer-dir") {
|
|
||||||
self.freezer_db_path = Some(PathBuf::from(freezer_dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.network.apply_cli_args(args)?;
|
|
||||||
self.rest_api.apply_cli_args(args)?;
|
|
||||||
self.websocket_server.apply_cli_args(args)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that the directory at `path` exists, by creating it and all parents if necessary.
|
/// Ensure that the directory at `path` exists, by creating it and all parents if necessary.
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ authors = ["Age Manning <Age@AgeManning.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
|
||||||
hex = "0.3"
|
hex = "0.3"
|
||||||
# rust-libp2p is presently being sourced from a Sigma Prime fork of the
|
# rust-libp2p is presently being sourced from a Sigma Prime fork of the
|
||||||
# `libp2p/rust-libp2p` repository.
|
# `libp2p/rust-libp2p` repository.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use clap::ArgMatches;
|
|
||||||
use enr::Enr;
|
use enr::Enr;
|
||||||
use libp2p::gossipsub::{GossipsubConfig, GossipsubConfigBuilder};
|
use libp2p::gossipsub::{GossipsubConfig, GossipsubConfigBuilder};
|
||||||
use libp2p::Multiaddr;
|
use libp2p::Multiaddr;
|
||||||
@@ -97,84 +96,3 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a default Config.
|
|
||||||
impl Config {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Config::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_cli_args(&mut self, args: &ArgMatches) -> Result<(), String> {
|
|
||||||
// If a `datadir` has been specified, set the network dir to be inside it.
|
|
||||||
if let Some(dir) = args.value_of("datadir") {
|
|
||||||
self.network_dir = PathBuf::from(dir).join("network");
|
|
||||||
};
|
|
||||||
|
|
||||||
// If a network dir has been specified, override the `datadir` definition.
|
|
||||||
if let Some(dir) = args.value_of("network-dir") {
|
|
||||||
self.network_dir = PathBuf::from(dir);
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(listen_address_str) = args.value_of("listen-address") {
|
|
||||||
let listen_address = listen_address_str
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| format!("Invalid listen address: {:?}", listen_address_str))?;
|
|
||||||
self.listen_address = listen_address;
|
|
||||||
self.discovery_address = listen_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(max_peers_str) = args.value_of("maxpeers") {
|
|
||||||
self.max_peers = max_peers_str
|
|
||||||
.parse::<usize>()
|
|
||||||
.map_err(|_| format!("Invalid number of max peers: {}", max_peers_str))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(port_str) = args.value_of("port") {
|
|
||||||
let port = port_str
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| format!("Invalid port: {}", port_str))?;
|
|
||||||
self.libp2p_port = port;
|
|
||||||
self.discovery_port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(boot_enr_str) = args.value_of("boot-nodes") {
|
|
||||||
self.boot_nodes = boot_enr_str
|
|
||||||
.split(',')
|
|
||||||
.map(|enr| enr.parse().map_err(|_| format!("Invalid ENR: {}", enr)))
|
|
||||||
.collect::<Result<Vec<Enr>, _>>()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(libp2p_addresses_str) = args.value_of("libp2p-addresses") {
|
|
||||||
self.libp2p_nodes = libp2p_addresses_str
|
|
||||||
.split(',')
|
|
||||||
.map(|multiaddr| {
|
|
||||||
multiaddr
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| format!("Invalid Multiaddr: {}", multiaddr))
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<Multiaddr>, _>>()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(topics_str) = args.value_of("topics") {
|
|
||||||
self.topics = topics_str.split(',').map(|s| s.into()).collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(discovery_address_str) = args.value_of("discovery-address") {
|
|
||||||
self.discovery_address = discovery_address_str
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| format!("Invalid discovery address: {:?}", discovery_address_str))?
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(disc_port_str) = args.value_of("disc-port") {
|
|
||||||
self.discovery_port = disc_port_str
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| format!("Invalid discovery port: {}", disc_port_str))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(p2p_priv_key) = args.value_of("p2p-priv-key") {
|
|
||||||
self.secret_key_hex = Some(p2p_priv_key.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ eth2_ssz = { path = "../../eth2/utils/ssz" }
|
|||||||
eth2_ssz_derive = { path = "../../eth2/utils/ssz_derive" }
|
eth2_ssz_derive = { path = "../../eth2/utils/ssz_derive" }
|
||||||
state_processing = { path = "../../eth2/state_processing" }
|
state_processing = { path = "../../eth2/state_processing" }
|
||||||
types = { path = "../../eth2/types" }
|
types = { path = "../../eth2/types" }
|
||||||
clap = "2.33"
|
|
||||||
http = "0.1"
|
http = "0.1"
|
||||||
hyper = "0.12"
|
hyper = "0.12"
|
||||||
exit-future = "0.1.4"
|
exit-future = "0.1.4"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use clap::ArgMatches;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
@@ -50,25 +49,3 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
|
||||||
pub fn apply_cli_args(&mut self, args: &ArgMatches) -> Result<(), &'static str> {
|
|
||||||
if args.is_present("no-api") {
|
|
||||||
self.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(rpc_address) = args.value_of("api-address") {
|
|
||||||
self.listen_address = rpc_address
|
|
||||||
.parse::<Ipv4Addr>()
|
|
||||||
.map_err(|_| "api-address is not a valid IPv4 address.")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(rpc_port) = args.value_of("api-port") {
|
|
||||||
self.port = rpc_port
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| "api-port is not a valid u16.")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,20 +29,19 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
* Network parameters.
|
* Network parameters.
|
||||||
*/
|
*/
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("port-bump")
|
Arg::with_name("zero-ports")
|
||||||
.long("port-bump")
|
.long("zero-ports")
|
||||||
.short("b")
|
.short("z")
|
||||||
.value_name("INCREMENT")
|
.help("Sets all listening TCP/UDP ports to 0, allowing the OS to choose some \
|
||||||
.help("Sets all listening TCP/UDP ports to default values, but with each port increased by \
|
arbitrary free port number.")
|
||||||
INCREMENT. Useful when starting multiple nodes on a single machine. Using increments \
|
.takes_value(false),
|
||||||
in multiples of 10 is recommended.")
|
|
||||||
.takes_value(true),
|
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("listen-address")
|
Arg::with_name("listen-address")
|
||||||
.long("listen-address")
|
.long("listen-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("The address lighthouse will listen for UDP and TCP connections. (default 127.0.0.1).")
|
.help("The address lighthouse will listen for UDP and TCP connections.")
|
||||||
|
.default_value("127.0.0.1")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@@ -50,13 +49,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.long("port")
|
.long("port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The TCP/UDP port to listen on. The UDP port can be modified by the --discovery-port flag.")
|
.help("The TCP/UDP port to listen on. The UDP port can be modified by the --discovery-port flag.")
|
||||||
.conflicts_with("port-bump")
|
.default_value("9000")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("maxpeers")
|
Arg::with_name("maxpeers")
|
||||||
.long("maxpeers")
|
.long("maxpeers")
|
||||||
.help("The maximum number of peers (default 10).")
|
.help("The maximum number of peers.")
|
||||||
|
.default_value("10")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@@ -72,64 +72,70 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.long("disc-port")
|
.long("disc-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The discovery UDP port.")
|
.help("The discovery UDP port.")
|
||||||
.conflicts_with("port-bump")
|
.default_value("9000")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("discovery-address")
|
Arg::with_name("discovery-address")
|
||||||
.long("discovery-address")
|
.long("discovery-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("The IP address to broadcast to other peers on how to reach this node.")
|
.help("The IP address to broadcast to other peers on how to reach this node. \
|
||||||
|
Default is determined automatically.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("topics")
|
Arg::with_name("topics")
|
||||||
.long("topics")
|
.long("topics")
|
||||||
.value_name("STRING")
|
.value_name("STRING")
|
||||||
.help("One or more comma-delimited gossipsub topic strings to subscribe to.")
|
.help("One or more comma-delimited gossipsub topic strings to subscribe to. Default \
|
||||||
|
is determined automatically.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("libp2p-addresses")
|
Arg::with_name("libp2p-addresses")
|
||||||
.long("libp2p-addresses")
|
.long("libp2p-addresses")
|
||||||
.value_name("MULTIADDR")
|
.value_name("MULTIADDR")
|
||||||
.help("One or more comma-delimited multiaddrs to manually connect to a libp2p peer without an ENR.")
|
.help("One or more comma-delimited multiaddrs to manually connect to a libp2p peer \
|
||||||
|
without an ENR.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("p2p-priv-key")
|
Arg::with_name("p2p-priv-key")
|
||||||
.long("p2p-priv-key")
|
.long("p2p-priv-key")
|
||||||
.value_name("HEX")
|
.value_name("HEX")
|
||||||
.help("A secp256k1 secret key, represented as ASCII-encoded hex bytes (with or without 0x prefix).")
|
.help("A secp256k1 secret key, represented as ASCII-encoded hex bytes (with or \
|
||||||
|
without 0x prefix). Default is either loaded from disk or generated \
|
||||||
|
automatically.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
/* REST API related arguments */
|
/* REST API related arguments */
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("no-api")
|
Arg::with_name("http")
|
||||||
.long("no-api")
|
.long("http")
|
||||||
.help("Disable RESTful HTTP API server.")
|
.help("Enable RESTful HTTP API server. Disabled by default.")
|
||||||
.takes_value(false),
|
.takes_value(false),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("api-address")
|
Arg::with_name("http-address")
|
||||||
.long("api-address")
|
.long("http-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("Set the listen address for the RESTful HTTP API server.")
|
.help("Set the listen address for the RESTful HTTP API server.")
|
||||||
|
.default_value("127.0.0.1")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("api-port")
|
Arg::with_name("http-port")
|
||||||
.long("api-port")
|
.long("http-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("Set the listen TCP port for the RESTful HTTP API server.")
|
.help("Set the listen TCP port for the RESTful HTTP API server.")
|
||||||
.conflicts_with("port-bump")
|
.default_value("5052")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
/* Websocket related arguments */
|
/* Websocket related arguments */
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("no-ws")
|
Arg::with_name("ws")
|
||||||
.long("no-ws")
|
.long("ws")
|
||||||
.help("Disable websocket server.")
|
.help("Enable the websocket server. Disabled by default.")
|
||||||
.takes_value(false),
|
.takes_value(false),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@@ -137,7 +143,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.long("ws-address")
|
.long("ws-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("Set the listen address for the websocket server.")
|
.help("Set the listen address for the websocket server.")
|
||||||
.conflicts_with_all(&["no-ws"])
|
.default_value("127.0.0.1")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@@ -145,16 +151,24 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.long("ws-port")
|
.long("ws-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("Set the listen TCP port for the websocket server.")
|
.help("Set the listen TCP port for the websocket server.")
|
||||||
.conflicts_with_all(&["no-ws", "port-bump"])
|
.default_value("5053")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Eth1 Integration
|
* Eth1 Integration
|
||||||
*/
|
*/
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("eth1")
|
||||||
|
.long("eth1")
|
||||||
|
.help("If present the node will connect to an eth1 node. This is required for \
|
||||||
|
block production, you must use this flag if you wish to serve a validator.")
|
||||||
|
.takes_value(false),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("dummy-eth1")
|
Arg::with_name("dummy-eth1")
|
||||||
.long("dummy-eth1")
|
.long("dummy-eth1")
|
||||||
|
.conflicts_with("eth1")
|
||||||
.help("If present, uses an eth1 backend that generates static dummy data.\
|
.help("If present, uses an eth1 backend that generates static dummy data.\
|
||||||
Identical to the method used at the 2019 Canada interop.")
|
Identical to the method used at the 2019 Canada interop.")
|
||||||
)
|
)
|
||||||
@@ -166,32 +180,6 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("http://localhost:8545")
|
.default_value("http://localhost:8545")
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name("eth1-follow")
|
|
||||||
.long("eth1-follow")
|
|
||||||
.value_name("BLOCK_COUNT")
|
|
||||||
.help("Specifies how many blocks we should cache behind the eth1 head. A larger number means a smaller cache.")
|
|
||||||
.takes_value(true)
|
|
||||||
// TODO: set this higher once we're not using testnets all the time.
|
|
||||||
.default_value("0")
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("deposit-contract")
|
|
||||||
.long("deposit-contract")
|
|
||||||
.short("e")
|
|
||||||
.value_name("DEPOSIT-CONTRACT")
|
|
||||||
.help("Specifies the deposit contract address on the Eth1 chain.")
|
|
||||||
.takes_value(true)
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("deposit-contract-deploy")
|
|
||||||
.long("deposit-contract-deploy")
|
|
||||||
.value_name("BLOCK_NUMBER")
|
|
||||||
.help("Specifies the block number that the deposit contract was deployed at.")
|
|
||||||
.takes_value(true)
|
|
||||||
// TODO: set this higher once we're not using testnets all the time.
|
|
||||||
.default_value("0")
|
|
||||||
)
|
|
||||||
/*
|
/*
|
||||||
* The "testnet" sub-command.
|
* The "testnet" sub-command.
|
||||||
*
|
*
|
||||||
@@ -199,21 +187,6 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
*/
|
*/
|
||||||
.subcommand(SubCommand::with_name("testnet")
|
.subcommand(SubCommand::with_name("testnet")
|
||||||
.about("Create a new Lighthouse datadir using a testnet strategy.")
|
.about("Create a new Lighthouse datadir using a testnet strategy.")
|
||||||
.arg(
|
|
||||||
Arg::with_name("eth2-config")
|
|
||||||
.long("eth2-config")
|
|
||||||
.value_name("TOML_FILE")
|
|
||||||
.help("A existing eth2_spec TOML file (e.g., eth2_spec.toml).")
|
|
||||||
.takes_value(true)
|
|
||||||
.conflicts_with("spec")
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("client-config")
|
|
||||||
.long("client-config")
|
|
||||||
.value_name("TOML_FILE")
|
|
||||||
.help("An existing beacon_node TOML file (e.g., beacon_node.toml).")
|
|
||||||
.takes_value(true)
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("random-datadir")
|
Arg::with_name("random-datadir")
|
||||||
.long("random-datadir")
|
.long("random-datadir")
|
||||||
@@ -221,13 +194,6 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.help("If present, append a random string to the datadir path. Useful for fast development \
|
.help("If present, append a random string to the datadir path. Useful for fast development \
|
||||||
iteration.")
|
iteration.")
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name("random-propagation")
|
|
||||||
.long("random-propagation")
|
|
||||||
.value_name("INTEGER")
|
|
||||||
.takes_value(true)
|
|
||||||
.help("Specifies (as a percentage) the likelihood of propagating blocks and attestations. This should only be used for testing networking elements. The value must like in the range 1-100.")
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("force")
|
Arg::with_name("force")
|
||||||
.long("force")
|
.long("force")
|
||||||
@@ -236,33 +202,22 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
backup directory.")
|
backup directory.")
|
||||||
.conflicts_with("random-datadir")
|
.conflicts_with("random-datadir")
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("random-propagation")
|
||||||
|
.long("random-propagation")
|
||||||
|
.value_name("INTEGER")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("Specifies (as a percentage) the likelihood of propagating blocks and \
|
||||||
|
attestations. This should only be used for testing networking elements. The \
|
||||||
|
value must like in the range 1-100. Default is 100.")
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("slot-time")
|
Arg::with_name("slot-time")
|
||||||
.long("slot-time")
|
.long("slot-time")
|
||||||
.short("t")
|
.short("t")
|
||||||
.value_name("MILLISECONDS")
|
.value_name("MILLISECONDS")
|
||||||
.help("Defines the slot time when creating a new testnet.")
|
.help("Defines the slot time when creating a new testnet. The default is \
|
||||||
)
|
specified by the spec.")
|
||||||
/*
|
|
||||||
* `boostrap`
|
|
||||||
*
|
|
||||||
* Start a new node by downloading genesis and network info from another node via the
|
|
||||||
* HTTP API.
|
|
||||||
*/
|
|
||||||
.subcommand(SubCommand::with_name("bootstrap")
|
|
||||||
.about("Connects to the given HTTP server, downloads a genesis state and attempts to peer with it.")
|
|
||||||
.arg(Arg::with_name("server")
|
|
||||||
.value_name("HTTP_SERVER")
|
|
||||||
.required(true)
|
|
||||||
.default_value("http://localhost:5052")
|
|
||||||
.help("A HTTP server, with a http:// prefix"))
|
|
||||||
.arg(Arg::with_name("libp2p-port")
|
|
||||||
.short("p")
|
|
||||||
.long("port")
|
|
||||||
.value_name("TCP_PORT")
|
|
||||||
.help("A libp2p listen port used to peer with the bootstrap server. This flag is useful \
|
|
||||||
when port-fowarding is used: you may connect using a different port than \
|
|
||||||
the one the server is immediately listening on."))
|
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
* `recent`
|
* `recent`
|
||||||
@@ -282,7 +237,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.short("m")
|
.short("m")
|
||||||
.value_name("MINUTES")
|
.value_name("MINUTES")
|
||||||
.required(true)
|
.required(true)
|
||||||
.default_value("0")
|
.default_value("30")
|
||||||
.help("The maximum number of minutes that will have elapsed before genesis"))
|
.help("The maximum number of minutes that will have elapsed before genesis"))
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
@@ -320,25 +275,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.required(true)
|
.required(true)
|
||||||
.help("A file from which to read the state"))
|
.help("A file from which to read the state"))
|
||||||
)
|
)
|
||||||
/*
|
|
||||||
* `eth1`
|
|
||||||
*
|
|
||||||
* Connect to a Sigma Prime testnet.
|
|
||||||
*/
|
|
||||||
.subcommand(SubCommand::with_name("eth1")
|
|
||||||
.about("Connect to a testnet defined by an eth2_testnet directory.")
|
|
||||||
.arg(Arg::with_name("directory")
|
|
||||||
.value_name("DIRECTORY")
|
|
||||||
.index(1)
|
|
||||||
.help("A directory generated by lcli. Defaults to ~/.lighthouse/testnet. See lcli testnet --help"))
|
|
||||||
)
|
|
||||||
/*
|
/*
|
||||||
* `prysm`
|
* `prysm`
|
||||||
*
|
*
|
||||||
* Connect to the Prysmatic Labs testnet.
|
* Connect to the Prysmatic Labs testnet.
|
||||||
*/
|
*/
|
||||||
.subcommand(SubCommand::with_name("prysm")
|
.subcommand(SubCommand::with_name("prysm")
|
||||||
.about("Connect to the Prysmatic Labs testnet on Goerli.")
|
.about("Connect to the Prysmatic Labs testnet on Goerli. Not guaranteed to be \
|
||||||
|
up-to-date or functioning.")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -57,15 +57,15 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
|
|||||||
) -> impl Future<Item = Self, Error = String> + 'a {
|
) -> impl Future<Item = Self, Error = String> + 'a {
|
||||||
let log = context.log.clone();
|
let log = context.log.clone();
|
||||||
|
|
||||||
// TODO: the eth2 config in the env is being completely ignored.
|
// TODO: the eth2 config in the env is being modified.
|
||||||
//
|
//
|
||||||
// See https://github.com/sigp/lighthouse/issues/602
|
// See https://github.com/sigp/lighthouse/issues/602
|
||||||
get_configs(&matches, log).into_future().and_then(
|
get_configs(&matches, context.eth2_config.clone(), log)
|
||||||
move |(client_config, eth2_config, _log)| {
|
.into_future()
|
||||||
|
.and_then(move |(client_config, eth2_config, _log)| {
|
||||||
context.eth2_config = eth2_config;
|
context.eth2_config = eth2_config;
|
||||||
Self::new(context, client_config)
|
Self::new(context, client_config)
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a new beacon node `Client` in the given `environment`.
|
/// Starts a new beacon node `Client` in the given `environment`.
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
|
||||||
exit-future = "0.1.4"
|
exit-future = "0.1.4"
|
||||||
futures = "0.1.29"
|
futures = "0.1.29"
|
||||||
serde = "1.0.102"
|
serde = "1.0.102"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use clap::ArgMatches;
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
/// The core configuration of a Lighthouse beacon node.
|
/// The core configuration of a Lighthouse beacon node.
|
||||||
@@ -21,25 +20,3 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
|
||||||
pub fn apply_cli_args(&mut self, args: &ArgMatches) -> Result<(), &'static str> {
|
|
||||||
if args.is_present("no-ws") {
|
|
||||||
self.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(rpc_address) = args.value_of("ws-address") {
|
|
||||||
self.listen_address = rpc_address
|
|
||||||
.parse::<Ipv4Addr>()
|
|
||||||
.map_err(|_| "ws-address is not a valid IPv4 address.")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(rpc_port) = args.value_of("ws-port") {
|
|
||||||
self.port = rpc_port
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| "ws-port is not a valid u16.")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ tempdir = "0.3"
|
|||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "^1.0"
|
serde_json = "^1.0"
|
||||||
types = { path = "../../types"}
|
types = { path = "../../types"}
|
||||||
|
eth2-libp2p = { path = "../../../beacon_node/eth2-libp2p"}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
//!
|
//!
|
||||||
//! https://github.com/sigp/lighthouse/pull/605
|
//! https://github.com/sigp/lighthouse/pull/605
|
||||||
|
|
||||||
|
use eth2_libp2p::Enr;
|
||||||
use std::fs::{create_dir_all, File};
|
use std::fs::{create_dir_all, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use types::Address;
|
use types::Address;
|
||||||
@@ -14,12 +15,14 @@ use types::Address;
|
|||||||
pub const ADDRESS_FILE: &str = "deposit_contract.txt";
|
pub const ADDRESS_FILE: &str = "deposit_contract.txt";
|
||||||
pub const DEPLOY_BLOCK_FILE: &str = "deploy_block.txt";
|
pub const DEPLOY_BLOCK_FILE: &str = "deploy_block.txt";
|
||||||
pub const MIN_GENESIS_TIME_FILE: &str = "min_genesis_time.txt";
|
pub const MIN_GENESIS_TIME_FILE: &str = "min_genesis_time.txt";
|
||||||
|
pub const BOOT_NODES_FILE: &str = "boot_nodes.json";
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct Eth2TestnetDir {
|
pub struct Eth2TestnetDir {
|
||||||
deposit_contract_address: String,
|
deposit_contract_address: String,
|
||||||
pub deposit_contract_deploy_block: u64,
|
pub deposit_contract_deploy_block: u64,
|
||||||
pub min_genesis_time: u64,
|
pub min_genesis_time: u64,
|
||||||
|
pub boot_nodes: Vec<Enr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eth2TestnetDir {
|
impl Eth2TestnetDir {
|
||||||
@@ -28,6 +31,7 @@ impl Eth2TestnetDir {
|
|||||||
deposit_contract_address: String,
|
deposit_contract_address: String,
|
||||||
deposit_contract_deploy_block: u64,
|
deposit_contract_deploy_block: u64,
|
||||||
min_genesis_time: u64,
|
min_genesis_time: u64,
|
||||||
|
boot_nodes: Vec<Enr>,
|
||||||
) -> Result<Self, String> {
|
) -> Result<Self, String> {
|
||||||
if base_dir.exists() {
|
if base_dir.exists() {
|
||||||
return Err("Testnet directory already exists".to_string());
|
return Err("Testnet directory already exists".to_string());
|
||||||
@@ -36,60 +40,52 @@ impl Eth2TestnetDir {
|
|||||||
create_dir_all(&base_dir)
|
create_dir_all(&base_dir)
|
||||||
.map_err(|e| format!("Unable to create testnet directory: {:?}", e))?;
|
.map_err(|e| format!("Unable to create testnet directory: {:?}", e))?;
|
||||||
|
|
||||||
File::create(base_dir.join(ADDRESS_FILE))
|
macro_rules! write_to_file {
|
||||||
.map_err(|e| format!("Unable to create {}: {:?}", ADDRESS_FILE, e))
|
($file: ident, $variable: ident) => {
|
||||||
|
File::create(base_dir.join($file))
|
||||||
|
.map_err(|e| format!("Unable to create {}: {:?}", $file, e))
|
||||||
.and_then(|file| {
|
.and_then(|file| {
|
||||||
serde_json::to_writer(file, &deposit_contract_address)
|
serde_json::to_writer(file, &$variable)
|
||||||
.map_err(|e| format!("Unable to write {}: {:?}", ADDRESS_FILE, e))
|
.map_err(|e| format!("Unable to write {}: {:?}", $file, e))
|
||||||
})?;
|
})?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
File::create(base_dir.join(DEPLOY_BLOCK_FILE))
|
write_to_file!(ADDRESS_FILE, deposit_contract_address);
|
||||||
.map_err(|e| format!("Unable to create {}: {:?}", DEPLOY_BLOCK_FILE, e))
|
write_to_file!(DEPLOY_BLOCK_FILE, deposit_contract_deploy_block);
|
||||||
.and_then(|file| {
|
write_to_file!(MIN_GENESIS_TIME_FILE, min_genesis_time);
|
||||||
serde_json::to_writer(file, &deposit_contract_deploy_block)
|
write_to_file!(BOOT_NODES_FILE, boot_nodes);
|
||||||
.map_err(|e| format!("Unable to write {}: {:?}", DEPLOY_BLOCK_FILE, e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
File::create(base_dir.join(MIN_GENESIS_TIME_FILE))
|
|
||||||
.map_err(|e| format!("Unable to create {}: {:?}", MIN_GENESIS_TIME_FILE, e))
|
|
||||||
.and_then(|file| {
|
|
||||||
serde_json::to_writer(file, &min_genesis_time)
|
|
||||||
.map_err(|e| format!("Unable to write {}: {:?}", MIN_GENESIS_TIME_FILE, e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
deposit_contract_address,
|
deposit_contract_address,
|
||||||
deposit_contract_deploy_block,
|
deposit_contract_deploy_block,
|
||||||
min_genesis_time,
|
min_genesis_time,
|
||||||
|
boot_nodes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(base_dir: PathBuf) -> Result<Self, String> {
|
pub fn load(base_dir: PathBuf) -> Result<Self, String> {
|
||||||
let deposit_contract_address = File::open(base_dir.join(ADDRESS_FILE))
|
macro_rules! load_from_file {
|
||||||
.map_err(|e| format!("Unable to open {}: {:?}", ADDRESS_FILE, e))
|
($file: ident) => {
|
||||||
|
File::open(base_dir.join($file))
|
||||||
|
.map_err(|e| format!("Unable to open {}: {:?}", $file, e))
|
||||||
.and_then(|file| {
|
.and_then(|file| {
|
||||||
serde_json::from_reader(file)
|
serde_json::from_reader(file)
|
||||||
.map_err(|e| format!("Unable to parse {}: {:?}", ADDRESS_FILE, e))
|
.map_err(|e| format!("Unable to parse {}: {:?}", $file, e))
|
||||||
})?;
|
})?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let deposit_contract_deploy_block = File::open(base_dir.join(DEPLOY_BLOCK_FILE))
|
let deposit_contract_address = load_from_file!(ADDRESS_FILE);
|
||||||
.map_err(|e| format!("Unable to open {}: {:?}", DEPLOY_BLOCK_FILE, e))
|
let deposit_contract_deploy_block = load_from_file!(DEPLOY_BLOCK_FILE);
|
||||||
.and_then(|file| {
|
let min_genesis_time = load_from_file!(MIN_GENESIS_TIME_FILE);
|
||||||
serde_json::from_reader(file)
|
let boot_nodes = load_from_file!(BOOT_NODES_FILE);
|
||||||
.map_err(|e| format!("Unable to parse {}: {:?}", DEPLOY_BLOCK_FILE, e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let min_genesis_time = File::open(base_dir.join(MIN_GENESIS_TIME_FILE))
|
|
||||||
.map_err(|e| format!("Unable to open {}: {:?}", MIN_GENESIS_TIME_FILE, e))
|
|
||||||
.and_then(|file| {
|
|
||||||
serde_json::from_reader(file)
|
|
||||||
.map_err(|e| format!("Unable to parse {}: {:?}", MIN_GENESIS_TIME_FILE, e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
deposit_contract_address,
|
deposit_contract_address,
|
||||||
deposit_contract_deploy_block,
|
deposit_contract_deploy_block,
|
||||||
min_genesis_time,
|
min_genesis_time,
|
||||||
|
boot_nodes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +118,8 @@ mod tests {
|
|||||||
deposit_contract_address.clone(),
|
deposit_contract_address.clone(),
|
||||||
deposit_contract_deploy_block,
|
deposit_contract_deploy_block,
|
||||||
min_genesis_time,
|
min_genesis_time,
|
||||||
|
// TODO: add some Enr for testing.
|
||||||
|
vec![],
|
||||||
)
|
)
|
||||||
.expect("should create struct");
|
.expect("should create struct");
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ fn main() {
|
|||||||
.short("d")
|
.short("d")
|
||||||
.value_name("DIR")
|
.value_name("DIR")
|
||||||
.global(true)
|
.global(true)
|
||||||
.help("Data directory for keys and databases.")
|
.help("Data directory for lighthouse keys and databases.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.subcommand(beacon_node::cli_app())
|
.subcommand(beacon_node::cli_app())
|
||||||
|
|||||||
Reference in New Issue
Block a user