-
Notifications
You must be signed in to change notification settings - Fork 992
[Merged by Bors] - Post merge local testnets #3807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
ad4c9d8
3bc7d64
d991078
26da254
b1dd81e
e949793
d4c39b6
002d57d
6878292
0756c25
df82d65
cebc86f
908193a
b9b74b7
bbdebc0
f1350b8
dca4dfa
724f619
3a9d2a9
47d019e
fa76fd7
9f9b3ac
585486a
1f44c51
6c59864
801ab3a
4850594
9273463
7554d84
5aa429a
567f496
ec848d2
a048c86
0a68641
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| use account_utils::eth2_keystore::{keypair_from_secret, Keystore, KeystoreBuilder}; | ||
| use account_utils::random_password; | ||
| use clap::ArgMatches; | ||
| use eth2_wallet::bip39::Seed; | ||
| use eth2_wallet::bip39::{Language, Mnemonic}; | ||
| use eth2_wallet::{recover_validator_secret_from_mnemonic, KeyType}; | ||
| use rayon::prelude::*; | ||
| use std::fs; | ||
| use std::path::PathBuf; | ||
| use validator_dir::Builder as ValidatorBuilder; | ||
|
|
||
| /// Generates validator directories with keys derived from the given mnemonic. | ||
| pub fn generate_validator_dirs( | ||
| indices: &[usize], | ||
| mnemonic_phrase: &str, | ||
| validators_dir: PathBuf, | ||
| secrets_dir: PathBuf, | ||
| ) -> Result<(), String> { | ||
| if !validators_dir.exists() { | ||
| fs::create_dir_all(&validators_dir) | ||
| .map_err(|e| format!("Unable to create validators dir: {:?}", e))?; | ||
| } | ||
|
|
||
| if !secrets_dir.exists() { | ||
| fs::create_dir_all(&secrets_dir) | ||
| .map_err(|e| format!("Unable to create secrets dir: {:?}", e))?; | ||
| } | ||
| let mnemonic = Mnemonic::from_phrase(mnemonic_phrase, Language::English).map_err(|e| { | ||
| format!( | ||
| "Unable to derive mnemonic from string {:?}: {:?}", | ||
| mnemonic_phrase, e | ||
| ) | ||
| })?; | ||
|
|
||
| let seed = Seed::new(&mnemonic, ""); | ||
|
|
||
| let _: Vec<_> = indices | ||
| .par_iter() | ||
| .map(|index| { | ||
| let voting_password = random_password(); | ||
|
|
||
| let derive = |key_type: KeyType, password: &[u8]| -> Result<Keystore, String> { | ||
| let (secret, path) = recover_validator_secret_from_mnemonic( | ||
| seed.as_bytes(), | ||
| *index as u32, | ||
| key_type, | ||
| ) | ||
| .map_err(|e| format!("Unable to recover validator keys: {:?}", e))?; | ||
|
|
||
| let keypair = keypair_from_secret(secret.as_bytes()) | ||
| .map_err(|e| format!("Unable build keystore: {:?}", e))?; | ||
|
|
||
| KeystoreBuilder::new(&keypair, password, format!("{}", path)) | ||
| .map_err(|e| format!("Unable build keystore: {:?}", e))? | ||
| .build() | ||
| .map_err(|e| format!("Unable build keystore: {:?}", e)) | ||
| }; | ||
|
|
||
| let voting_keystore = derive(KeyType::Voting, voting_password.as_bytes()).unwrap(); | ||
|
|
||
| println!("Validator {}", index + 1); | ||
|
|
||
| ValidatorBuilder::new(validators_dir.clone()) | ||
| .password_dir(secrets_dir.clone()) | ||
| .store_withdrawal_keystore(false) | ||
| .voting_keystore(voting_keystore, voting_password.as_bytes()) | ||
| .build() | ||
| .map_err(|e| format!("Unable to build validator: {:?}", e)) | ||
| .unwrap() | ||
| }) | ||
| .collect(); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| pub fn run(matches: &ArgMatches) -> Result<(), String> { | ||
| let validator_count: usize = clap_utils::parse_required(matches, "count")?; | ||
| let base_dir: PathBuf = clap_utils::parse_required(matches, "base-dir")?; | ||
| let node_count: Option<usize> = clap_utils::parse_optional(matches, "node-count")?; | ||
| let mnemonics_phrase: String = clap_utils::parse_required(matches, "mnemonics-phrase")?; | ||
| if let Some(node_count) = node_count { | ||
| let validators_per_node = validator_count / node_count; | ||
| let validator_range = (0..validator_count).collect::<Vec<_>>(); | ||
| let indices_range = validator_range | ||
| .chunks(validators_per_node) | ||
| .collect::<Vec<_>>(); | ||
|
|
||
| for (i, indices) in indices_range.iter().enumerate() { | ||
| let validators_dir = base_dir.join(format!("node_{}", i + 1)).join("validators"); | ||
| let secrets_dir = base_dir.join(format!("node_{}", i + 1)).join("secrets"); | ||
| generate_validator_dirs(indices, &mnemonics_phrase, validators_dir, secrets_dir)?; | ||
|
||
| } | ||
| } else { | ||
| let validators_dir = base_dir.join("validators"); | ||
| let secrets_dir = base_dir.join("secrets"); | ||
| generate_validator_dirs( | ||
| (0..validator_count).collect::<Vec<_>>().as_slice(), | ||
| &mnemonics_phrase, | ||
| validators_dir, | ||
| secrets_dir, | ||
| )?; | ||
| } | ||
| Ok(()) | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.