*: Refactor authority discovery (key mngmt, runtime API) (#3955)

* {core,srml}/authority-discovery: Move generic to specific session keys

* {srml,core}/authority-discovery: Verify signature outside of runtime

Given that the `core/authority-discovery` uses concrete authority
identifiers and signatures, one can verify a signature with the
authority discovery within `core`. Given the above, the `verify` runtime
api is obsolete and thus removed.

* *: Add authority discovery to the set of session keys

* *: Sign authority discovery DHT payload with keystore instead of runtime

Instead of calling a runtime function to sign a dht payload, which then
invokes the keystore, pass the keystore to the authority discovery
module and use it directly.

* core/authority-discovery: Give libp2p Kademlia time to start up

* core/authority-discovery: Move authorities priority group name to const

* node/runtime/src/lib.rs: Bump runtime spec version

* *: Fix lints and node/testing test failures

* *: Fix formatting

* core/authority-discovery: Box dht event channel in unit tests

* node/cli/src/service.rs: Fix future import

* node/cli/src/service.rs: Replace unwrap by expect with proof

* node/cli/src/chain_spec: Remove TODO for testnet key generation

* core/authority-discovery/src/lib: Remove scale encoding TODOs

* srml/authority-discovery: Make comment a doc comment

* core/authority-discovery: Remove unused StreamExt import

* node/runtime: Bump impl version to debug CI

* Test ci.

* Change the line width to 100.

* Revert "Change the line width to 100."

This reverts commit edff1f855bc71e0418bf3a967f81a35591d882e3.

* Fix a check for polkadot to work on forked repos.

* Revert "node/runtime: Bump impl version to debug CI"

This reverts commit 1a90903b4c929bc55a9e0a538af34b50b7f65139.

* Revert "Test ci."

This reverts commit a2c9df574e645158f77cd2b3d4d9355bcae33aab.

* Cargo.lock: Fix wrong lock file merge

* srml/authority-discovery: Keep track of new validator set not upcoming

* core/authority-discovery: Document key retrieval functions
This commit is contained in:
Max Inden
2019-11-14 14:14:06 +01:00
committed by Bastian Köcher
parent 64f7ed04dc
commit becc3b0a4f
17 changed files with 324 additions and 300 deletions
+4
View File
@@ -26,6 +26,7 @@ crate-type = ["cdylib", "rlib"]
codec = { package = "parity-scale-codec", version = "1.0.6" }
serde = { version = "1.0.102", features = [ "derive" ] }
futures = "0.1.29"
futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] }
hex-literal = "0.2.1"
jsonrpc-core = "14.0.3"
log = "0.4.8"
@@ -37,6 +38,7 @@ primitives = { package = "substrate-primitives", path = "../../core/primitives"
sr-primitives = { path = "../../core/sr-primitives" }
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives" }
grandpa_primitives = { package = "substrate-finality-grandpa-primitives", path = "../../core/finality-grandpa/primitives" }
authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/primitives"}
# core dependencies
runtime-io = { package = "sr-io", path = "../../core/sr-io" }
@@ -47,6 +49,7 @@ transaction_pool = { package = "substrate-transaction-pool", path = "../../core/
network = { package = "substrate-network", path = "../../core/network" }
babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe" }
grandpa = { package = "substrate-finality-grandpa", path = "../../core/finality-grandpa" }
authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"}
keyring = { package = "substrate-keyring", path = "../../core/keyring" }
client_db = { package = "substrate-client-db", path = "../../core/client/db", default-features = false }
offchain = { package = "substrate-offchain", path = "../../core/offchain" }
@@ -65,6 +68,7 @@ balances = { package = "srml-balances", path = "../../srml/balances" }
transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" }
support = { package = "srml-support", path = "../../srml/support", default-features = false }
im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false }
sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false }
# node-specific dependencies
node-runtime = { path = "../runtime" }
+34 -9
View File
@@ -20,9 +20,9 @@ use chain_spec::ChainSpecExtension;
use primitives::{Pair, Public, crypto::UncheckedInto, sr25519};
use serde::{Serialize, Deserialize};
use node_runtime::{
BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, GrandpaConfig,
ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig,
SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY,
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, SudoConfig,
SystemConfig, TechnicalCommitteeConfig, WASM_BINARY,
};
use node_runtime::Block;
use node_runtime::constants::currency::*;
@@ -32,6 +32,7 @@ use substrate_telemetry::TelemetryEndpoints;
use grandpa_primitives::{AuthorityId as GrandpaId};
use babe_primitives::{AuthorityId as BabeId};
use im_online::sr25519::{AuthorityId as ImOnlineId};
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use sr_primitives::{Perbill, traits::{Verify, IdentifyAccount}};
pub use node_primitives::{AccountId, Balance, Signature};
@@ -61,8 +62,13 @@ pub fn flaming_fir_config() -> Result<ChainSpec, String> {
ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..])
}
fn session_keys(grandpa: GrandpaId, babe: BabeId, im_online: ImOnlineId) -> SessionKeys {
SessionKeys { grandpa, babe, im_online, }
fn session_keys(
grandpa: GrandpaId,
babe: BabeId,
im_online: ImOnlineId,
authority_discovery: AuthorityDiscoveryId,
) -> SessionKeys {
SessionKeys { grandpa, babe, im_online, authority_discovery }
}
fn staging_testnet_config_genesis() -> GenesisConfig {
@@ -72,7 +78,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
// and
// for i in 1 2 3 4 ; do for j in session; do subkey --ed25519 inspect "$secret"//fir//$j//$i; done; done
let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)> = vec![(
let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId)> = vec![(
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].into(),
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
@@ -83,6 +89,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
),(
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].into(),
@@ -94,6 +102,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
),(
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].into(),
@@ -105,6 +115,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
),(
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].into(),
@@ -116,6 +128,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
)];
// generated with secret: subkey inspect "$secret"/fir
@@ -164,19 +178,27 @@ pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId where
}
/// 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) {
pub fn get_authority_keys_from_seed(seed: &str) -> (
AccountId,
AccountId,
GrandpaId,
BabeId,
ImOnlineId,
AuthorityDiscoveryId,
) {
(
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),
get_from_seed::<AuthorityDiscoveryId>(seed),
)
}
/// Helper function to create GenesisConfig for testing
pub fn testnet_genesis(
initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)>,
initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId)>,
root_key: AccountId,
endowed_accounts: Option<Vec<AccountId>>,
enable_println: bool,
@@ -220,7 +242,7 @@ pub fn testnet_genesis(
}),
session: Some(SessionConfig {
keys: initial_authorities.iter().map(|x| {
(x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))
(x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()))
}).collect::<Vec<_>>(),
}),
staking: Some(StakingConfig {
@@ -259,6 +281,9 @@ pub fn testnet_genesis(
im_online: Some(ImOnlineConfig {
keys: vec![],
}),
authority_discovery: Some(AuthorityDiscoveryConfig {
keys: vec![],
}),
grandpa: Some(GrandpaConfig {
authorities: vec![],
}),
+19 -1
View File
@@ -112,6 +112,11 @@ macro_rules! new_full {
($config:expr, $with_startup_data: expr) => {{
use futures::sync::mpsc;
use network::DhtEvent;
use futures03::{
compat::Stream01CompatExt,
stream::StreamExt,
future::{FutureExt, TryFutureExt},
};
let (
is_authority,
@@ -136,7 +141,7 @@ macro_rules! new_full {
// back-pressure. Authority discovery is triggering one event per authority within the current authority set.
// This estimates the authority set size to be somewhere below 10 000 thereby setting the channel buffer size to
// 10 000.
let (dht_event_tx, _dht_event_rx) =
let (dht_event_tx, dht_event_rx) =
mpsc::channel::<DhtEvent>(10_000);
let service = builder.with_network_protocol(|_| Ok(crate::service::NodeProtocol::new()))?
@@ -175,6 +180,19 @@ macro_rules! new_full {
let babe = babe::start_babe(babe_config)?;
service.spawn_essential_task(babe);
let future03_dht_event_rx = dht_event_rx.compat()
.map(|x| x.expect("<mpsc::channel::Receiver as Stream> never returns an error; qed"))
.boxed();
let authority_discovery = authority_discovery::AuthorityDiscovery::new(
service.client(),
service.network(),
service.keystore(),
future03_dht_event_rx,
);
let future01_authority_discovery = authority_discovery.map(|x| Ok(x)).compat();
service.spawn_task(future01_authority_discovery);
}
// if the node isn't actively participating in consensus then it doesn't
+4
View File
@@ -14,6 +14,7 @@ rustc-hex = { version = "2.0", optional = true }
serde = { version = "1.0.102", optional = true }
# primitives
authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/primitives", default-features = false }
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false }
node-primitives = { path = "../primitives", default-features = false }
offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false }
@@ -44,6 +45,7 @@ executive = { package = "srml-executive", path = "../../srml/executive", default
finality-tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false }
grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false }
im-online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false }
authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false }
indices = { package = "srml-indices", path = "../../srml/indices", default-features = false }
membership = { package = "srml-membership", path = "../../srml/membership", default-features = false }
nicks = { package = "srml-nicks", path = "../../srml/nicks", default-features = false }
@@ -71,6 +73,8 @@ runtime_io = { package = "sr-io", path = "../../core/sr-io" }
[features]
default = ["std"]
std = [
"authority-discovery/std",
"authority-discovery-primitives/std",
"authorship/std",
"babe-primitives/std",
"babe/std",
+13 -2
View File
@@ -42,6 +42,7 @@ use primitives::OpaqueMetadata;
use grandpa::AuthorityList as GrandpaAuthorityList;
use grandpa::fg_primitives;
use im_online::sr25519::{AuthorityId as ImOnlineId};
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
use contracts_rpc_runtime_api::ContractExecResult;
use system::offchain::TransactionSubmitter;
@@ -76,8 +77,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 193,
impl_version: 193,
spec_version: 194,
impl_version: 194,
apis: RUNTIME_API_VERSIONS,
};
@@ -209,6 +210,7 @@ impl_opaque_keys! {
pub grandpa: Grandpa,
pub babe: Babe,
pub im_online: ImOnline,
pub authority_discovery: AuthorityDiscovery,
}
}
@@ -433,6 +435,8 @@ impl offences::Trait for Runtime {
type OnOffenceHandler = Staking;
}
impl authority_discovery::Trait for Runtime {}
impl grandpa::Trait for Runtime {
type Event = Event;
}
@@ -521,6 +525,7 @@ construct_runtime!(
Contracts: contracts,
Sudo: sudo,
ImOnline: im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
AuthorityDiscovery: authority_discovery::{Module, Call, Config},
Offences: offences::{Module, Call, Storage, Event},
RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage},
Nicks: nicks::{Module, Call, Storage, Event<T>},
@@ -635,6 +640,12 @@ impl_runtime_apis! {
}
}
impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
fn authorities() -> Vec<AuthorityDiscoveryId> {
AuthorityDiscovery::authorities()
}
}
impl system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
fn account_nonce(account: AccountId) -> Index {
System::account_nonce(account)
+1
View File
@@ -89,6 +89,7 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig
authorities: vec![],
}),
im_online: Some(Default::default()),
authority_discovery: Some(Default::default()),
democracy: Some(Default::default()),
collective_Instance1: Some(Default::default()),
collective_Instance2: Some(Default::default()),
+1 -1
View File
@@ -59,6 +59,7 @@ pub fn to_session_keys(
grandpa: ed25519_keyring.to_owned().public().into(),
babe: sr25519_keyring.to_owned().public().into(),
im_online: sr25519_keyring.to_owned().public().into(),
authority_discovery: sr25519_keyring.to_owned().public().into(),
}
}
@@ -99,4 +100,3 @@ pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> Unche
},
}
}