From a643ac6c6f5c910bb26d9549d7f97cccae5a6496 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Thu, 12 Sep 2019 15:42:35 +0200 Subject: [PATCH] Fix subkey does not verify with pubkey (#3547) * Decode hex * Remove log * Some refactoring to help with testing * Add own functions for sign and verify. * Add sign test * Sign-verify test * Generate-sign-verify test for both cryptos * Add aliases * Print signature * More refactoring * Update sign-transaction as transfer * Simplify transfer and sign-transaction * main to top file * rename read_input_message to read_message_from_stdin * More refactoring * Add read_required_parameter * Add format seed * More refactoring * format code * add print_extrinsic * Remove 0x from print * fix naming * Fix readme * Remove rustfmt * Remove commented test * Fix import nits --- substrate/subkey/README.adoc | 4 +- substrate/subkey/src/main.rs | 573 +++++++++++++++++++++------------ substrate/subkey/src/vanity.rs | 57 ++-- 3 files changed, 407 insertions(+), 227 deletions(-) diff --git a/substrate/subkey/README.adoc b/substrate/subkey/README.adoc index 52770e78ec..07533a002f 100644 --- a/substrate/subkey/README.adoc +++ b/substrate/subkey/README.adoc @@ -31,7 +31,7 @@ OUTPUT: `subkey` expects a message to come in on STDIN, one way to sign a message would look like this: ```bash -echo | subkey sign +echo -n | subkey sign OUTPUT: a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b7406d1b7e03231df6dd4a5257546ddad13259356e1c3adfb509 @@ -40,7 +40,7 @@ a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b740 === Verifying a signature ```bash -echo | subkey verify
+echo -n | subkey verify
OUTPUT: Signature verifies correctly. diff --git a/substrate/subkey/src/main.rs b/substrate/subkey/src/main.rs index a68674513a..c112dfa1b4 100644 --- a/substrate/subkey/src/main.rs +++ b/substrate/subkey/src/main.rs @@ -18,54 +18,69 @@ #[cfg(feature = "bench")] extern crate test; -use std::{str::FromStr, io::{stdin, Read}, convert::TryInto}; +use bip39::{Language, Mnemonic, MnemonicType}; +use clap::{load_yaml, App, ArgMatches}; +use codec::{Decode, Encode}; use hex_literal::hex; -use clap::load_yaml; -use bip39::{Mnemonic, Language, MnemonicType}; +use node_primitives::{Balance, Hash, Index}; +use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; use primitives::{ - ed25519, sr25519, hexdisplay::HexDisplay, Pair, Public, blake2_256, - crypto::{Ss58Codec, set_default_ss58_version, Ss58AddressFormat} + crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, + ed25519, sr25519, Pair, Public, H256, hexdisplay::HexDisplay, }; -use codec::{Encode, Decode}; use sr_primitives::generic::Era; -use node_primitives::{Balance, Index, Hash}; -use node_runtime::{Call, UncheckedExtrinsic, SignedPayload, BalancesCall, Runtime, VERSION}; +use std::{ + convert::TryInto, + io::{stdin, Read}, + str::FromStr, +}; mod vanity; -trait Crypto { - type Pair: Pair; +trait Crypto: Sized { + type Pair: Pair; type Public: Public + Ss58Codec + AsRef<[u8]> + std::hash::Hash; fn pair_from_suri(suri: &str, password: Option<&str>) -> Self::Pair { Self::Pair::from_string(suri, password).expect("Invalid phrase") } - fn ss58_from_pair(pair: &Self::Pair) -> String { pair.public().to_ss58check() } - fn public_from_pair(pair: &Self::Pair) -> Vec { pair.public().as_ref().to_owned() } + fn ss58_from_pair(pair: &Self::Pair) -> String { + pair.public().to_ss58check() + } + fn public_from_pair(pair: &Self::Pair) -> Self::Public { + pair.public() + } fn print_from_uri( uri: &str, password: Option<&str>, network_override: Option, - ) where ::Public: Sized + Ss58Codec + AsRef<[u8]> { + ) where + ::Public: PublicT, + { if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { - println!("Secret phrase `{}` is account:\n Secret seed: 0x{}\n Public key (hex): 0x{}\n Address (SS58): {}", + let public_key = Self::public_from_pair(&pair); + println!("Secret phrase `{}` is account:\n Secret seed: {}\n Public key (hex): {}\n Address (SS58): {}", uri, - HexDisplay::from(&seed.as_ref()), - HexDisplay::from(&Self::public_from_pair(&pair)), + format_seed::(seed), + format_public_key::(public_key), Self::ss58_from_pair(&pair) ); } else if let Ok(pair) = Self::Pair::from_string(uri, password) { - println!("Secret Key URI `{}` is account:\n Public key (hex): 0x{}\n Address (SS58): {}", + let public_key = Self::public_from_pair(&pair); + println!( + "Secret Key URI `{}` is account:\n Public key (hex): {}\n Address (SS58): {}", uri, - HexDisplay::from(&Self::public_from_pair(&pair)), + format_public_key::(public_key), Self::ss58_from_pair(&pair) ); - } else if let Ok((public, v)) = ::Public::from_string_with_version(uri) { + } else if let Ok((public_key, v)) = + ::Public::from_string_with_version(uri) + { let v = network_override.unwrap_or(v); - println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): 0x{}\n Address (SS58): {}", + println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): {}\n Address (SS58): {}", uri, String::from(v), - HexDisplay::from(&public.as_ref()), - public.to_ss58check_with_version(v) + format_public_key::(public_key.clone()), + public_key.to_ss58check_with_version(v) ); } else { println!("Invalid phrase/URI given"); @@ -91,10 +106,256 @@ impl Crypto for Sr25519 { type Public = sr25519::Public; } -fn execute(matches: clap::ArgMatches) where - <::Pair as Pair>::Signature: AsRef<[u8]> + AsMut<[u8]> + Default, - <::Pair as Pair>::Public: Sized + AsRef<[u8]> + Ss58Codec, +type SignatureOf = <::Pair as Pair>::Signature; +type PublicOf = <::Pair as Pair>::Public; +type SeedOf = <::Pair as Pair>::Seed; + +trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default {} +trait PublicT: Sized + AsRef<[u8]> + Ss58Codec {} + +impl SignatureT for sr25519::Signature {} +impl SignatureT for ed25519::Signature {} +impl PublicT for sr25519::Public {} +impl PublicT for ed25519::Public {} + +fn main() { + let yaml = load_yaml!("cli.yml"); + let matches = App::from_yaml(yaml) + .version(env!("CARGO_PKG_VERSION")) + .get_matches(); + + if matches.is_present("ed25519") { + execute::(matches) + } else { + execute::(matches) + } +} + +fn execute(matches: ArgMatches) +where + SignatureOf: SignatureT, + PublicOf: PublicT, { + let password = matches.value_of("password"); + let maybe_network: Option = matches.value_of("network").map(|network| { + network + .try_into() + .expect("Invalid network name: must be polkadot/substrate/kusama") + }); + if let Some(network) = maybe_network { + set_default_ss58_version(network); + } + match matches.subcommand() { + ("generate", Some(matches)) => { + let mnemonic = generate_mnemonic(matches); + C::print_from_uri(mnemonic.phrase(), password, maybe_network); + } + ("inspect", Some(matches)) => { + let uri = matches + .value_of("uri") + .expect("URI parameter is required; thus it can't be None; qed"); + C::print_from_uri(uri, password, maybe_network); + } + ("sign", Some(matches)) => { + let should_decode = matches.is_present("hex"); + let message = read_message_from_stdin(should_decode); + let signature = do_sign::(matches, message, password); + println!("{}", signature); + } + ("verify", Some(matches)) => { + let should_decode = matches.is_present("hex"); + let message = read_message_from_stdin(should_decode); + let is_valid_signature = do_verify::(matches, message, password); + if is_valid_signature { + println!("Signature verifies correctly."); + } else { + println!("Signature invalid."); + } + } + ("vanity", Some(matches)) => { + let desired: String = matches + .value_of("pattern") + .map(str::to_string) + .unwrap_or_default(); + let result = vanity::generate_key::(&desired).expect("Key generation failed"); + let formated_seed = format_seed::(result.seed); + C::print_from_uri(&formated_seed, None, maybe_network); + } + ("transfer", Some(matches)) => { + let signer = read_pair::(matches.value_of("from"), password); + let index = read_required_parameter::(matches, "index"); + let genesis_hash = read_genesis_hash(matches); + + let to = read_public_key::(matches.value_of("to"), password); + let amount = read_required_parameter::(matches, "amount"); + let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); + + let extrinsic = create_extrinsic(function, index, signer, genesis_hash); + + print_extrinsic(extrinsic); + } + ("sign-transaction", Some(matches)) => { + let signer = read_pair::(matches.value_of("suri"), password); + let index = read_required_parameter::(matches, "nonce"); + let genesis_hash = read_genesis_hash(matches); + + let call = matches.value_of("call").expect("call is required; qed"); + let function: Call = hex::decode(&call) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .unwrap(); + + let extrinsic = create_extrinsic(function, index, signer, genesis_hash); + + print_extrinsic(extrinsic); + } + _ => print_usage(&matches), + } +} + +/// Creates a new randomly generated mnemonic phrase. +fn generate_mnemonic(matches: &ArgMatches) -> Mnemonic { + let words = matches + .value_of("words") + .map(|x| usize::from_str(x).expect("Invalid number given for --words")) + .map(|x| { + MnemonicType::for_word_count(x) + .expect("Invalid number of words given for phrase: must be 12/15/18/21/24") + }) + .unwrap_or(MnemonicType::Words12); + Mnemonic::new(words, Language::English) +} + +fn do_sign(matches: &ArgMatches, message: Vec, password: Option<&str>) -> String +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let pair = read_pair::(matches.value_of("suri"), password); + let signature = pair.sign(&message); + format_signature::(&signature) +} + +fn do_verify(matches: &ArgMatches, message: Vec, password: Option<&str>) -> bool +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let signature = read_signature::(matches); + let pubkey = read_public_key::(matches.value_of("uri"), password); + <::Pair as Pair>::verify(&signature, &message, &pubkey) +} + +fn read_message_from_stdin(should_decode: bool) -> Vec { + let mut message = vec![]; + stdin() + .lock() + .read_to_end(&mut message) + .expect("Error reading from stdin"); + if should_decode { + message = hex::decode(&message).expect("Invalid hex in message"); + } + message +} + +fn read_required_parameter(matches: &ArgMatches, name: &str) -> T +where + ::Err: std::fmt::Debug, +{ + let str_value = matches + .value_of(name) + .expect("parameter is required; thus it can't be None; qed"); + str::parse::(str_value).expect("Invalid 'nonce' parameter; expecting an integer.") +} + +fn read_genesis_hash(matches: &ArgMatches) -> H256 { + let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { + "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), + "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), + h => hex::decode(h) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .expect("Invalid genesis hash or unrecognised chain identifier"), + }; + println!( + "Using a genesis hash of {}", + HexDisplay::from(&genesis_hash.as_ref()) + ); + genesis_hash +} + +fn read_signature(matches: &ArgMatches) -> SignatureOf +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let sig_data = matches + .value_of("sig") + .expect("signature parameter is required; thus it can't be None; qed"); + let mut signature = <::Pair as Pair>::Signature::default(); + let sig_data = hex::decode(sig_data).expect("signature is invalid hex"); + if sig_data.len() != signature.as_ref().len() { + panic!( + "signature has an invalid length. read {} bytes, expected {} bytes", + sig_data.len(), + signature.as_ref().len(), + ); + } + signature.as_mut().copy_from_slice(&sig_data); + signature +} + +fn read_public_key(matched_uri: Option<&str>, password: Option<&str>) -> PublicOf +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); + let uri = if uri.starts_with("0x") { + &uri[2..] + } else { + uri + }; + if let Ok(pubkey_vec) = hex::decode(uri) { + ::Public::from_slice(pubkey_vec.as_slice()) + } else { + ::Pair::from_string(uri, password) + .ok() + .map(|p| p.public()) + .expect("Invalid URI; expecting either a secret URI or a public URI.") + } +} + +fn read_pair( + matched_suri: Option<&str>, + password: Option<&str>, +) -> ::Pair +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let suri = matched_suri.expect("parameter is required; thus it can't be None; qed"); + C::pair_from_suri(suri, password) +} + +fn format_signature(signature: &SignatureOf) -> String { + format!("{}", hex::encode(signature)) +} + +fn format_seed(seed: SeedOf) -> String { + format!("0x{}", HexDisplay::from(&seed.as_ref())) +} + +fn format_public_key(public_key: PublicOf) -> String { + format!("0x{}", HexDisplay::from(&public_key.as_ref())) +} + +fn create_extrinsic( + function: Call, + index: Index, + signer: ::Pair, + genesis_hash: H256, +) -> UncheckedExtrinsic { let extra = |i: Index, f: Balance| { ( system::CheckVersion::::new(), @@ -106,201 +367,99 @@ fn execute(matches: clap::ArgMatches) where Default::default(), ) }; - let password = matches.value_of("password"); - let maybe_network: Option = matches.value_of("network") - .map(|network| network.try_into() - .expect("Invalid network name: must be polkadot/substrate/kusama") - ); - if let Some(network) = maybe_network { - set_default_ss58_version(network); - } - match matches.subcommand() { - ("generate", Some(matches)) => { - // create a new randomly generated mnemonic phrase - let words = matches.value_of("words") - .map(|x| usize::from_str(x).expect("Invalid number given for --words")) - .map(|x| MnemonicType::for_word_count(x) - .expect("Invalid number of words given for phrase: must be 12/15/18/21/24") - ).unwrap_or(MnemonicType::Words12); - let mnemonic = Mnemonic::new(words, Language::English); - C::print_from_uri(mnemonic.phrase(), password, maybe_network); - } - ("inspect", Some(matches)) => { - let uri = matches.value_of("uri") - .expect("URI parameter is required; thus it can't be None; qed"); - C::print_from_uri(uri, password, maybe_network); - } - ("vanity", Some(matches)) => { - let desired: String = matches.value_of("pattern").map(str::to_string).unwrap_or_default(); - let result = vanity::generate_key::(&desired).expect("Key generation failed"); - C::print_from_uri( - &format!("0x{}", HexDisplay::from(&result.seed.as_ref())), - None, - maybe_network - ); - } - ("sign", Some(matches)) => { - let suri = matches.value_of("suri") - .expect("secret URI parameter is required; thus it can't be None; qed"); - let pair = C::pair_from_suri(suri, password); - let mut message = vec![]; - stdin().lock().read_to_end(&mut message).expect("Error reading from stdin"); - if matches.is_present("hex") { - message = hex::decode(&message).expect("Invalid hex in message"); - } - let sig = pair.sign(&message); - println!("{}", hex::encode(&sig)); - } - ("transfer", Some(matches)) => { - let signer = matches.value_of("from") - .expect("parameter is required; thus it can't be None; qed"); - let signer = Sr25519::pair_from_suri(signer, password); - - let to = matches.value_of("to") - .expect("parameter is required; thus it can't be None; qed"); - let to = sr25519::Public::from_string(to).ok().or_else(|| - sr25519::Pair::from_string(to, password).ok().map(|p| p.public()) - ).expect("Invalid 'to' URI; expecting either a secret URI or a public URI."); - - let amount = matches.value_of("amount") - .expect("parameter is required; thus it can't be None; qed"); - let amount = str::parse::(amount) - .expect("Invalid 'amount' parameter; expecting an integer."); - - let index = matches.value_of("index") - .expect("parameter is required; thus it can't be None; qed"); - let index = str::parse::(index) - .expect("Invalid 'index' parameter; expecting an integer."); - - let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => hex::decode(h).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()) - .expect("Invalid genesis hash or unrecognised chain identifier"), - }; - - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - - let raw_payload = SignedPayload::from_raw( - function, - extra(index, 0), - (VERSION.spec_version as u32, genesis_hash, genesis_hash, (), (), (), ()), - ); - let signature = raw_payload.using_encoded(|payload| { - println!("Signing {}", HexDisplay::from(&payload)); - signer.sign(payload) - }); - let (function, extra, _) = raw_payload.deconstruct(); - let extrinsic = UncheckedExtrinsic::new_signed( - function, - signer.public().into(), - signature.into(), - extra, - ); - println!("0x{}", hex::encode(&extrinsic.encode())); - } - ("sign-transaction", Some(matches)) => { - let s = matches.value_of("suri") - .expect("secret URI parameter is required; thus it can't be None; qed"); - let signer = Sr25519::pair_from_suri(s, password); - - let index = matches.value_of("nonce") - .expect("nonce is required; thus it can't be None; qed"); - let index = str::parse::(index) - .expect("Invalid 'nonce' parameter; expecting an integer."); - - let call = matches.value_of("call") - .expect("call is required; thus it can't be None; qed"); - let function: Call = hex::decode(&call).ok() - .and_then(|x| Decode::decode(&mut &x[..]).ok()).unwrap(); - - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => hex::decode(h).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()) - .expect("Invalid genesis hash or unrecognised chain identifier"), - }; - - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - - let raw_payload = ( - function, - extra(index, 0), - (&genesis_hash, &genesis_hash), - ); - let signature = raw_payload.using_encoded(|payload| - if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { - signer.sign(payload) - } - ); - - let extrinsic = UncheckedExtrinsic::new_signed( - raw_payload.0, - signer.public().into(), - signature.into(), - extra(index, 0), - ); - - println!("0x{}", hex::encode(&extrinsic.encode())); - } - ("verify", Some(matches)) => { - let sig_data = matches.value_of("sig") - .expect("signature parameter is required; thus it can't be None; qed"); - let mut sig = <::Pair as Pair>::Signature::default(); - let sig_data = hex::decode(sig_data).expect("signature is invalid hex"); - if sig_data.len() != sig.as_ref().len() { - panic!("signature is an invalid length. {} bytes is not the expected value of {} bytes", sig_data.len(), sig.as_ref().len()); - } - sig.as_mut().copy_from_slice(&sig_data); - let uri = matches.value_of("uri") - .expect("public uri parameter is required; thus it can't be None; qed"); - let pubkey = <::Pair as Pair>::Public::from_string(uri).ok().or_else(|| - ::Pair::from_string(uri, password).ok().map(|p| p.public()) - ).expect("Invalid URI; expecting either a secret URI or a public URI."); - let mut message = vec![]; - stdin().lock().read_to_end(&mut message).expect("Error reading from stdin"); - if matches.is_present("hex") { - message = hex::decode(&message).expect("Invalid hex in message"); - } - if <::Pair as Pair>::verify(&sig, &message, &pubkey) { - println!("Signature verifies correctly.") - } else { - println!("Signature invalid.") - } - } - _ => print_usage(&matches), - } + let raw_payload = SignedPayload::from_raw( + function, + extra(index, 0), + ( + VERSION.spec_version as u32, + genesis_hash, + genesis_hash, + (), + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); + let (function, extra, _) = raw_payload.deconstruct(); + + UncheckedExtrinsic::new_signed( + function, + signer.public().into(), + signature.into(), + extra, + ) } -fn main() { - let yaml = load_yaml!("cli.yml"); - let matches = clap::App::from_yaml(yaml) - .version(env!("CARGO_PKG_VERSION")) - .get_matches(); - - if matches.is_present("ed25519") { - execute::(matches) - } else { - execute::(matches) - } +fn print_extrinsic(extrinsic: UncheckedExtrinsic) { + println!("0x{}", hex::encode(&extrinsic.encode())); } -fn print_usage(matches: &clap::ArgMatches) { +fn print_usage(matches: &ArgMatches) { println!("{}", matches.usage()); } #[cfg(test)] mod tests { - use super::{Hash, Decode}; + use super::*; + + fn test_generate_sign_verify() + where + SignatureOf: SignatureT, + PublicOf: PublicT, + { + let yaml = load_yaml!("cli.yml"); + let app = App::from_yaml(yaml); + let password = None; + + // Generate public key and seed. + let arg_vec = vec!["subkey", "generate"]; + + let matches = app.clone().get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + let mnemonic = generate_mnemonic(matches); + + let (pair, seed) = + <::Pair as Pair>::from_phrase(mnemonic.phrase(), password) + .unwrap(); + let public_key = CryptoType::public_from_pair(&pair); + let public_key = format_public_key::(public_key); + let seed = format_seed::(seed); + + // Sign a message using previous seed. + let arg_vec = vec!["subkey", "sign", &seed[..]]; + + let matches = app.get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + let message = "Blah Blah\n".as_bytes().to_vec(); + let signature = do_sign::(matches, message.clone(), password); + + // Verify the previous signature. + let arg_vec = vec!["subkey", "verify", &signature[..], &public_key[..]]; + + let matches = App::from_yaml(yaml).get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + assert!(do_verify::(matches, message, password)); + } + + #[test] + fn generate_sign_verify_should_work_for_ed25519() { + test_generate_sign_verify::(); + } + + #[test] + fn generate_sign_verify_should_work_for_sr25519() { + test_generate_sign_verify::(); + } + #[test] fn should_work() { let s = "0123456789012345678901234567890123456789012345678901234567890123"; - let d1: Hash = hex::decode(s).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()).unwrap(); + let d1: Hash = hex::decode(s) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .unwrap(); let d2: Hash = { let mut gh: [u8; 32] = Default::default(); diff --git a/substrate/subkey/src/vanity.rs b/substrate/subkey/src/vanity.rs index 988055c67c..ea30f7413e 100644 --- a/substrate/subkey/src/vanity.rs +++ b/substrate/subkey/src/vanity.rs @@ -14,15 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rand::{rngs::OsRng, RngCore}; use super::Crypto; use primitives::Pair; +use rand::{rngs::OsRng, RngCore}; fn good_waypoint(done: u64) -> u64 { match done { - 0 ..= 1_000_000 => 100_000, - 0 ..= 10_000_000 => 1_000_000, - 0 ..= 100_000_000 => 10_000_000, + 0..=1_000_000 => 100_000, + 0..=10_000_000 => 1_000_000, + 0..=100_000_000 => 10_000_000, _ => 100_000_000, } } @@ -30,8 +30,13 @@ fn good_waypoint(done: u64) -> u64 { fn next_seed(seed: &mut [u8]) { for i in 0..seed.len() { match seed[i] { - 255 => { seed[i] = 0; } - _ => { seed[i] += 1; break; } + 255 => { + seed[i] = 0; + } + _ => { + seed[i] += 1; + break; + } } } } @@ -101,15 +106,20 @@ pub(super) fn generate_key(desired: &str) -> Result, &str> #[cfg(test)] mod tests { - use super::*; use super::super::Ed25519; - use primitives::{Pair, crypto::Ss58Codec}; + use super::*; + use primitives::{crypto::Ss58Codec, Pair}; #[cfg(feature = "bench")] use test::Bencher; #[test] fn test_generation_with_single_char() { - assert!(generate_key::("j").unwrap().pair.public().to_ss58check().contains("j")); + assert!(generate_key::("j") + .unwrap() + .pair + .public() + .to_ss58check() + .contains("j")); } #[test] @@ -120,34 +130,45 @@ mod tests { #[test] fn test_score_100() { - let score = calculate_score("Polkadot", "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"); + let score = calculate_score( + "Polkadot", + "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim", + ); assert_eq!(score, 430); } #[test] fn test_score_50_2() { // 50% for the position + 50% for the size - assert_eq!(calculate_score("Polkadot", "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"), 238); + assert_eq!( + calculate_score( + "Polkadot", + "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim" + ), + 238 + ); } #[test] fn test_score_0() { - assert_eq!(calculate_score("Polkadot", "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK"), 0); + assert_eq!( + calculate_score( + "Polkadot", + "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK" + ), + 0 + ); } #[cfg(feature = "bench")] #[bench] fn bench_paranoiac(b: &mut Bencher) { - b.iter(|| { - generate_key("polk") - }); + b.iter(|| generate_key("polk")); } #[cfg(feature = "bench")] #[bench] fn bench_not_paranoiac(b: &mut Bencher) { - b.iter(|| { - generate_key("polk") - }); + b.iter(|| generate_key("polk")); } }