From a7d1346d518db0e3df19ee75ea450045d38bcfb6 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Fri, 6 Mar 2020 22:22:23 -0700 Subject: [PATCH] Remove ask-seed-phrase arg from validator, archiver (#8697) * Remove ask-seed-phrase from validator * Update paper-wallet docs * Remove ask-seed-phrase from archiver * Remove unused structs, methods --- archiver/src/main.rs | 46 ++++++--------------- clap-utils/src/keypair.rs | 75 +--------------------------------- docs/src/paper-wallet/usage.md | 11 +++-- validator/src/main.rs | 55 +++++++------------------ 4 files changed, 32 insertions(+), 155 deletions(-) diff --git a/archiver/src/main.rs b/archiver/src/main.rs index df7c610600..9d95bf7eb6 100644 --- a/archiver/src/main.rs +++ b/archiver/src/main.rs @@ -2,21 +2,20 @@ use clap::{crate_description, crate_name, App, Arg}; use console::style; use solana_archiver_lib::archiver::Archiver; use solana_clap_utils::{ - input_validators::is_keypair, - keypair::{ - self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG, - SKIP_SEED_PHRASE_VALIDATION_ARG, - }, + input_parsers::keypair_of, input_validators::is_keypair_or_ask_keyword, + keypair::SKIP_SEED_PHRASE_VALIDATION_ARG, }; use solana_core::{ cluster_info::{Node, VALIDATOR_PORT_RANGE}, contact_info::ContactInfo, }; -use solana_sdk::{commitment_config::CommitmentConfig, signature::Signer}; +use solana_sdk::{ + commitment_config::CommitmentConfig, + signature::{Keypair, Signer}, +}; use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, - process::exit, sync::Arc, }; @@ -32,7 +31,7 @@ fn main() { .long("identity-keypair") .value_name("PATH") .takes_value(true) - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .help("File containing an identity (keypair)"), ) .arg( @@ -60,48 +59,27 @@ fn main() { .long("storage-keypair") .value_name("PATH") .takes_value(true) - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .help("File containing the storage account keypair"), ) - .arg( - Arg::with_name(ASK_SEED_PHRASE_ARG.name) - .long(ASK_SEED_PHRASE_ARG.long) - .value_name("KEYPAIR NAME") - .multiple(true) - .takes_value(true) - .possible_values(&["identity-keypair", "storage-keypair"]) - .help(ASK_SEED_PHRASE_ARG.help), - ) .arg( Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name) .long(SKIP_SEED_PHRASE_VALIDATION_ARG.long) - .requires(ASK_SEED_PHRASE_ARG.name) .help(SKIP_SEED_PHRASE_VALIDATION_ARG.help), ) .get_matches(); let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap()); - let identity_keypair = keypair_input(&matches, "identity_keypair") - .unwrap_or_else(|err| { - eprintln!("Identity keypair input failed: {}", err); - exit(1); - }) - .keypair; - let KeypairWithSource { - keypair: storage_keypair, - source: storage_keypair_source, - } = keypair_input(&matches, "storage_keypair").unwrap_or_else(|err| { - eprintln!("Storage keypair input failed: {}", err); - exit(1); - }); - if storage_keypair_source == keypair::Source::Generated { + let identity_keypair = keypair_of(&matches, "identity_keypair").unwrap_or_else(Keypair::new); + + let storage_keypair = keypair_of(&matches, "storage_keypair").unwrap_or_else(|| { clap::Error::with_description( "The `storage-keypair` argument was not found", clap::ErrorKind::ArgumentNotFound, ) .exit(); - } + }); let entrypoint_addr = matches .value_of("entrypoint") diff --git a/clap-utils/src/keypair.rs b/clap-utils/src/keypair.rs index 1de568d32f..ccfc0e1e61 100644 --- a/clap-utils/src/keypair.rs +++ b/clap-utils/src/keypair.rs @@ -4,7 +4,7 @@ use crate::{ ArgConstant, }; use bip39::{Language, Mnemonic, Seed}; -use clap::{values_t, ArgMatches, Error, ErrorKind}; +use clap::{ArgMatches, Error, ErrorKind}; use rpassword::prompt_password_stderr; use solana_remote_wallet::{ remote_keypair::generate_remote_keypair, @@ -113,36 +113,12 @@ pub fn signer_from_path( // Keyword used to indicate that the user should be asked for a keypair seed phrase pub const ASK_KEYWORD: &str = "ASK"; -pub const ASK_SEED_PHRASE_ARG: ArgConstant<'static> = ArgConstant { - long: "ask-seed-phrase", - name: "ask_seed_phrase", - help: "Recover a keypair using a seed phrase and optional passphrase", -}; - pub const SKIP_SEED_PHRASE_VALIDATION_ARG: ArgConstant<'static> = ArgConstant { long: "skip-seed-phrase-validation", name: "skip_seed_phrase_validation", help: "Skip validation of seed phrases. Use this if your phrase does not use the BIP39 official English word list", }; -#[derive(Debug, PartialEq)] -pub enum Source { - Generated, - Path, - SeedPhrase, -} - -pub struct KeypairWithSource { - pub keypair: Keypair, - pub source: Source, -} - -impl KeypairWithSource { - fn new(keypair: Keypair, source: Source) -> Self { - Self { keypair, source } - } -} - /// Prompts user for a passphrase and then asks for confirmirmation to check for mistakes pub fn prompt_passphrase(prompt: &str) -> Result> { let passphrase = prompt_password_stderr(&prompt)?; @@ -196,47 +172,6 @@ pub fn keypair_from_seed_phrase( Ok(keypair) } -/// Checks CLI arguments to determine whether a keypair should be: -/// - inputted securely via stdin, -/// - read in from a file, -/// - or newly generated -pub fn keypair_input( - matches: &clap::ArgMatches, - keypair_name: &str, -) -> Result> { - let ask_seed_phrase_matches = - values_t!(matches.values_of(ASK_SEED_PHRASE_ARG.name), String).unwrap_or_default(); - let keypair_match_name = keypair_name.replace('-', "_"); - if ask_seed_phrase_matches - .iter() - .any(|s| s.as_str() == keypair_name) - { - if matches.value_of(keypair_match_name).is_some() { - clap::Error::with_description( - &format!( - "`--{} {}` cannot be used with `{} `", - ASK_SEED_PHRASE_ARG.long, keypair_name, keypair_name - ), - clap::ErrorKind::ArgumentConflict, - ) - .exit(); - } - - let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name); - keypair_from_seed_phrase(keypair_name, skip_validation, true) - .map(|keypair| KeypairWithSource::new(keypair, Source::SeedPhrase)) - } else if let Some(keypair_file) = matches.value_of(keypair_match_name) { - if keypair_file.starts_with("usb://") { - Ok(KeypairWithSource::new(Keypair::new(), Source::Path)) - } else { - read_keypair_file(keypair_file) - .map(|keypair| KeypairWithSource::new(keypair, Source::Path)) - } - } else { - Ok(KeypairWithSource::new(Keypair::new(), Source::Generated)) - } -} - fn sanitize_seed_phrase(seed_phrase: &str) -> String { seed_phrase .split_whitespace() @@ -247,14 +182,6 @@ fn sanitize_seed_phrase(seed_phrase: &str) -> String { #[cfg(test)] mod tests { use super::*; - use clap::ArgMatches; - - #[test] - fn test_keypair_input() { - let arg_matches = ArgMatches::default(); - let KeypairWithSource { source, .. } = keypair_input(&arg_matches, "").unwrap(); - assert_eq!(source, Source::Generated); - } #[test] fn test_sanitize_seed_phrase() { diff --git a/docs/src/paper-wallet/usage.md b/docs/src/paper-wallet/usage.md index ab968b3e08..572710143d 100644 --- a/docs/src/paper-wallet/usage.md +++ b/docs/src/paper-wallet/usage.md @@ -233,21 +233,20 @@ done < public_keys.txt In order to run a validator, you will need to specify an "identity keypair" which will be used to fund all of the vote transactions signed by your validator. -Rather than specifying a path with `--identity-keypair ` you can use the -`--ask-seed-phrase` option. +Rather than specifying a path with `--identity-keypair ` you can pass +`ASK` to securely input the funding keypair. ```bash -solana-validator --ask-seed-phrase identity-keypair --ledger ... +solana-validator --identity-keypair ASK --ledger ... [identity-keypair] seed phrase: 🔒 [identity-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue: ``` -The `--ask-seed-phrase` option accepts multiple keypairs. If you wish to use this -input method for your voting keypair as well you can do the following: +You can use this input method for your voting keypair as well: ```bash -solana-validator --ask-seed-phrase identity-keypair voting-keypair --ledger ... +solana-validator --identity-keypair ASK --voting-keypair ASK --ledger ... [identity-keypair] seed phrase: 🔒 [identity-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue: diff --git a/validator/src/main.rs b/validator/src/main.rs index bfc9c37e53..c817651e11 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -7,12 +7,9 @@ use indicatif::{ProgressBar, ProgressStyle}; use log::*; use rand::{thread_rng, Rng}; use solana_clap_utils::{ - input_parsers::pubkey_of, - input_validators::{is_keypair, is_pubkey, is_pubkey_or_keypair, is_slot}, - keypair::{ - self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG, - SKIP_SEED_PHRASE_VALIDATION_ARG, - }, + input_parsers::{keypair_of, pubkey_of}, + input_validators::{is_keypair_or_ask_keyword, is_pubkey, is_pubkey_or_keypair, is_slot}, + keypair::SKIP_SEED_PHRASE_VALIDATION_ARG, }; use solana_client::rpc_client::RpcClient; use solana_core::ledger_cleanup_service::DEFAULT_MAX_LEDGER_SLOTS; @@ -553,19 +550,9 @@ pub fn main() { .value_name("UNIX DOMAIN SOCKET") .help("Stream entries to this unix domain socket path") ) - .arg( - Arg::with_name(ASK_SEED_PHRASE_ARG.name) - .long(ASK_SEED_PHRASE_ARG.long) - .value_name("KEYPAIR NAME") - .multiple(true) - .takes_value(true) - .possible_values(&["identity-keypair", "storage-keypair", "voting-keypair"]) - .help(ASK_SEED_PHRASE_ARG.help), - ) .arg( Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name) .long(SKIP_SEED_PHRASE_VALIDATION_ARG.long) - .requires(ASK_SEED_PHRASE_ARG.name) .help(SKIP_SEED_PHRASE_VALIDATION_ARG.help), ) .arg( @@ -574,7 +561,7 @@ pub fn main() { .long("identity-keypair") .value_name("PATH") .takes_value(true) - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .help("File containing the identity keypair for the validator"), ) .arg( @@ -582,7 +569,7 @@ pub fn main() { .long("voting-keypair") .value_name("PATH") .takes_value(true) - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .help("File containing the authorized voting keypair. Default is an ephemeral keypair, which may disable voting without --vote-account."), ) .arg( @@ -598,7 +585,7 @@ pub fn main() { .long("storage-keypair") .value_name("PATH") .takes_value(true) - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .help("File containing the storage account keypair. Default is an ephemeral keypair"), ) .arg( @@ -854,28 +841,14 @@ pub fn main() { ) .get_matches(); - let identity_keypair = Arc::new( - keypair_input(&matches, "identity-keypair") - .unwrap_or_else(|err| { - eprintln!("Identity keypair input failed: {}", err); - exit(1); - }) - .keypair, - ); - let KeypairWithSource { - keypair: voting_keypair, - source: voting_keypair_source, - } = keypair_input(&matches, "voting-keypair").unwrap_or_else(|err| { - eprintln!("Voting keypair input failed: {}", err); - exit(1); - }); - let ephemeral_voting_keypair = voting_keypair_source == keypair::Source::Generated; - let storage_keypair = keypair_input(&matches, "storage-keypair") - .unwrap_or_else(|err| { - eprintln!("Storage keypair input failed: {}", err); - exit(1); - }) - .keypair; + let identity_keypair = + Arc::new(keypair_of(&matches, "identity_keypair").unwrap_or_else(Keypair::new)); + + let (voting_keypair, ephemeral_voting_keypair) = keypair_of(&matches, "voting_keypair") + .map(|keypair| (keypair, false)) + .unwrap_or_else(|| (Keypair::new(), true)); + + let storage_keypair = keypair_of(&matches, "storage_keypair").unwrap_or_else(Keypair::new); let ledger_path = PathBuf::from(matches.value_of("ledger_path").unwrap()); let entrypoint = matches.value_of("entrypoint");