Fix printing of subkey when using the --network override (#6932)

* Fix printing of subkey when using the `--network` override

This fixes a bug where `--network` did not printed the account ss58 address for the
requested network. Basically we now always print all account ss58 addresses using the
requested network.

* Review comments

* Fixes test

* Update client/cli/src/commands/inspect.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update client/cli/src/commands/utils.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Fix more tests

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Bastian Köcher
2020-08-22 14:53:39 +02:00
committed by GitHub
parent 8ae1695526
commit e7f25ebda8
10 changed files with 80 additions and 78 deletions
+2 -2
View File
@@ -19,7 +19,7 @@
use structopt::StructOpt; use structopt::StructOpt;
use sc_cli::{ use sc_cli::{
Error, VanityCmd, SignCmd, VerifyCmd, InsertCmd, Error, VanityCmd, SignCmd, VerifyCmd, InsertCmd,
GenerateNodeKeyCmd, GenerateCmd, InspectCmd, InspectNodeKeyCmd GenerateNodeKeyCmd, GenerateCmd, InspectKeyCmd, InspectNodeKeyCmd
}; };
use substrate_frame_cli::ModuleIdCmd; use substrate_frame_cli::ModuleIdCmd;
use sp_core::crypto::Ss58Codec; use sp_core::crypto::Ss58Codec;
@@ -38,7 +38,7 @@ pub enum Subkey {
Generate(GenerateCmd), Generate(GenerateCmd),
/// Gets a public key and a SS58 address from the provided Secret URI /// Gets a public key and a SS58 address from the provided Secret URI
InspectKey(InspectCmd), InspectKey(InspectKeyCmd),
/// Print the peer ID corresponding to the node key in the given file /// Print the peer ID corresponding to the node key in the given file
InspectNodeKey(InspectNodeKeyCmd), InspectNodeKey(InspectNodeKeyCmd),
@@ -62,7 +62,6 @@ impl GenerateCmd {
}; };
let mnemonic = Mnemonic::new(words, Language::English); let mnemonic = Mnemonic::new(words, Language::English);
let password = self.keystore_params.read_password()?; let password = self.keystore_params.read_password()?;
let maybe_network = self.network_scheme.network.clone();
let output = self.output_scheme.output_type.clone(); let output = self.output_scheme.output_type.clone();
with_crypto_scheme!( with_crypto_scheme!(
@@ -70,7 +69,7 @@ impl GenerateCmd {
print_from_uri( print_from_uri(
mnemonic.phrase(), mnemonic.phrase(),
password, password,
maybe_network, self.network_scheme.network.clone(),
output output
) )
); );
@@ -60,8 +60,9 @@ mod tests {
#[test] #[test]
fn generate_node_key() { fn generate_node_key() {
let mut file = Builder::new().prefix("keyfile").tempfile().unwrap(); let mut file = Builder::new().prefix("keyfile").tempfile().unwrap();
let file_path = file.path().display().to_string();
let generate = let generate =
GenerateNodeKeyCmd::from_iter(&["generate-node-key", "--file", "/tmp/keyfile"]); GenerateNodeKeyCmd::from_iter(&["generate-node-key", "--file", &file_path]);
assert!(generate.run().is_ok()); assert!(generate.run().is_ok());
let mut buf = String::new(); let mut buf = String::new();
assert!(file.read_to_string(&mut buf).is_ok()); assert!(file.read_to_string(&mut buf).is_ok());
+10 -8
View File
@@ -28,12 +28,14 @@ use structopt::StructOpt;
name = "inspect-key", name = "inspect-key",
about = "Gets a public key and a SS58 address from the provided Secret URI" about = "Gets a public key and a SS58 address from the provided Secret URI"
)] )]
pub struct InspectCmd { pub struct InspectKeyCmd {
/// A Key URI to be inspected. May be a secret seed, secret URI /// A Key URI to be inspected. May be a secret seed, secret URI
/// (with derivation paths and password), SS58 or public URI. /// (with derivation paths and password), SS58 or public URI.
/// If the value is a file, the file content is used as URI. ///
/// If not given, you will be prompted for the URI. /// If the given value is a file, the file content will be used
#[structopt(long)] /// as URI.
///
/// If omitted, you will be prompted for the URI.
uri: Option<String>, uri: Option<String>,
#[allow(missing_docs)] #[allow(missing_docs)]
@@ -53,7 +55,7 @@ pub struct InspectCmd {
pub crypto_scheme: CryptoSchemeFlag, pub crypto_scheme: CryptoSchemeFlag,
} }
impl InspectCmd { impl InspectKeyCmd {
/// Run the command /// Run the command
pub fn run(&self) -> Result<(), Error> { pub fn run(&self) -> Result<(), Error> {
let uri = utils::read_uri(self.uri.as_ref())?; let uri = utils::read_uri(self.uri.as_ref())?;
@@ -76,7 +78,7 @@ impl InspectCmd {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::InspectCmd; use super::*;
use structopt::StructOpt; use structopt::StructOpt;
#[test] #[test]
@@ -86,10 +88,10 @@ mod tests {
let seed = "0xad1fb77243b536b90cfe5f0d351ab1b1ac40e3890b41dc64f766ee56340cfca5"; let seed = "0xad1fb77243b536b90cfe5f0d351ab1b1ac40e3890b41dc64f766ee56340cfca5";
let inspect = let inspect =
InspectCmd::from_iter(&["inspect-key", "--uri", words, "--password", "12345"]); InspectKeyCmd::from_iter(&["inspect-key", words, "--password", "12345"]);
assert!(inspect.run().is_ok()); assert!(inspect.run().is_ok());
let inspect = InspectCmd::from_iter(&["inspect-key", "--uri", seed]); let inspect = InspectKeyCmd::from_iter(&["inspect-key", seed]);
assert!(inspect.run().is_ok()); assert!(inspect.run().is_ok());
} }
} }
+2 -2
View File
@@ -22,7 +22,7 @@ use structopt::StructOpt;
use super::{ use super::{
insert::InsertCmd, insert::InsertCmd,
inspect::InspectCmd, inspect::InspectKeyCmd,
generate::GenerateCmd, generate::GenerateCmd,
inspect_node_key::InspectNodeKeyCmd, inspect_node_key::InspectNodeKeyCmd,
generate_node_key::GenerateNodeKeyCmd, generate_node_key::GenerateNodeKeyCmd,
@@ -38,7 +38,7 @@ pub enum KeySubcommand {
Generate(GenerateCmd), Generate(GenerateCmd),
/// Gets a public key and a SS58 address from the provided Secret URI /// Gets a public key and a SS58 address from the provided Secret URI
InspectKey(InspectCmd), InspectKey(InspectKeyCmd),
/// Print the peer ID corresponding to the node key in the given file /// Print the peer ID corresponding to the node key in the given file
InspectNodeKey(InspectNodeKeyCmd), InspectNodeKey(InspectNodeKeyCmd),
+1 -1
View File
@@ -47,7 +47,7 @@ pub use self::{
sign::SignCmd, sign::SignCmd,
generate::GenerateCmd, generate::GenerateCmd,
insert::InsertCmd, insert::InsertCmd,
inspect::InspectCmd, inspect::InspectKeyCmd,
generate_node_key::GenerateNodeKeyCmd, generate_node_key::GenerateNodeKeyCmd,
inspect_node_key::InspectNodeKeyCmd, inspect_node_key::InspectNodeKeyCmd,
key::KeySubcommand, key::KeySubcommand,
+54 -53
View File
@@ -54,95 +54,96 @@ pub fn read_uri(uri: Option<&String>) -> error::Result<String> {
pub fn print_from_uri<Pair>( pub fn print_from_uri<Pair>(
uri: &str, uri: &str,
password: Option<SecretString>, password: Option<SecretString>,
network_override: Ss58AddressFormat, network_override: Option<Ss58AddressFormat>,
output: OutputType, output: OutputType,
) ) where Pair: sp_core::Pair, Pair::Public: Into<MultiSigner> {
where
Pair: sp_core::Pair,
Pair::Public: Into<MultiSigner>,
{
let password = password.as_ref().map(|s| s.expose_secret().as_str()); let password = password.as_ref().map(|s| s.expose_secret().as_str());
if let Ok((pair, seed)) = Pair::from_phrase(uri, password.clone()) { if let Ok((pair, seed)) = Pair::from_phrase(uri, password.clone()) {
let public_key = pair.public(); let public_key = pair.public();
let network_override = network_override.unwrap_or_default();
match output { match output {
OutputType::Json => { OutputType::Json => {
let json = json!({ let json = json!({
"secretPhrase": uri, "secretPhrase": uri,
"secretSeed": format_seed::<Pair>(seed), "secretSeed": format_seed::<Pair>(seed),
"publicKey": format_public_key::<Pair>(public_key.clone()), "publicKey": format_public_key::<Pair>(public_key.clone()),
"accountId": format_account_id::<Pair>(public_key), "accountId": format_account_id::<Pair>(public_key),
"ss58Address": pair.public().into().into_account().to_ss58check(), "ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override),
}); });
println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed"));
}, },
OutputType::Text => { OutputType::Text => {
println!("Secret phrase `{}` is account:\n \ println!(
Secret seed: {}\n \ "Secret phrase `{}` is account:\n \
Public key (hex): {}\n \ Secret seed: {}\n \
Account ID: {}\n \ Public key (hex): {}\n \
SS58 Address: {}", Account ID: {}\n \
uri, SS58 Address: {}",
format_seed::<Pair>(seed), uri,
format_public_key::<Pair>(public_key.clone()), format_seed::<Pair>(seed),
format_account_id::<Pair>(public_key), format_public_key::<Pair>(public_key.clone()),
pair.public().into().into_account().to_ss58check(), format_account_id::<Pair>(public_key),
pair.public().into().into_account().to_ss58check_with_version(network_override),
); );
}, },
} }
} else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password.clone()) { } else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password.clone()) {
let public_key = pair.public(); let public_key = pair.public();
let network_override = network_override.unwrap_or_default();
match output { match output {
OutputType::Json => { OutputType::Json => {
let json = json!({ let json = json!({
"secretKeyUri": uri, "secretKeyUri": uri,
"secretSeed": if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() }, "secretSeed": if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
"publicKey": format_public_key::<Pair>(public_key.clone()), "publicKey": format_public_key::<Pair>(public_key.clone()),
"accountId": format_account_id::<Pair>(public_key), "accountId": format_account_id::<Pair>(public_key),
"ss58Address": pair.public().into().into_account().to_ss58check(), "ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override),
}); });
println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed"));
}, },
OutputType::Text => { OutputType::Text => {
println!("Secret Key URI `{}` is account:\n \ println!(
Secret seed: {}\n \ "Secret Key URI `{}` is account:\n \
Public key (hex): {}\n \ Secret seed: {}\n \
Account ID: {}\n \ Public key (hex): {}\n \
SS58 Address: {}", Account ID: {}\n \
uri, SS58 Address: {}",
if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() }, uri,
format_public_key::<Pair>(public_key.clone()), if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
format_account_id::<Pair>(public_key), format_public_key::<Pair>(public_key.clone()),
pair.public().into().into_account().to_ss58check(), format_account_id::<Pair>(public_key),
pair.public().into().into_account().to_ss58check_with_version(network_override),
); );
}, },
} }
} else if let Ok((public_key, _v)) = Pair::Public::from_string_with_version(uri) { } else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) {
let v = network_override; let network_override = network_override.unwrap_or(network);
match output { match output {
OutputType::Json => { OutputType::Json => {
let json = json!({ let json = json!({
"publicKeyUri": uri, "publicKeyUri": uri,
"networkId": String::from(v), "networkId": String::from(network_override),
"publicKey": format_public_key::<Pair>(public_key.clone()), "publicKey": format_public_key::<Pair>(public_key.clone()),
"accountId": format_account_id::<Pair>(public_key.clone()), "accountId": format_account_id::<Pair>(public_key.clone()),
"ss58Address": public_key.to_ss58check_with_version(v), "ss58Address": public_key.to_ss58check_with_version(network_override),
}); });
println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed"));
}, },
OutputType::Text => { OutputType::Text => {
println!("Public Key URI `{}` is account:\n \ println!(
Network ID/version: {}\n \ "Public Key URI `{}` is account:\n \
Public key (hex): {}\n \ Network ID/version: {}\n \
Account ID: {}\n \ Public key (hex): {}\n \
SS58 Address: {}", Account ID: {}\n \
SS58 Address: {}",
uri, uri,
String::from(v), String::from(network_override),
format_public_key::<Pair>(public_key.clone()), format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()), format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(v), public_key.to_ss58check_with_version(network_override),
); );
}, },
} }
+2 -2
View File
@@ -153,12 +153,12 @@ pub struct NetworkSchemeFlag {
#[structopt( #[structopt(
long, long,
value_name = "NETWORK", value_name = "NETWORK",
short = "n",
possible_values = &Ss58AddressFormat::all_names()[..], possible_values = &Ss58AddressFormat::all_names()[..],
parse(try_from_str = Ss58AddressFormat::try_from), parse(try_from_str = Ss58AddressFormat::try_from),
case_insensitive = true, case_insensitive = true,
default_value = "polkadot"
)] )]
pub network: Ss58AddressFormat, pub network: Option<Ss58AddressFormat>,
} }
#[cfg(test)] #[cfg(test)]
+3 -2
View File
@@ -265,7 +265,6 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
} }
/// Return the ss58-check string for this key. /// Return the ss58-check string for this key.
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String {
let mut v = vec![version.into()]; let mut v = vec![version.into()];
@@ -274,9 +273,11 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
v.extend(&r.as_bytes()[0..2]); v.extend(&r.as_bytes()[0..2]);
v.to_base58() v.to_base58()
} }
/// Return the ss58-check string for this key. /// Return the ss58-check string for this key.
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) } fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) }
/// Some if the string is a properly encoded SS58Check address, optionally with /// Some if the string is a properly encoded SS58Check address, optionally with
/// a derivation path following. /// a derivation path following.
#[cfg(feature = "std")] #[cfg(feature = "std")]
@@ -377,7 +378,7 @@ macro_rules! ss58_address_format {
Ss58AddressFormat::Custom(n) if n == x => Ok(Ss58AddressFormat::Custom(x)), Ss58AddressFormat::Custom(n) if n == x => Ok(Ss58AddressFormat::Custom(x)),
_ => Err(()), _ => Err(()),
} }
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
Err(()) Err(())
}, },
@@ -44,9 +44,8 @@ pub struct ModuleIdCmd {
possible_values = &Ss58AddressFormat::all_names()[..], possible_values = &Ss58AddressFormat::all_names()[..],
parse(try_from_str = Ss58AddressFormat::try_from), parse(try_from_str = Ss58AddressFormat::try_from),
case_insensitive = true, case_insensitive = true,
default_value = "substrate"
)] )]
pub network: Ss58AddressFormat, pub network: Option<Ss58AddressFormat>,
#[allow(missing_docs)] #[allow(missing_docs)]
#[structopt(flatten)] #[structopt(flatten)]
@@ -78,14 +77,13 @@ impl ModuleIdCmd {
.map_err(|_| "Cannot convert argument to moduleid: argument should be 8-character string")?; .map_err(|_| "Cannot convert argument to moduleid: argument should be 8-character string")?;
let account_id: R::AccountId = ModuleId(id_fixed_array).into_account(); let account_id: R::AccountId = ModuleId(id_fixed_array).into_account();
let network = self.network;
with_crypto_scheme!( with_crypto_scheme!(
self.crypto_scheme.scheme, self.crypto_scheme.scheme,
print_from_uri( print_from_uri(
&account_id.to_ss58check_with_version(network), &account_id.to_ss58check_with_version(self.network.clone().unwrap_or_default()),
password, password,
network, self.network,
self.output_scheme.output_type.clone() self.output_scheme.output_type.clone()
) )
); );