Add SECP256k1/ECDSA support for transaction signing (#3861)

* Add SECP256k1/ECDSA support for transaction signing.

* Refactoring and fixes

* Fix for contracts

* Avoid breaking runtime host function

* Build fixes, make subkey work more generaically.

* Fix tests

* Dedpulicate a bit of code, remove unneeded code, docs

* Bump runtime version

* Fix a test and clean up some code.

* Derivation can derive seed.

* Whitespace

* Bump runtime again.

* Update core/primitives/src/crypto.rs

Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Update core/primitives/src/ecdsa.rs

Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Fix AppVerify
This commit is contained in:
Gavin Wood
2019-10-24 10:59:09 +02:00
committed by GitHub
parent 62a238a81b
commit d97775542a
30 changed files with 1286 additions and 419 deletions
+38 -29
View File
@@ -17,7 +17,7 @@
//! Substrate chain configurations.
use chain_spec::ChainSpecExtension;
use primitives::{Pair, Public, crypto::UncheckedInto};
use primitives::{Pair, Public, crypto::UncheckedInto, sr25519};
use serde::{Serialize, Deserialize};
use node_runtime::{
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
@@ -32,10 +32,13 @@ use substrate_telemetry::TelemetryEndpoints;
use grandpa_primitives::{AuthorityId as GrandpaId};
use babe_primitives::{AuthorityId as BabeId};
use im_online::sr25519::{AuthorityId as ImOnlineId};
use sr_primitives::Perbill;
use sr_primitives::{traits::Verify, Perbill};
pub use node_primitives::{AccountId, Balance};
pub use node_primitives::{AccountId, Balance, Signature};
pub use node_runtime::GenesisConfig;
use sr_primitives::traits::IdentifyAccount;
type AccountPublic = <Signature as Verify>::Signer;
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
@@ -72,9 +75,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)> = vec![(
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(),
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].into(),
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].unchecked_into(),
hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].into(),
// 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC
hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
@@ -83,9 +86,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
),(
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].unchecked_into(),
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].into(),
// 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF
hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].unchecked_into(),
hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].into(),
// 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE
hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
@@ -94,9 +97,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
),(
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].unchecked_into(),
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].into(),
// 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9
hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].unchecked_into(),
hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].into(),
// 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d
hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
@@ -105,9 +108,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
),(
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].unchecked_into(),
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].into(),
// 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn
hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].unchecked_into(),
hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].into(),
// 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4
hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
@@ -120,7 +123,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
let root_key: AccountId = hex![
// 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo
"9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809"
].unchecked_into();
].into();
let endowed_accounts: Vec<AccountId> = vec![root_key.clone()];
@@ -154,12 +157,18 @@ pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Pu
.public()
}
/// Helper function to generate an account ID from seed
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId where
AccountPublic: From<<TPublic::Pair as Pair>::Public>
{
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}
/// Helper function to generate stash, controller and session key from seed
pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId) {
(
get_from_seed::<AccountId>(&format!("{}//stash", seed)),
get_from_seed::<AccountId>(seed),
get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
get_account_id_from_seed::<sr25519::Public>(seed),
get_from_seed::<GrandpaId>(seed),
get_from_seed::<BabeId>(seed),
get_from_seed::<ImOnlineId>(seed),
@@ -175,18 +184,18 @@ pub fn testnet_genesis(
) -> GenesisConfig {
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(|| {
vec![
get_from_seed::<AccountId>("Alice"),
get_from_seed::<AccountId>("Bob"),
get_from_seed::<AccountId>("Charlie"),
get_from_seed::<AccountId>("Dave"),
get_from_seed::<AccountId>("Eve"),
get_from_seed::<AccountId>("Ferdie"),
get_from_seed::<AccountId>("Alice//stash"),
get_from_seed::<AccountId>("Bob//stash"),
get_from_seed::<AccountId>("Charlie//stash"),
get_from_seed::<AccountId>("Dave//stash"),
get_from_seed::<AccountId>("Eve//stash"),
get_from_seed::<AccountId>("Ferdie//stash"),
get_account_id_from_seed::<sr25519::Public>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Bob"),
get_account_id_from_seed::<sr25519::Public>("Charlie"),
get_account_id_from_seed::<sr25519::Public>("Dave"),
get_account_id_from_seed::<sr25519::Public>("Eve"),
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
]
});
@@ -272,7 +281,7 @@ fn development_config_genesis() -> GenesisConfig {
vec![
get_authority_keys_from_seed("Alice"),
],
get_from_seed::<AccountId>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
true,
)
@@ -298,7 +307,7 @@ fn local_testnet_genesis() -> GenesisConfig {
get_authority_keys_from_seed("Alice"),
get_authority_keys_from_seed("Bob"),
],
get_from_seed::<AccountId>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
false,
)
@@ -330,7 +339,7 @@ pub(crate) mod tests {
vec![
get_authority_keys_from_seed("Alice"),
],
get_from_seed::<AccountId>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
false,
)
+9 -4
View File
@@ -25,16 +25,21 @@ use codec::{Encode, Decode};
use keyring::sr25519::Keyring;
use node_runtime::{
Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit,
MinimumPeriod,
MinimumPeriod
};
use node_primitives::Signature;
use primitives::{sr25519, crypto::Pair};
use sr_primitives::{generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension}};
use sr_primitives::{
generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension, Verify, IdentifyAccount}
};
use transaction_factory::RuntimeAdapter;
use transaction_factory::modes::Mode;
use inherents::InherentData;
use timestamp;
use finality_tracker;
type AccountPublic = <Signature as Verify>::Signer;
pub struct FactoryState<N> {
block_no: N,
@@ -167,7 +172,7 @@ impl RuntimeAdapter for FactoryState<Number> {
}
fn master_account_id() -> Self::AccountId {
Keyring::Alice.pair().public()
Keyring::Alice.to_account_id()
}
fn master_account_secret() -> Self::Secret {
@@ -177,7 +182,7 @@ impl RuntimeAdapter for FactoryState<Number> {
/// Generates a random `AccountId` from `seed`.
fn gen_random_account_id(seed: &Self::Number) -> Self::AccountId {
let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(*seed));
pair.public().into()
AccountPublic::from(pair.public()).into_account()
}
/// Generates a random `Secret` from `seed`.
+9 -8
View File
@@ -330,17 +330,15 @@ mod tests {
use consensus_common::{
Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport,
};
use node_primitives::{Block, DigestItem};
use node_runtime::{BalancesCall, Call, UncheckedExtrinsic};
use node_primitives::{Block, DigestItem, Signature};
use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address};
use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION};
use codec::{Encode, Decode};
use primitives::{
crypto::Pair as CryptoPair,
sr25519::Public as AddressPublic, H256,
};
use primitives::{crypto::Pair as CryptoPair, H256};
use sr_primitives::{
generic::{BlockId, Era, Digest, SignedPayload},
traits::Block as BlockT,
traits::Verify,
OpaqueExtrinsic,
};
use timestamp;
@@ -348,6 +346,9 @@ mod tests {
use keyring::AccountKeyring;
use substrate_service::{AbstractService, Roles};
use crate::service::new_full;
use sr_primitives::traits::IdentifyAccount;
type AccountPublic = <Signature as Verify>::Signer;
#[cfg(feature = "rhd")]
fn test_sync() {
@@ -518,8 +519,8 @@ mod tests {
},
|service, _| {
let amount = 5 * CENTS;
let to = AddressPublic::from_raw(bob.public().0);
let from = AddressPublic::from_raw(charlie.public().0);
let to: Address = AccountPublic::from(bob.public()).into_account().into();
let from: Address = AccountPublic::from(charlie.public()).into_account().into();
let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
let best_block_id = BlockId::number(service.client().info().chain.best_number);
let version = service.client().runtime_version_at(&best_block_id).unwrap().spec_version;