diff --git a/Cargo.lock b/Cargo.lock index 3941aa7ec3..3c0863bd3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3648,6 +3648,7 @@ dependencies = [ "unused_port", "validator_client", "validator_dir", + "validator_manager", ] [[package]] diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index b74e1516f4..3b0416cf0f 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -54,6 +54,7 @@ directory = { path = "../common/directory" } unused_port = { path = "../common/unused_port" } database_manager = { path = "../database_manager" } slasher = { path = "../slasher" } +validator_manager = { path = "../validator_manager" } [dev-dependencies] tempfile = "3.1.0" diff --git a/lighthouse/src/main.rs b/lighthouse/src/main.rs index 7897494cc4..89928f1edd 100644 --- a/lighthouse/src/main.rs +++ b/lighthouse/src/main.rs @@ -283,6 +283,7 @@ fn main() { .subcommand(validator_client::cli_app()) .subcommand(account_manager::cli_app()) .subcommand(database_manager::cli_app()) + .subcommand(validator_manager::cli_app()) .get_matches(); // Configure the allocator early in the process, before it has the chance to use the default values for @@ -498,6 +499,16 @@ fn run( return Ok(()); } + if let Some(sub_matches) = matches.subcommand_matches(account_manager::CMD) { + eprintln!("Running validator manager for {} network", network_name); + + // Pass the entire `environment` to the account manager so it can run blocking operations. + validator_manager::run(sub_matches, environment)?; + + // Exit as soon as account manager returns control. + return Ok(()); + } + if let Some(sub_matches) = matches.subcommand_matches(database_manager::CMD) { info!(log, "Running database manager for {} network", network_name); // Pass the entire `environment` to the database manager so it can run blocking operations. diff --git a/validator_manager/src/lib.rs b/validator_manager/src/lib.rs index 5507b5aaa0..add88991aa 100644 --- a/validator_manager/src/lib.rs +++ b/validator_manager/src/lib.rs @@ -15,19 +15,28 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { } /// Run the account manager, returning an error if the operation did not succeed. -pub async fn run<'a, T: EthSpec>( +pub fn run<'a, T: EthSpec>( matches: &'a ArgMatches<'a>, - env: Environment, + mut env: Environment, ) -> Result<(), String> { - match matches.subcommand() { - (validators::CMD, Some(matches)) => validators::cli_run(matches, env).await?, - (unknown, _) => { - return Err(format!( - "{} is not a valid {} command. See --help.", - unknown, CMD - )); - } - } + let context = env.core_context(); - Ok(()) + context + .executor + // This `block_on_dangerous` call reasonable since it is at the very highest level of the + // application, the rest of which is all async. All other functions below this should be + // async and should never call `block_on_dangerous` themselves. + .block_on_dangerous( + async { + match matches.subcommand() { + (validators::CMD, Some(matches)) => validators::cli_run(matches, env).await, + (unknown, _) => Err(format!( + "{} is not a valid {} command. See --help.", + unknown, CMD + )), + } + }, + "validator_manager", + ) + .ok_or("Shutting down")? }