use account_utils::validator_definitions::ValidatorDefinitions; use bls::PublicKey; use clap::{Arg, ArgAction, ArgMatches, Command}; use clap_utils::FLAG_HEADER; use std::{collections::HashSet, path::PathBuf}; pub const CMD: &str = "modify"; pub const ENABLE: &str = "enable"; pub const DISABLE: &str = "disable"; pub const PUBKEY_FLAG: &str = "pubkey"; pub const ALL: &str = "all"; pub fn cli_app() -> Command { Command::new(CMD) .about("Modify validator status in validator_definitions.yml.") .display_order(0) .subcommand( Command::new(ENABLE) .about("Enable validator(s) in validator_definitions.yml.") .arg( Arg::new(PUBKEY_FLAG) .long(PUBKEY_FLAG) .value_name("PUBKEY") .help("Validator pubkey to enable") .action(ArgAction::Set) .display_order(0), ) .arg( Arg::new(ALL) .long(ALL) .help("Enable all validators in the validator directory") .action(ArgAction::SetTrue) .help_heading(FLAG_HEADER) .conflicts_with(PUBKEY_FLAG) .display_order(0), ), ) .subcommand( Command::new(DISABLE) .about("Disable validator(s) in validator_definitions.yml.") .arg( Arg::new(PUBKEY_FLAG) .long(PUBKEY_FLAG) .value_name("PUBKEY") .help("Validator pubkey to disable") .action(ArgAction::Set) .display_order(0), ) .arg( Arg::new(ALL) .long(ALL) .help("Disable all validators in the validator directory") .action(ArgAction::SetTrue) .help_heading(FLAG_HEADER) .conflicts_with(PUBKEY_FLAG) .display_order(0), ), ) } pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), String> { // `true` implies we are setting `validator_definition.enabled = true` and // vice versa. let (enabled, sub_matches) = match matches.subcommand() { Some((ENABLE, sub_matches)) => (true, sub_matches), Some((DISABLE, sub_matches)) => (false, sub_matches), Some((unknown, _)) => { return Err(format!( "{} does not have a {} command. See --help", CMD, unknown )); } _ => return Err(format!("No command provided for {}. See --help", CMD)), }; let mut defs = ValidatorDefinitions::open(&validator_dir).map_err(|e| { format!( "No validator definitions found in {:?}: {:?}", validator_dir, e ) })?; let pubkeys_to_modify = if sub_matches.get_flag(ALL) { defs.as_slice() .iter() .map(|def| def.voting_public_key.clone()) .collect::>() } else { let public_key: PublicKey = clap_utils::parse_required(sub_matches, PUBKEY_FLAG)?; std::iter::once(public_key).collect::>() }; // Modify required entries from validator_definitions. for def in defs.as_mut_slice() { if pubkeys_to_modify.contains(&def.voting_public_key) { def.enabled = enabled; eprintln!( "Validator {} {}", def.voting_public_key, if enabled { "enabled" } else { "disabled" } ); } } defs.save(&validator_dir) .map_err(|e| format!("Unable to modify validator definitions: {:?}", e))?; eprintln!("\nSuccessfully modified validator_definitions.yml"); Ok(()) }