lighthouse/beacon_node/client/src/config.rs

157 lines
4.9 KiB
Rust
Raw Normal View History

2019-06-25 08:02:11 +00:00
use clap::ArgMatches;
use network::NetworkConfig;
use serde_derive::{Deserialize, Serialize};
use slog::{info, o, Drain};
2019-07-10 00:27:44 +00:00
use std::fs::{self, OpenOptions};
2019-06-25 08:02:11 +00:00
use std::path::PathBuf;
2019-07-10 00:27:44 +00:00
use std::sync::Mutex;
2019-06-25 08:02:11 +00:00
/// The number initial validators when starting the `Minimal`.
const TESTNET_SPEC_CONSTANTS: &str = "minimal";
2019-06-25 08:02:11 +00:00
/// The core configuration of a Lighthouse beacon node.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub data_dir: PathBuf,
pub db_type: String,
db_name: String,
2019-07-10 00:27:44 +00:00
pub log_file: PathBuf,
pub spec_constants: String,
/// Defines how we should initialize a BeaconChain instances.
///
/// This field is not serialized, there for it will not be written to (or loaded from) config
/// files. It can only be configured via the CLI.
2019-08-23 08:23:58 +00:00
#[serde(skip)]
pub beacon_chain_start_method: BeaconChainStartMethod,
2019-06-25 08:02:11 +00:00
pub network: network::NetworkConfig,
pub rpc: rpc::RPCConfig,
pub rest_api: rest_api::ApiConfig,
2019-06-25 08:02:11 +00:00
}
/// Defines how the client should initialize a BeaconChain.
///
/// In general, there are two methods:
/// - resuming a new chain, or
/// - initializing a new one.
2019-08-23 08:23:58 +00:00
#[derive(Debug, Clone)]
pub enum BeaconChainStartMethod {
/// Resume from an existing BeaconChain, loaded from the existing local database.
2019-08-23 08:23:58 +00:00
Resume,
/// Create a new beacon chain with `validator_count` validators, all with well-known secret keys.
2019-08-23 08:23:58 +00:00
///
/// Set the genesis time to be the start of the previous 30-minute window.
RecentGenesis { validator_count: usize },
/// Create a new beacon chain with `genesis_time` and `validator_count` validators, all with well-known
2019-08-23 08:23:58 +00:00
/// secret keys.
Generated {
validator_count: usize,
genesis_time: u64,
},
/// Create a new beacon chain by loading a YAML-encoded genesis state from a file.
2019-08-23 08:23:58 +00:00
Yaml { file: PathBuf },
/// Create a new beacon chain by using a HTTP server (running our REST-API) to load genesis and
/// finalized states and blocks.
2019-08-23 08:23:58 +00:00
HttpBootstrap {
server: String,
port: Option<String>,
},
}
impl Default for BeaconChainStartMethod {
2019-08-23 08:23:58 +00:00
fn default() -> Self {
BeaconChainStartMethod::Resume
2019-08-23 08:23:58 +00:00
}
}
2019-06-25 08:02:11 +00:00
impl Default for Config {
fn default() -> Self {
Self {
data_dir: PathBuf::from(".lighthouse"),
2019-07-10 00:27:44 +00:00
log_file: PathBuf::from(""),
2019-06-25 08:02:11 +00:00
db_type: "disk".to_string(),
db_name: "chain_db".to_string(),
network: NetworkConfig::new(),
rpc: <_>::default(),
rest_api: <_>::default(),
spec_constants: TESTNET_SPEC_CONSTANTS.into(),
beacon_chain_start_method: <_>::default(),
2019-06-25 08:02:11 +00:00
}
}
}
impl Config {
/// Returns the path to which the client may initialize an on-disk database.
pub fn db_path(&self) -> Option<PathBuf> {
self.data_dir()
.and_then(|path| Some(path.join(&self.db_name)))
}
/// Returns the core path for the client.
pub fn data_dir(&self) -> Option<PathBuf> {
let path = dirs::home_dir()?.join(&self.data_dir);
fs::create_dir_all(&path).ok()?;
Some(path)
}
2019-07-10 00:27:44 +00:00
// Update the logger to output in JSON to specified file
fn update_logger(&mut self, log: &mut slog::Logger) -> Result<(), &'static str> {
let file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&self.log_file);
if file.is_err() {
return Err("Cannot open log file");
}
let file = file.unwrap();
if let Some(file) = self.log_file.to_str() {
info!(
*log,
"Log file specified, output will now be written to {} in json.", file
);
} else {
info!(
*log,
"Log file specified output will now be written in json"
);
}
let drain = Mutex::new(slog_json::Json::default(file)).fuse();
let drain = slog_async::Async::new(drain).build().fuse();
*log = slog::Logger::root(drain, o!());
Ok(())
}
2019-06-25 08:02:11 +00:00
/// 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.
2019-07-10 00:27:44 +00:00
pub fn apply_cli_args(
&mut self,
args: &ArgMatches,
log: &mut slog::Logger,
) -> Result<(), String> {
2019-06-25 08:02:11 +00:00
if let Some(dir) = args.value_of("datadir") {
self.data_dir = PathBuf::from(dir);
};
if let Some(dir) = args.value_of("db") {
self.db_type = dir.to_string();
2019-07-10 00:27:44 +00:00
};
2019-06-25 08:02:11 +00:00
self.network.apply_cli_args(args)?;
self.rpc.apply_cli_args(args)?;
First RESTful HTTP API (#399) * Added generated code for REST API. - Created a new crate rest_api, which will adapt the openapi generated code to Lighthouse - Committed automatically generated code from openapi-generator-cli (via docker). Should hopfully not have to modify this at all, and do all changes in the rest_api crate. * Removed openapi generated code, because it was the rust client, not the rust server. * Added the correct rust-server code, automatically generated from openapi. * Added generated code for REST API. - Created a new crate rest_api, which will adapt the openapi generated code to Lighthouse - Committed automatically generated code from openapi-generator-cli (via docker). Should hopfully not have to modify this at all, and do all changes in the rest_api crate. * Removed openapi generated code, because it was the rust client, not the rust server. * Added the correct rust-server code, automatically generated from openapi. * Included REST API in configuratuion. - Started adding the rest_api into the beacon node's dependencies. - Set up configuration file for rest_api and integrated into main client config - Added CLI flags for REST API. * Futher work on REST API. - Adding the dependencies to rest_api crate - Created a skeleton BeaconNodeService, which will handle /node requests. - Started the rest_api server definition, with the high level request handling logic. * Added generated code for REST API. - Created a new crate rest_api, which will adapt the openapi generated code to Lighthouse - Committed automatically generated code from openapi-generator-cli (via docker). Should hopfully not have to modify this at all, and do all changes in the rest_api crate. * Removed openapi generated code, because it was the rust client, not the rust server. * Added the correct rust-server code, automatically generated from openapi. * Included REST API in configuratuion. - Started adding the rest_api into the beacon node's dependencies. - Set up configuration file for rest_api and integrated into main client config - Added CLI flags for REST API. * Futher work on REST API. - Adding the dependencies to rest_api crate - Created a skeleton BeaconNodeService, which will handle /node requests. - Started the rest_api server definition, with the high level request handling logic. * WIP: Restructured REST API to use hyper_router and separate services. * WIP: Fixing rust for REST API * WIP: Fixed up many bugs in trying to get router to compile. * WIP: Got the beacon_node to compile with the REST changes * Basic API works! - Changed CLI flags from rest-api* to api* - Fixed port cli flag - Tested, works over HTTP * WIP: Moved things around so that we can get state inside the handlers. * WIP: Significant API updates. - Started writing a macro for getting the handler functions. - Added the BeaconChain into the type map, gives stateful access to the beacon state. - Created new generic error types (haven't figured out yet), to reduce code duplication. - Moved common stuff into lib.rs * WIP: Factored macros, defined API result and error. - did more logging when creating HTTP responses - Tried moving stuff into macros, but can't get macros in macros to compile. - Pulled out a lot of placeholder code. * Fixed macros so that things compile. * Cleaned up code. - Removed unused imports - Removed comments - Addressed all compiler warnings. - Ran cargo fmt. * Removed auto-generated OpenAPI code. * Addressed Paul's suggestions. - Fixed spelling mistake - Moved the simple macros into functions, since it doesn't make sense for them to be macros. - Removed redundant code & inclusions. * Removed redundant validate_request function. * Included graceful shutdown in Hyper server. * Fixing the dropped exit_signal, which prevented the API from starting. * Wrapped the exit signal, to get an API shutdown log line.
2019-07-31 08:29:41 +00:00
self.rest_api.apply_cli_args(args)?;
2019-06-25 08:02:11 +00:00
2019-07-10 00:27:44 +00:00
if let Some(log_file) = args.value_of("logfile") {
self.log_file = PathBuf::from(log_file);
self.update_logger(log)?;
};
2019-06-25 08:02:11 +00:00
Ok(())
}
}