mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 21:37:56 +00:00
2c0e73b78c
In order to have authorities (validators) discover each other, they need
to publish their public addresses by their ip address on the Kademlia
Dht indexed by their public key. This payload needs to be signed by a
key identifying them as a valid authority.
Code inside `/core` does not know the current set of authorities nor
can it assume what kind of cryptography primitives are currently in use.
Instead it can retrieve its public key and the current set of
authorities from the runtime and have it sign and verify Dht payloads.
This commit enables code in `/core` to do so by introducing a srml
module and runtime api to:
1. Retrieve own public key.
2. Retrieve public keys of current authority set.
3. Sign a Dht payload.
4. Verify a Dht payload.
This commit makes the logic from the previous commit
(`core/consensus/common/primitives.ConsensusApi`)
cf80af9255 obsolete and thus removes it.
401 lines
13 KiB
Rust
401 lines
13 KiB
Rust
// Copyright 2018-2019 Parity Technologies (UK) Ltd.
|
|
// This file is part of Substrate.
|
|
|
|
// Substrate is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// Substrate is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//! Substrate chain configurations.
|
|
|
|
use primitives::{Pair, Public, crypto::UncheckedInto};
|
|
pub use node_primitives::{AccountId, Balance};
|
|
use node_runtime::{
|
|
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
|
|
ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus,
|
|
StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY,
|
|
};
|
|
use node_runtime::constants::{time::*, currency::*};
|
|
pub use node_runtime::GenesisConfig;
|
|
use substrate_service;
|
|
use hex_literal::hex;
|
|
use substrate_telemetry::TelemetryEndpoints;
|
|
use grandpa_primitives::{AuthorityId as GrandpaId};
|
|
use babe_primitives::{AuthorityId as BabeId};
|
|
use im_online::AuthorityId as ImOnlineId;
|
|
use sr_primitives::Perbill;
|
|
|
|
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
|
|
|
/// Specialized `ChainSpec`.
|
|
pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
|
|
|
|
/// Flaming Fir testnet generator
|
|
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 staging_testnet_config_genesis() -> GenesisConfig {
|
|
// stash, controller, session-key
|
|
// generated with secret:
|
|
// for i in 1 2 3 4 ; do for j in stash controller; do subkey inspect "$secret"/fir/$j/$i; done; done
|
|
// 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![(
|
|
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
|
|
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(),
|
|
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
|
|
hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].unchecked_into(),
|
|
// 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC
|
|
hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(),
|
|
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
|
|
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
|
|
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
|
|
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
|
|
),(
|
|
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
|
|
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].unchecked_into(),
|
|
// 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF
|
|
hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].unchecked_into(),
|
|
// 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE
|
|
hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(),
|
|
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
|
|
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
|
|
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
|
|
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
|
|
),(
|
|
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
|
|
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].unchecked_into(),
|
|
// 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9
|
|
hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].unchecked_into(),
|
|
// 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d
|
|
hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(),
|
|
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
|
|
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
|
|
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
|
|
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
|
|
),(
|
|
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
|
|
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].unchecked_into(),
|
|
// 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn
|
|
hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].unchecked_into(),
|
|
// 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4
|
|
hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(),
|
|
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
|
|
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
|
|
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
|
|
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
|
|
)];
|
|
|
|
// generated with secret: subkey inspect "$secret"/fir
|
|
let endowed_accounts: Vec<AccountId> = vec![
|
|
// 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo
|
|
hex!["9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809"].unchecked_into(),
|
|
];
|
|
|
|
const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
|
|
const STASH: Balance = 100 * DOLLARS;
|
|
|
|
GenesisConfig {
|
|
system: Some(SystemConfig {
|
|
code: WASM_BINARY.to_vec(),
|
|
changes_trie_config: Default::default(),
|
|
}),
|
|
balances: Some(BalancesConfig {
|
|
balances: endowed_accounts.iter().cloned()
|
|
.map(|k| (k, ENDOWMENT))
|
|
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
|
.collect(),
|
|
vesting: vec![],
|
|
}),
|
|
indices: Some(IndicesConfig {
|
|
ids: endowed_accounts.iter().cloned()
|
|
.chain(initial_authorities.iter().map(|x| x.0.clone()))
|
|
.collect::<Vec<_>>(),
|
|
}),
|
|
session: Some(SessionConfig {
|
|
keys: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))
|
|
}).collect::<Vec<_>>(),
|
|
}),
|
|
staking: Some(StakingConfig {
|
|
current_era: 0,
|
|
validator_count: 7,
|
|
minimum_validator_count: 4,
|
|
stakers: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)
|
|
}).collect(),
|
|
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
|
slash_reward_fraction: Perbill::from_percent(10),
|
|
.. Default::default()
|
|
}),
|
|
democracy: Some(DemocracyConfig::default()),
|
|
collective_Instance1: Some(CouncilConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
collective_Instance2: Some(TechnicalCommitteeConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
elections: Some(ElectionsConfig {
|
|
members: vec![],
|
|
presentation_duration: 1 * DAYS,
|
|
term_duration: 28 * DAYS,
|
|
desired_seats: 0,
|
|
}),
|
|
contracts: Some(ContractsConfig {
|
|
current_schedule: Default::default(),
|
|
gas_price: 1 * MILLICENTS,
|
|
}),
|
|
sudo: Some(SudoConfig {
|
|
key: endowed_accounts[0].clone(),
|
|
}),
|
|
babe: Some(BabeConfig {
|
|
authorities: vec![],
|
|
}),
|
|
im_online: Some(ImOnlineConfig {
|
|
keys: vec![],
|
|
}),
|
|
authority_discovery: Some(AuthorityDiscoveryConfig{
|
|
keys: vec![],
|
|
}),
|
|
grandpa: Some(GrandpaConfig {
|
|
authorities: vec![],
|
|
}),
|
|
membership_Instance1: Some(Default::default()),
|
|
}
|
|
}
|
|
|
|
/// Staging testnet config.
|
|
pub fn staging_testnet_config() -> ChainSpec {
|
|
let boot_nodes = vec![];
|
|
ChainSpec::from_genesis(
|
|
"Staging Testnet",
|
|
"staging_testnet",
|
|
staging_testnet_config_genesis,
|
|
boot_nodes,
|
|
Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])),
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
/// Helper function to generate a crypto pair from seed
|
|
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
|
|
TPublic::Pair::from_string(&format!("//{}", seed), None)
|
|
.expect("static values are valid; qed")
|
|
.public()
|
|
}
|
|
|
|
|
|
/// 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_from_seed::<GrandpaId>(seed),
|
|
get_from_seed::<BabeId>(seed),
|
|
get_from_seed::<ImOnlineId>(seed),
|
|
)
|
|
}
|
|
|
|
/// Helper function to create GenesisConfig for testing
|
|
pub fn testnet_genesis(
|
|
initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)>,
|
|
root_key: AccountId,
|
|
endowed_accounts: Option<Vec<AccountId>>,
|
|
enable_println: bool,
|
|
) -> 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"),
|
|
]
|
|
});
|
|
|
|
const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
|
|
const STASH: Balance = 100 * DOLLARS;
|
|
|
|
let desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32;
|
|
|
|
GenesisConfig {
|
|
system: Some(SystemConfig {
|
|
code: WASM_BINARY.to_vec(),
|
|
changes_trie_config: Default::default(),
|
|
}),
|
|
indices: Some(IndicesConfig {
|
|
ids: endowed_accounts.clone(),
|
|
}),
|
|
balances: Some(BalancesConfig {
|
|
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
|
vesting: vec![],
|
|
}),
|
|
session: Some(SessionConfig {
|
|
keys: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))
|
|
}).collect::<Vec<_>>(),
|
|
}),
|
|
staking: Some(StakingConfig {
|
|
current_era: 0,
|
|
minimum_validator_count: 1,
|
|
validator_count: 2,
|
|
stakers: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)
|
|
}).collect(),
|
|
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
|
slash_reward_fraction: Perbill::from_percent(10),
|
|
.. Default::default()
|
|
}),
|
|
democracy: Some(DemocracyConfig::default()),
|
|
collective_Instance1: Some(CouncilConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
collective_Instance2: Some(TechnicalCommitteeConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
elections: Some(ElectionsConfig {
|
|
members: endowed_accounts.iter()
|
|
.filter(|&endowed| initial_authorities.iter().find(|&(_, controller, ..)| controller == endowed).is_none())
|
|
.map(|a| (a.clone(), 1000000)).collect(),
|
|
presentation_duration: 10,
|
|
term_duration: 1000000,
|
|
desired_seats: desired_seats,
|
|
}),
|
|
contracts: Some(ContractsConfig {
|
|
current_schedule: contracts::Schedule {
|
|
enable_println, // this should only be enabled on development chains
|
|
..Default::default()
|
|
},
|
|
gas_price: 1 * MILLICENTS,
|
|
}),
|
|
sudo: Some(SudoConfig {
|
|
key: root_key,
|
|
}),
|
|
babe: Some(BabeConfig {
|
|
authorities: vec![],
|
|
}),
|
|
im_online: Some(ImOnlineConfig {
|
|
keys: vec![],
|
|
}),
|
|
authority_discovery: Some(AuthorityDiscoveryConfig{
|
|
keys: vec![],
|
|
}),
|
|
grandpa: Some(GrandpaConfig {
|
|
authorities: vec![],
|
|
}),
|
|
membership_Instance1: Some(Default::default()),
|
|
}
|
|
}
|
|
|
|
fn development_config_genesis() -> GenesisConfig {
|
|
testnet_genesis(
|
|
vec![
|
|
get_authority_keys_from_seed("Alice"),
|
|
],
|
|
get_from_seed::<AccountId>("Alice"),
|
|
None,
|
|
true,
|
|
)
|
|
}
|
|
|
|
/// Development config (single validator Alice)
|
|
pub fn development_config() -> ChainSpec {
|
|
ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None)
|
|
}
|
|
|
|
fn local_testnet_genesis() -> GenesisConfig {
|
|
testnet_genesis(
|
|
vec![
|
|
get_authority_keys_from_seed("Alice"),
|
|
get_authority_keys_from_seed("Bob"),
|
|
],
|
|
get_from_seed::<AccountId>("Alice"),
|
|
None,
|
|
false,
|
|
)
|
|
}
|
|
|
|
/// Local testnet config (multivalidator Alice + Bob)
|
|
pub fn local_testnet_config() -> ChainSpec {
|
|
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub(crate) mod tests {
|
|
use super::*;
|
|
use service_test;
|
|
use crate::service::Factory;
|
|
|
|
fn local_testnet_genesis_instant_single() -> GenesisConfig {
|
|
testnet_genesis(
|
|
vec![
|
|
get_authority_keys_from_seed("Alice"),
|
|
],
|
|
get_from_seed::<AccountId>("Alice"),
|
|
None,
|
|
false,
|
|
)
|
|
}
|
|
|
|
/// Local testnet config (single validator - Alice)
|
|
pub fn integration_test_config_with_single_authority() -> ChainSpec {
|
|
ChainSpec::from_genesis(
|
|
"Integration Test",
|
|
"test",
|
|
local_testnet_genesis_instant_single,
|
|
vec![],
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
/// Local testnet config (multivalidator Alice + Bob)
|
|
pub fn integration_test_config_with_two_authorities() -> ChainSpec {
|
|
ChainSpec::from_genesis(
|
|
"Integration Test",
|
|
"test",
|
|
local_testnet_genesis,
|
|
vec![],
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn test_connectivity() {
|
|
service_test::connectivity::<Factory>(integration_test_config_with_two_authorities());
|
|
}
|
|
}
|