2019-02-14 01:09:18 +00:00
|
|
|
extern crate slog;
|
|
|
|
|
2019-02-27 23:24:27 +00:00
|
|
|
mod run;
|
2019-02-14 01:09:18 +00:00
|
|
|
|
|
|
|
use clap::{App, Arg};
|
2019-06-08 17:17:03 +00:00
|
|
|
use client::{ClientConfig, Eth2Config};
|
2019-06-07 23:44:27 +00:00
|
|
|
use slog::{crit, o, Drain};
|
2019-06-08 01:00:34 +00:00
|
|
|
use std::fs;
|
|
|
|
use std::fs::File;
|
|
|
|
use std::io::prelude::*;
|
|
|
|
|
|
|
|
pub const DEFAULT_DATA_DIR: &str = ".lighthouse";
|
2019-02-14 01:09:18 +00:00
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
pub const CLIENT_CONFIG_FILENAME: &str = "client_config.toml";
|
|
|
|
pub const ETH2_CONFIG_FILENAME: &str = "eth2_config.toml";
|
|
|
|
|
2019-02-14 01:09:18 +00:00
|
|
|
fn main() {
|
|
|
|
let decorator = slog_term::TermDecorator::new().build();
|
|
|
|
let drain = slog_term::CompactFormat::new(decorator).build().fuse();
|
|
|
|
let drain = slog_async::Async::new(drain).build().fuse();
|
2019-02-27 23:24:27 +00:00
|
|
|
let logger = slog::Logger::root(drain, o!());
|
2019-02-14 01:09:18 +00:00
|
|
|
|
|
|
|
let matches = App::new("Lighthouse")
|
2019-02-27 23:24:27 +00:00
|
|
|
.version(version::version().as_str())
|
|
|
|
.author("Sigma Prime <contact@sigmaprime.io>")
|
2019-02-14 01:09:18 +00:00
|
|
|
.about("Eth 2.0 Client")
|
2019-04-01 01:14:44 +00:00
|
|
|
// file system related arguments
|
2019-02-14 01:09:18 +00:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("datadir")
|
|
|
|
.long("datadir")
|
|
|
|
.value_name("DIR")
|
|
|
|
.help("Data directory for keys and databases.")
|
2019-06-08 01:00:34 +00:00
|
|
|
.takes_value(true)
|
|
|
|
.default_value(DEFAULT_DATA_DIR),
|
2019-02-14 01:09:18 +00:00
|
|
|
)
|
2019-04-01 01:14:44 +00:00
|
|
|
// network related arguments
|
2019-02-27 23:24:27 +00:00
|
|
|
.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-02-27 23:24:27 +00:00
|
|
|
.value_name("Listen Address")
|
2019-06-07 23:44:27 +00:00
|
|
|
.help("One or more comma-delimited multi-addresses to listen for p2p connections.")
|
2019-02-14 01:09:18 +00:00
|
|
|
.takes_value(true),
|
|
|
|
)
|
2019-04-01 01:14:44 +00:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("boot-nodes")
|
|
|
|
.long("boot-nodes")
|
|
|
|
.value_name("BOOTNODES")
|
2019-06-07 23:44:27 +00:00
|
|
|
.help("One or more comma-delimited multi-addresses to bootstrap the p2p network.")
|
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-03-19 13:01:00 +00:00
|
|
|
.value_name("RPCADDRESS")
|
|
|
|
.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
|
|
|
.value_name("RPCPORT")
|
|
|
|
.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")
|
|
|
|
.value_name("HTTP")
|
|
|
|
.help("Enable the HTTP server.")
|
|
|
|
.takes_value(false),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("http-address")
|
|
|
|
.long("http-address")
|
|
|
|
.value_name("HTTPADDRESS")
|
|
|
|
.help("Listen address for the HTTP server.")
|
|
|
|
.takes_value(true),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::with_name("http-port")
|
|
|
|
.long("http-port")
|
|
|
|
.value_name("HTTPPORT")
|
|
|
|
.help("Listen port for the HTTP server.")
|
|
|
|
.takes_value(true),
|
|
|
|
)
|
2019-03-31 07:57:48 +00:00
|
|
|
.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"])
|
2019-03-31 07:57:48 +00:00
|
|
|
.default_value("memory"),
|
|
|
|
)
|
2019-06-08 17:17:03 +00:00
|
|
|
.arg(
|
|
|
|
Arg::with_name("recent_genesis")
|
|
|
|
.long("recent_genesis")
|
|
|
|
.help("When present, genesis will be within 30 minutes prior. Only for testing"),
|
|
|
|
)
|
2019-02-14 01:09:18 +00:00
|
|
|
.get_matches();
|
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
let mut client_config = match load_config::<ClientConfig>(
|
|
|
|
matches.value_of("data_dir"),
|
|
|
|
CLIENT_CONFIG_FILENAME,
|
|
|
|
) {
|
2019-06-08 01:00:34 +00:00
|
|
|
Ok(c) => c,
|
|
|
|
Err(e) => {
|
|
|
|
crit!(logger, "Failed to load/generate a ChainConfig"; "error" => format!("{:?}", e));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
2019-06-07 23:44:27 +00:00
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
if let Some(data_dir) = matches.value_of("data_dir") {
|
|
|
|
client_config.data_dir = data_dir.to_string();
|
|
|
|
}
|
|
|
|
|
|
|
|
match client_config.apply_cli_args(&matches) {
|
|
|
|
Ok(()) => (),
|
|
|
|
Err(s) => {
|
|
|
|
crit!(logger, "Failed to parse ClientConfig CLI arguments"; "error" => s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut eth2_config = match load_config::<Eth2Config>(
|
|
|
|
matches.value_of("data_dir"),
|
|
|
|
ETH2_CONFIG_FILENAME,
|
|
|
|
) {
|
|
|
|
Ok(c) => c,
|
|
|
|
Err(e) => {
|
|
|
|
crit!(logger, "Failed to load/generate an Eth2Config"; "error" => format!("{:?}", e));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
match eth2_config.apply_cli_args(&matches) {
|
2019-06-07 23:44:27 +00:00
|
|
|
Ok(()) => (),
|
|
|
|
Err(s) => {
|
2019-06-08 17:17:03 +00:00
|
|
|
crit!(logger, "Failed to parse Eth2Config CLI arguments"; "error" => s);
|
2019-06-07 23:44:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
2019-02-14 01:09:18 +00:00
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
match run::run_beacon_node(client_config, eth2_config, &logger) {
|
2019-03-19 11:53:51 +00:00
|
|
|
Ok(_) => {}
|
2019-06-07 23:44:27 +00:00
|
|
|
Err(e) => crit!(logger, "Beacon node failed to start"; "reason" => format!("{:}", e)),
|
2019-03-19 11:53:51 +00:00
|
|
|
}
|
2019-02-14 01:09:18 +00:00
|
|
|
}
|
2019-06-08 01:00:34 +00:00
|
|
|
|
|
|
|
/// Loads a `ClientConfig` from file. If unable to load from file, generates a default
|
|
|
|
/// configuration and saves that as a sample file.
|
2019-06-08 17:17:03 +00:00
|
|
|
fn load_config<T>(data_dir: Option<&str>, config_filename: &str) -> Result<T, String>
|
|
|
|
where
|
|
|
|
T: Default + serde::de::DeserializeOwned + serde::Serialize,
|
|
|
|
{
|
2019-06-08 01:00:34 +00:00
|
|
|
let data_dir = data_dir.unwrap_or_else(|| DEFAULT_DATA_DIR);
|
|
|
|
|
|
|
|
let path = dirs::home_dir()
|
|
|
|
.ok_or_else(|| "Unable to locate home directory")?
|
|
|
|
.join(&data_dir);
|
|
|
|
fs::create_dir_all(&path).map_err(|_| "Unable to open data_dir")?;
|
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
if let Ok(mut file) = File::open(path.join(config_filename)) {
|
2019-06-08 01:00:34 +00:00
|
|
|
let mut contents = String::new();
|
|
|
|
file.read_to_string(&mut contents).map_err(|e| {
|
|
|
|
format!(
|
|
|
|
"Unable to read existing {}. Error: {:?}",
|
2019-06-08 17:17:03 +00:00
|
|
|
config_filename, e
|
2019-06-08 01:00:34 +00:00
|
|
|
)
|
|
|
|
})?;
|
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
toml::from_str(&contents).map_err(|e| format!("Unable to parse {}: {:?}", config_filename, e))
|
2019-06-08 01:00:34 +00:00
|
|
|
} else {
|
2019-06-08 17:17:03 +00:00
|
|
|
let config = T::default();
|
2019-06-08 01:00:34 +00:00
|
|
|
|
2019-06-08 17:17:03 +00:00
|
|
|
if let Ok(mut file) = File::create(path.join(config_filename)) {
|
2019-06-08 01:00:34 +00:00
|
|
|
let toml_encoded = toml::to_string(&config).map_err(|e| {
|
|
|
|
format!(
|
|
|
|
"Failed to write configuration to {}. Error: {:?}",
|
2019-06-08 17:17:03 +00:00
|
|
|
config_filename, e
|
2019-06-08 01:00:34 +00:00
|
|
|
)
|
|
|
|
})?;
|
|
|
|
file.write_all(toml_encoded.as_bytes())
|
2019-06-08 17:17:03 +00:00
|
|
|
.expect(&format!("Unable to write to {}", config_filename));
|
2019-06-08 01:00:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(config)
|
|
|
|
}
|
|
|
|
}
|