From a86a781fd549d426db10c5c7b5b6871ecfd67232 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2020 21:03:00 +0000 Subject: [PATCH] CLI: Print address ephemeral keypair seed phrase to stderr on deploy failure (bp #13046) (#13054) * CLI: Print address ephemeral keypair seed phrase to stderr on deploy failure (cherry picked from commit 2905ccc7ecc4633a36f38718b2cc1df5e8658e07) # Conflicts: # cli/Cargo.toml # cli/src/cli.rs * Fix conflicts Co-authored-by: Trent Nelson Co-authored-by: Tyera Eulberg --- Cargo.lock | 1 + cli/Cargo.toml | 1 + cli/src/cli.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5b04d6625..8ecf38b09b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3591,6 +3591,7 @@ dependencies = [ "solana_rbpf", "tempfile", "thiserror", + "tiny-bip39", "url 2.1.1", ] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a3610d10b6..a20d7c23f9 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -48,6 +48,7 @@ solana-version = { path = "../version", version = "1.3.19" } solana-vote-program = { path = "../programs/vote", version = "1.3.19" } solana-vote-signer = { path = "../vote-signer", version = "1.3.19" } thiserror = "1.0.20" +tiny-bip39 = "0.7.0" url = "2.1.1" [dev-dependencies] diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 89be10a0e6..e343b889cd 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -2,6 +2,7 @@ use crate::{ checks::*, cluster_query::*, feature::*, inflation::*, nonce::*, spend_utils::*, stake::*, validator_info::*, vote::*, }; +use bip39::{Language, Mnemonic, MnemonicType, Seed}; use chrono::prelude::*; use clap::{value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand}; use log::*; @@ -51,7 +52,7 @@ use solana_sdk::{ loader_instruction, message::Message, pubkey::{Pubkey, MAX_SEED_LEN}, - signature::{Keypair, Signature, Signer, SignerError}, + signature::{keypair_from_seed, Keypair, Signature, Signer, SignerError}, signers::Signers, system_instruction::{self, SystemError}, system_program, @@ -1240,7 +1241,48 @@ fn process_deploy( address: Option, use_deprecated_loader: bool, ) -> ProcessResult { - let new_keypair = Keypair::new(); // Create ephemeral keypair to use for program address, if not provided + const WORDS: usize = 12; + // Create ephemeral keypair to use for program address, if not provided + let mnemonic = Mnemonic::new(MnemonicType::for_word_count(WORDS)?, Language::English); + let seed = Seed::new(&mnemonic, ""); + let new_keypair = keypair_from_seed(seed.as_bytes())?; + + let result = do_process_deploy( + rpc_client, + config, + program_location, + address, + use_deprecated_loader, + new_keypair, + ); + + if result.is_err() && address.is_none() { + let phrase: &str = mnemonic.phrase(); + let divider = String::from_utf8(vec![b'='; phrase.len()]).unwrap(); + eprintln!( + "{}\nTo reuse this address, recover the ephemeral keypair file with", + divider + ); + eprintln!( + "`solana-keygen recover` and the following {}-word seed phrase,", + WORDS + ); + eprintln!( + "then pass it as the [ADDRESS_SIGNER] argument to `solana deploy ...`\n{}\n{}\n{}", + divider, phrase, divider + ); + } + result +} + +fn do_process_deploy( + rpc_client: &RpcClient, + config: &CliConfig, + program_location: &str, + address: Option, + use_deprecated_loader: bool, + new_keypair: Keypair, +) -> ProcessResult { let program_id = if let Some(i) = address { config.signers[i] } else { @@ -2617,7 +2659,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, ' .arg( Arg::with_name("address_signer") .index(2) - .value_name("SIGNER_KEYPAIR") + .value_name("ADDRESS_SIGNER") .takes_value(true) .validator(is_valid_signer) .help("The signer for the desired address of the program [default: new random address]")