diff --git a/validator_manager/src/create_validators.rs b/validator_manager/src/create_validators.rs index e83a50d54e6..cbd61886f42 100644 --- a/validator_manager/src/create_validators.rs +++ b/validator_manager/src/create_validators.rs @@ -26,6 +26,7 @@ pub const GAS_LIMIT_FLAG: &str = "gas-limit"; pub const FEE_RECIPIENT_FLAG: &str = "suggested-fee-recipient"; pub const BUILDER_PROPOSALS_FLAG: &str = "builder-proposals"; pub const BEACON_NODE_FLAG: &str = "beacon-node"; +pub const FORCE_BLS_WITHDRAWAL_CREDENTIALS: &str = "force-bls-withdrawal-credentials"; pub const VALIDATORS_FILENAME: &str = "validators.json"; pub const DEPOSITS_FILENAME: &str = "deposits.json"; @@ -173,6 +174,15 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .takes_value(true), ) + .arg( + Arg::with_name(FORCE_BLS_WITHDRAWAL_CREDENTIALS) + .takes_value(false) + .long(FORCE_BLS_WITHDRAWAL_CREDENTIALS) + .help( + "If present, allows BLS withdrawal credentials rather than an execution \ + address. This is not recommended.", + ), + ) } /// The CLI arguments are parsed into this struct before running the application. This step of @@ -192,6 +202,7 @@ pub struct CreateConfig { pub fee_recipient: Option
, pub gas_limit: Option, pub bn_url: Option, + pub force_bls_withdrawal_credentials: bool, } impl CreateConfig { @@ -215,6 +226,7 @@ impl CreateConfig { fee_recipient: clap_utils::parse_optional(matches, FEE_RECIPIENT_FLAG)?, gas_limit: clap_utils::parse_optional(matches, GAS_LIMIT_FLAG)?, bn_url: clap_utils::parse_optional(matches, BEACON_NODE_FLAG)?, + force_bls_withdrawal_credentials: matches.is_present(FORCE_BLS_WITHDRAWAL_CREDENTIALS), }) } } @@ -241,8 +253,17 @@ impl ValidatorsAndDeposits { fee_recipient, gas_limit, bn_url, + force_bls_withdrawal_credentials, } = config; + // Since Capella, it really doesn't make much sense to use BLS + // withdrawal credentials. Try to guide users away from doing so. + if eth1_withdrawal_address.is_none() && !force_bls_withdrawal_credentials { + return Err(format!( + "--{ETH1_WITHDRAWAL_ADDRESS_FLAG} is required. See --help for more information." + )); + } + if count == 0 { return Err(format!("--{} cannot be 0", COUNT_FLAG)); } @@ -524,6 +545,10 @@ pub mod tests { const TEST_VECTOR_DEPOSIT_CLI_VERSION: &str = "2.3.0"; + fn junk_execution_address() -> Option
{ + Some(Address::from_str("0x0f51bb10119727a7e5ea3538074fb341f56b09ad").unwrap()) + } + pub struct TestBuilder { spec: ChainSpec, output_dir: TempDir, @@ -557,11 +582,12 @@ pub mod tests { stdin_inputs: false, disable_deposits: false, specify_voting_keystore_password: false, - eth1_withdrawal_address: None, + eth1_withdrawal_address: junk_execution_address(), builder_proposals: None, fee_recipient: None, gas_limit: None, bn_url: None, + force_bls_withdrawal_credentials: false, }; Self { @@ -709,6 +735,30 @@ pub mod tests { TestBuilder::default().run_test().await.assert_ok(); } + #[tokio::test] + async fn no_eth1_address_without_force() { + TestBuilder::default() + .mutate_config(|config| { + config.eth1_withdrawal_address = None; + config.force_bls_withdrawal_credentials = false + }) + .run_test() + .await + .assert_err(); + } + + #[tokio::test] + async fn bls_withdrawal_credentials() { + TestBuilder::default() + .mutate_config(|config| { + config.eth1_withdrawal_address = None; + config.force_bls_withdrawal_credentials = true + }) + .run_test() + .await + .assert_ok(); + } + #[tokio::test] async fn default_test_values_deposits_disabled() { TestBuilder::default() @@ -732,8 +782,7 @@ pub mod tests { TestBuilder::default() .mutate_config(|config| { config.count = 2; - config.eth1_withdrawal_address = - Some(Address::from_str("0x0f51bb10119727a7e5ea3538074fb341f56b09ad").unwrap()); + config.eth1_withdrawal_address = junk_execution_address(); }) .run_test() .await @@ -822,6 +871,9 @@ pub mod tests { config.eth1_withdrawal_address = Some( Address::from_str("0x0f51bb10119727a7e5ea3538074fb341f56b09ad").unwrap(), ); + } else { + config.eth1_withdrawal_address = None; + config.force_bls_withdrawal_credentials = true; } }) .run_test()