mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-19 13:58:28 +00:00
Add DumpConfigs
This commit is contained in:
@@ -1,12 +1,36 @@
|
|||||||
use clap::App;
|
use clap::App;
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use environment::Environment;
|
use environment::Environment;
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::path::PathBuf;
|
||||||
use types::EthSpec;
|
use types::EthSpec;
|
||||||
|
use validators::create_validators::write_to_json_file;
|
||||||
|
|
||||||
mod validators;
|
mod validators;
|
||||||
|
|
||||||
pub const CMD: &str = "validator_manager";
|
pub const CMD: &str = "validator_manager";
|
||||||
|
|
||||||
|
/// This flag is on the top-level `lighthouse` binary.
|
||||||
|
const DUMP_CONFIGS_FLAG: &str = "dump-configs";
|
||||||
|
|
||||||
|
/// Used only in testing, this allows a command to dump its configuration to a file and then exit
|
||||||
|
/// successfully. This allows for testing how the CLI arguments translate to some configuration.
|
||||||
|
pub enum DumpConfigs {
|
||||||
|
Disabled,
|
||||||
|
Enabled(PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DumpConfigs {
|
||||||
|
/// Returns `Ok(true)` if the configuration was successfully written to a file and the
|
||||||
|
/// application should exit successfully without doing anything else.
|
||||||
|
pub fn should_exit_early<T: Serialize>(&self, config: &T) -> Result<bool, String> {
|
||||||
|
match self {
|
||||||
|
DumpConfigs::Disabled => Ok(false),
|
||||||
|
DumpConfigs::Enabled(dump_path) => write_to_json_file(dump_path, config).map(|()| true),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||||
App::new(CMD)
|
App::new(CMD)
|
||||||
.visible_aliases(&["vm", CMD])
|
.visible_aliases(&["vm", CMD])
|
||||||
@@ -21,6 +45,9 @@ pub fn run<'a, T: EthSpec>(
|
|||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let context = env.core_context();
|
let context = env.core_context();
|
||||||
let spec = context.eth2_config.spec.clone();
|
let spec = context.eth2_config.spec.clone();
|
||||||
|
let dump_configs = clap_utils::parse_optional(matches, DUMP_CONFIGS_FLAG)?
|
||||||
|
.map(DumpConfigs::Enabled)
|
||||||
|
.unwrap_or_else(|| DumpConfigs::Disabled);
|
||||||
|
|
||||||
context
|
context
|
||||||
.executor
|
.executor
|
||||||
@@ -31,7 +58,7 @@ pub fn run<'a, T: EthSpec>(
|
|||||||
async {
|
async {
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
(validators::CMD, Some(matches)) => {
|
(validators::CMD, Some(matches)) => {
|
||||||
validators::cli_run::<T>(matches, &spec).await
|
validators::cli_run::<T>(matches, &spec, dump_configs).await
|
||||||
}
|
}
|
||||||
(unknown, _) => Err(format!(
|
(unknown, _) => Err(format!(
|
||||||
"{} is not a valid {} command. See --help.",
|
"{} is not a valid {} command. See --help.",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::common::*;
|
use super::common::*;
|
||||||
|
use crate::DumpConfigs;
|
||||||
use account_utils::{random_password_string, read_mnemonic_from_cli, read_password_from_user};
|
use account_utils::{random_password_string, read_mnemonic_from_cli, read_password_from_user};
|
||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{App, Arg, ArgMatches};
|
||||||
use eth2::{
|
use eth2::{
|
||||||
@@ -7,7 +8,7 @@ use eth2::{
|
|||||||
BeaconNodeHttpClient, SensitiveUrl, Timeouts,
|
BeaconNodeHttpClient, SensitiveUrl, Timeouts,
|
||||||
};
|
};
|
||||||
use eth2_wallet::WalletBuilder;
|
use eth2_wallet::WalletBuilder;
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -180,7 +181,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
|
|
||||||
/// The CLI arguments are parsed into this struct before running the application. This step of
|
/// The CLI arguments are parsed into this struct before running the application. This step of
|
||||||
/// indirection allows for testing the underlying logic without needing to parse CLI arguments.
|
/// indirection allows for testing the underlying logic without needing to parse CLI arguments.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct CreateConfig {
|
pub struct CreateConfig {
|
||||||
pub output_path: PathBuf,
|
pub output_path: PathBuf,
|
||||||
pub first_index: u32,
|
pub first_index: u32,
|
||||||
@@ -460,9 +461,14 @@ impl ValidatorsAndDeposits {
|
|||||||
pub async fn cli_run<'a, T: EthSpec>(
|
pub async fn cli_run<'a, T: EthSpec>(
|
||||||
matches: &'a ArgMatches<'a>,
|
matches: &'a ArgMatches<'a>,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
|
dump_configs: DumpConfigs,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let config = CreateConfig::from_cli(matches, spec)?;
|
let config = CreateConfig::from_cli(matches, spec)?;
|
||||||
run::<T>(config, spec).await
|
if dump_configs.should_exit_early(&config)? {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
run::<T>(config, spec).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run<'a, T: EthSpec>(config: CreateConfig, spec: &ChainSpec) -> Result<(), String> {
|
async fn run<'a, T: EthSpec>(config: CreateConfig, spec: &ChainSpec) -> Result<(), String> {
|
||||||
@@ -506,7 +512,10 @@ async fn run<'a, T: EthSpec>(config: CreateConfig, spec: &ChainSpec) -> Result<(
|
|||||||
/// Write some object to a file as JSON.
|
/// Write some object to a file as JSON.
|
||||||
///
|
///
|
||||||
/// The file must be created new, it must not already exist.
|
/// The file must be created new, it must not already exist.
|
||||||
fn write_to_json_file<P: AsRef<Path>, S: Serialize>(path: P, contents: &S) -> Result<(), String> {
|
pub fn write_to_json_file<P: AsRef<Path>, S: Serialize>(
|
||||||
|
path: P,
|
||||||
|
contents: &S,
|
||||||
|
) -> Result<(), String> {
|
||||||
eprintln!("Writing {:?}", path.as_ref());
|
eprintln!("Writing {:?}", path.as_ref());
|
||||||
let mut file = fs::OpenOptions::new()
|
let mut file = fs::OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::common::*;
|
use super::common::*;
|
||||||
|
use crate::DumpConfigs;
|
||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{App, Arg, ArgMatches};
|
||||||
use eth2::{
|
use eth2::{
|
||||||
lighthouse_vc::{
|
lighthouse_vc::{
|
||||||
@@ -7,6 +8,7 @@ use eth2::{
|
|||||||
},
|
},
|
||||||
SensitiveUrl,
|
SensitiveUrl,
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
struct ImportConfig {
|
struct ImportConfig {
|
||||||
validators_file_path: PathBuf,
|
validators_file_path: PathBuf,
|
||||||
vc_url: SensitiveUrl,
|
vc_url: SensitiveUrl,
|
||||||
@@ -91,9 +93,16 @@ impl ImportConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cli_run<'a>(matches: &'a ArgMatches<'a>) -> Result<(), String> {
|
pub async fn cli_run<'a>(
|
||||||
|
matches: &'a ArgMatches<'a>,
|
||||||
|
dump_configs: DumpConfigs,
|
||||||
|
) -> Result<(), String> {
|
||||||
let config = ImportConfig::from_cli(matches)?;
|
let config = ImportConfig::from_cli(matches)?;
|
||||||
run(config).await
|
if dump_configs.should_exit_early(&config)? {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
run(config).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run<'a>(config: ImportConfig) -> Result<(), String> {
|
async fn run<'a>(config: ImportConfig) -> Result<(), String> {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ pub mod common;
|
|||||||
pub mod create_validators;
|
pub mod create_validators;
|
||||||
pub mod import_validators;
|
pub mod import_validators;
|
||||||
|
|
||||||
|
use crate::DumpConfigs;
|
||||||
use clap::{App, ArgMatches};
|
use clap::{App, ArgMatches};
|
||||||
use types::{ChainSpec, EthSpec};
|
use types::{ChainSpec, EthSpec};
|
||||||
|
|
||||||
@@ -17,12 +18,15 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
pub async fn cli_run<'a, T: EthSpec>(
|
pub async fn cli_run<'a, T: EthSpec>(
|
||||||
matches: &'a ArgMatches<'a>,
|
matches: &'a ArgMatches<'a>,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
|
dump_configs: DumpConfigs,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
(create_validators::CMD, Some(matches)) => {
|
(create_validators::CMD, Some(matches)) => {
|
||||||
create_validators::cli_run::<T>(matches, spec).await
|
create_validators::cli_run::<T>(matches, spec, dump_configs).await
|
||||||
|
}
|
||||||
|
(import_validators::CMD, Some(matches)) => {
|
||||||
|
import_validators::cli_run(matches, dump_configs).await
|
||||||
}
|
}
|
||||||
(import_validators::CMD, Some(matches)) => import_validators::cli_run(matches).await,
|
|
||||||
(unknown, _) => Err(format!(
|
(unknown, _) => Err(format!(
|
||||||
"{} does not have a {} command. See --help",
|
"{} does not have a {} command. See --help",
|
||||||
CMD, unknown
|
CMD, unknown
|
||||||
|
|||||||
Reference in New Issue
Block a user