Skip to content

Commit

Permalink
Add deposit data to recover function
Browse files Browse the repository at this point in the history
  • Loading branch information
paulhauner committed Aug 15, 2022
1 parent fdc2fd5 commit 0e335bd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
2 changes: 1 addition & 1 deletion account_manager/src/validator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn cli_run<T: EthSpec>(matches: &ArgMatches, env: Environment<T>) -> Result<
(modify::CMD, Some(matches)) => modify::cli_run(matches, validator_base_dir),
(import::CMD, Some(matches)) => import::cli_run(matches, validator_base_dir),
(list::CMD, Some(_)) => list::cli_run(validator_base_dir),
(recover::CMD, Some(matches)) => recover::cli_run(matches, validator_base_dir),
(recover::CMD, Some(matches)) => recover::cli_run::<T>(matches, env, validator_base_dir),
(slashing_protection::CMD, Some(matches)) => {
slashing_protection::cli_run(matches, env, validator_base_dir)
}
Expand Down
53 changes: 51 additions & 2 deletions account_manager/src/validator/recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ use account_utils::random_password;
use clap::{App, Arg, ArgMatches};
use directory::ensure_dir_exists;
use directory::{parse_path_or_default_with_flag, DEFAULT_SECRET_DIR};
use environment::Environment;
use eth2_wallet::bip39::Seed;
use eth2_wallet::{recover_validator_secret_from_mnemonic, KeyType, ValidatorKeystores};
use std::fs;
use std::path::PathBuf;
use types::*;
use validator_dir::Builder as ValidatorDirBuilder;

pub const CMD: &str = "recover";
pub const FIRST_INDEX_FLAG: &str = "first-index";
pub const MNEMONIC_FLAG: &str = "mnemonic-path";
pub const JSON_DEPOSIT_DATA_PATH: &str = "json-deposit-data-path";

pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
App::new(CMD)
Expand Down Expand Up @@ -76,9 +81,26 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
.long(STDIN_INPUTS_FLAG)
.help("If present, read all user inputs from stdin instead of tty."),
)
.arg(
Arg::with_name(JSON_DEPOSIT_DATA_PATH)
.long(JSON_DEPOSIT_DATA_PATH)
.value_name("PATH")
.help(
"When provided, outputs a JSON file containing deposit data which \
is equivalent to the 'deposit-data-*.json' file used by the \
staking-deposit-cli tool.",
)
.takes_value(true),
)
}

pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), String> {
pub fn cli_run<T: EthSpec>(
matches: &ArgMatches,
mut env: Environment<T>,
validator_dir: PathBuf,
) -> Result<(), String> {
let spec = env.core_context().eth2_config.spec;

let secrets_dir = if matches.value_of("datadir").is_some() {
let path: PathBuf = clap_utils::parse_required(matches, "datadir")?;
path.join(DEFAULT_SECRET_DIR)
Expand All @@ -89,6 +111,8 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
let count: u32 = clap_utils::parse_required(matches, COUNT_FLAG)?;
let mnemonic_path: Option<PathBuf> = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?;
let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG);
let json_deposit_data_path: Option<PathBuf> =
clap_utils::parse_optional(matches, JSON_DEPOSIT_DATA_PATH)?;

eprintln!("secrets-dir path: {:?}", secrets_dir);

Expand All @@ -103,6 +127,8 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin

let seed = Seed::new(&mnemonic, "");

let mut json_deposit_data = Some(vec![]).filter(|_| json_deposit_data_path.is_some());

for index in first_index..first_index + count {
let voting_password = random_password();
let withdrawal_password = random_password();
Expand All @@ -128,14 +154,21 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin

let voting_pubkey = keystores.voting.pubkey().to_string();

ValidatorDirBuilder::new(validator_dir.clone())
let validator_dir = ValidatorDirBuilder::new(validator_dir.clone())
.password_dir(secrets_dir.clone())
.voting_keystore(keystores.voting, voting_password.as_bytes())
.withdrawal_keystore(keystores.withdrawal, withdrawal_password.as_bytes())
.store_withdrawal_keystore(matches.is_present(STORE_WITHDRAW_FLAG))
.build()
.map_err(|e| format!("Unable to build validator directory: {:?}", e))?;

if let Some(json_deposit_data) = &mut json_deposit_data {
let standard_deposit_data_json = validator_dir
.standard_deposit_data_json(&spec)
.map_err(|e| format!("Unable to create standard JSON deposit data: {:?}", e))?;
json_deposit_data.push(standard_deposit_data_json);
}

println!(
"{}/{}\tIndex: {}\t0x{}",
index - first_index,
Expand All @@ -145,5 +178,21 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
);
}

// If configured, create a single JSON file which contains deposit data information for all
// validators.
if let Some(json_deposit_data_path) = json_deposit_data_path {
let json_deposit_data =
json_deposit_data.ok_or("Internal error: JSON deposit data is None")?;

let mut file = fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(&json_deposit_data_path)
.map_err(|e| format!("Unable to create {:?}: {:?}", json_deposit_data_path, e))?;

serde_json::to_writer(&mut file, &json_deposit_data)
.map_err(|e| format!("Unable write JSON to {:?}: {:?}", json_deposit_data_path, e))?;
}

Ok(())
}

0 comments on commit 0e335bd

Please sign in to comment.