lighthouse/beacon_node/src/main.rs

253 lines
8.5 KiB
Rust
Raw Normal View History

mod run;
use clap::{App, Arg};
2019-06-08 17:17:03 +00:00
use client::{ClientConfig, Eth2Config};
2019-04-15 03:58:41 +00:00
use env_logger::{Builder, Env};
2019-07-01 06:38:42 +00:00
use eth2_config::{read_from_file, write_to_file};
use slog::{crit, o, Drain, Level};
2019-07-01 06:38:42 +00:00
use std::fs;
use std::path::PathBuf;
pub const DEFAULT_DATA_DIR: &str = ".lighthouse";
2019-06-09 10:41:51 +00:00
pub const CLIENT_CONFIG_FILENAME: &str = "beacon-node.toml";
2019-06-09 10:35:36 +00:00
pub const ETH2_CONFIG_FILENAME: &str = "eth2-spec.toml";
2019-06-08 17:17:03 +00:00
fn main() {
2019-04-15 03:58:41 +00:00
// debugging output for libp2p and external crates
Builder::from_env(Env::default()).init();
let matches = App::new("Lighthouse")
.version(version::version().as_str())
.author("Sigma Prime <contact@sigmaprime.io>")
.about("Eth 2.0 Client")
2019-04-01 01:14:44 +00:00
// file system related arguments
.arg(
Arg::with_name("datadir")
.long("datadir")
.value_name("DIR")
.help("Data directory for keys and databases.")
.takes_value(true)
)
2019-04-01 01:14:44 +00:00
// network related arguments
.arg(
2019-04-01 05:29:11 +00:00
Arg::with_name("listen-address")
2019-03-19 22:58:31 +00:00
.long("listen-address")
2019-06-25 08:02:11 +00:00
.value_name("Address")
.help("The address lighthouse will listen for UDP and TCP connections. (default 127.0.0.1).")
.takes_value(true),
)
2019-06-25 04:51:45 +00:00
.arg(
Arg::with_name("maxpeers")
.long("maxpeers")
2019-06-25 08:02:11 +00:00
.help("The maximum number of peers (default 10).")
2019-06-25 04:51:45 +00:00
.takes_value(true),
)
2019-04-01 01:14:44 +00:00
.arg(
Arg::with_name("boot-nodes")
.long("boot-nodes")
2019-06-25 04:51:45 +00:00
.allow_hyphen_values(true)
2019-04-01 01:14:44 +00:00
.value_name("BOOTNODES")
2019-06-25 04:51:45 +00:00
.help("One or more comma-delimited base64-encoded ENR's to bootstrap the p2p network.")
.takes_value(true),
)
.arg(
2019-06-25 08:02:11 +00:00
Arg::with_name("port")
.long("port")
.value_name("Lighthouse Port")
.help("The TCP/UDP port to listen on. The UDP port can be modified by the --discovery-port flag.")
2019-06-25 04:51:45 +00:00
.takes_value(true),
)
.arg(
Arg::with_name("discovery-port")
.long("disc-port")
2019-06-25 08:02:11 +00:00
.value_name("DiscoveryPort")
.help("The discovery UDP port.")
.takes_value(true),
)
.arg(
Arg::with_name("discovery-address")
.long("discovery-address")
.value_name("Address")
2019-07-01 06:38:42 +00:00
.help("The IP address to broadcast to other peers on how to reach this node.")
2019-04-01 01:14:44 +00:00
.takes_value(true),
)
// rpc related arguments
2019-03-19 13:01:00 +00:00
.arg(
Arg::with_name("rpc")
2019-03-19 22:58:31 +00:00
.long("rpc")
2019-03-19 13:01:00 +00:00
.value_name("RPC")
.help("Enable the RPC server.")
.takes_value(false),
)
.arg(
Arg::with_name("rpc-address")
2019-03-19 22:58:31 +00:00
.long("rpc-address")
2019-06-25 08:02:11 +00:00
.value_name("Address")
2019-03-19 13:01:00 +00:00
.help("Listen address for RPC endpoint.")
.takes_value(true),
)
.arg(
Arg::with_name("rpc-port")
2019-03-19 22:58:31 +00:00
.long("rpc-port")
2019-03-19 13:01:00 +00:00
.help("Listen port for RPC endpoint.")
.takes_value(true),
)
2019-05-28 03:50:51 +00:00
// HTTP related arguments
.arg(
Arg::with_name("http")
.long("http")
.help("Enable the HTTP server.")
.takes_value(false),
)
.arg(
Arg::with_name("http-address")
.long("http-address")
2019-06-25 08:02:11 +00:00
.value_name("Address")
2019-05-28 03:50:51 +00:00
.help("Listen address for the HTTP server.")
.takes_value(true),
)
.arg(
Arg::with_name("http-port")
.long("http-port")
.help("Listen port for the HTTP server.")
.takes_value(true),
)
.arg(
Arg::with_name("db")
.long("db")
.value_name("DB")
.help("Type of database to use.")
.takes_value(true)
2019-05-21 07:45:35 +00:00
.possible_values(&["disk", "memory"])
.default_value("memory"),
)
2019-06-08 17:17:03 +00:00
.arg(
Arg::with_name("spec-constants")
.long("spec-constants")
.value_name("TITLE")
.short("s")
.help("The title of the spec constants for chain config.")
.takes_value(true)
.possible_values(&["mainnet", "minimal"])
.default_value("minimal"),
)
.arg(
Arg::with_name("recent-genesis")
.long("recent-genesis")
.short("r")
2019-06-08 17:17:03 +00:00
.help("When present, genesis will be within 30 minutes prior. Only for testing"),
)
2019-04-15 01:29:08 +00:00
.arg(
Arg::with_name("verbosity")
.short("v")
.multiple(true)
.help("Sets the verbosity level")
.takes_value(true),
)
.get_matches();
2019-04-15 01:29:08 +00:00
// build the initial logger
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::CompactFormat::new(decorator).build().fuse();
let drain = slog_async::Async::new(drain).build();
let drain = match matches.occurrences_of("verbosity") {
0 => drain.filter_level(Level::Info),
1 => drain.filter_level(Level::Debug),
2 => drain.filter_level(Level::Trace),
_ => drain.filter_level(Level::Info),
};
2019-07-01 06:38:42 +00:00
let log = slog::Logger::root(drain.fuse(), o!());
2019-04-15 01:29:08 +00:00
2019-07-01 06:38:42 +00:00
let mut default_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
default_dir.push(DEFAULT_DATA_DIR);
let data_dir = &matches
.value_of("datadir")
.and_then(|v| Some(PathBuf::from(v)))
.unwrap_or_else(|| PathBuf::from(default_dir));
// create the directory if needed
match fs::create_dir_all(&data_dir) {
Ok(_) => {}
Err(e) => {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to initialize data dir"; "error" => format!("{}", e));
return;
}
2019-07-01 06:38:42 +00:00
}
let client_config_path = data_dir.join(CLIENT_CONFIG_FILENAME);
2019-04-15 01:29:08 +00:00
// Attempt to load the `ClientConfig` from disk.
//
// If file doesn't exist, create a new, default one.
let mut client_config = match read_from_file::<ClientConfig>(client_config_path.clone()) {
Ok(Some(c)) => c,
Ok(None) => {
let default = ClientConfig::default();
if let Err(e) = write_to_file(client_config_path, &default) {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to write default ClientConfig to file"; "error" => format!("{:?}", e));
return;
}
default
}
Err(e) => {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to load a ChainConfig file"; "error" => format!("{:?}", e));
return;
}
};
2019-06-07 23:44:27 +00:00
// Ensure the `data_dir` in the config matches that supplied to the CLI.
client_config.data_dir = data_dir.clone();
2019-06-08 17:17:03 +00:00
// Update the client config with any CLI args.
2019-06-08 17:17:03 +00:00
match client_config.apply_cli_args(&matches) {
Ok(()) => (),
Err(s) => {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to parse ClientConfig CLI arguments"; "error" => s);
2019-06-08 17:17:03 +00:00
return;
}
};
let eth2_config_path = data_dir.join(ETH2_CONFIG_FILENAME);
// Attempt to load the `Eth2Config` from file.
//
// If the file doesn't exist, create a default one depending on the CLI flags.
let mut eth2_config = match read_from_file::<Eth2Config>(eth2_config_path.clone()) {
Ok(Some(c)) => c,
Ok(None) => {
let default = match matches.value_of("spec-constants") {
Some("mainnet") => Eth2Config::mainnet(),
Some("minimal") => Eth2Config::minimal(),
_ => unreachable!(), // Guarded by slog.
};
if let Err(e) = write_to_file(eth2_config_path, &default) {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to write default Eth2Config to file"; "error" => format!("{:?}", e));
return;
}
default
}
2019-06-08 17:17:03 +00:00
Err(e) => {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to load/generate an Eth2Config"; "error" => format!("{:?}", e));
2019-06-08 17:17:03 +00:00
return;
}
};
// Update the eth2 config with any CLI flags.
2019-06-08 17:17:03 +00:00
match eth2_config.apply_cli_args(&matches) {
2019-06-07 23:44:27 +00:00
Ok(()) => (),
Err(s) => {
2019-07-01 06:38:42 +00:00
crit!(log, "Failed to parse Eth2Config CLI arguments"; "error" => s);
2019-06-07 23:44:27 +00:00
return;
}
};
2019-07-01 06:38:42 +00:00
match run::run_beacon_node(client_config, eth2_config, &log) {
2019-03-19 11:53:51 +00:00
Ok(_) => {}
2019-07-01 06:38:42 +00:00
Err(e) => crit!(log, "Beacon node failed to start"; "reason" => format!("{:}", e)),
2019-03-19 11:53:51 +00:00
}
}