mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 10:41:09 +00:00
Use BABE instead of AuRa in node (#3171)
* babe: add babe module trait * babe: track current slot and epoch start slot * babe: implement ShouldEndSession based on epochs * babe: rename weight type to avoid ambiguities * babe: expose epoch start slot in Epoch digest * babe: use epoch start for validating epoch transitions * babe: make the epoch duration a parameter type * babe: remove unused fields from config * node: update runtime to use babe instead of aura * node: use babe instead of aura * core: generate sr25519 keys from seed and add to keystore * core: remove AuthorityKeyring * node: remove unused primitive types related to babe crypto * uniform babe primitives crate import name * wrap long lines * babe: fix find_epoch_digest * fork-tree: fix find_node_where * node: set babe epoch duration to "10 minutes" * babe: cleanup import key cache if authorities don't change * node: make integration test compile (but fail) * node: bump spec_version * node: fix import * babe: don't use constants in storage fields array sizes * babe: account for first epoch slot way in the past * babe: signal next epoch change (not current) * babe: calculate next epoch randomness with next epoch index * babe: track next epoch in node * babe: cache current epoch and authorities separately * babe: generate valid babe vrf proofs in integration test * babe: cleanup claim_slot * babe: perform threshold calculation according to spec * babe: compute relative weight in threshold * babe: more precise threshold calculation * babe: use floats for threshold exponent calculation * babe: update constant c
This commit is contained in:
committed by
DemiMarie-parity
parent
407970406d
commit
9f50c8fce4
@@ -24,8 +24,8 @@ substrate-basic-authorship = { path = "../../core/basic-authorship" }
|
||||
substrate-service = { path = "../../core/service" }
|
||||
transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" }
|
||||
network = { package = "substrate-network", path = "../../core/network" }
|
||||
aura = { package = "substrate-consensus-aura", path = "../../core/consensus/aura" }
|
||||
aura_primitives = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives" }
|
||||
babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe" }
|
||||
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives" }
|
||||
grandpa = { package = "substrate-finality-grandpa", path = "../../core/finality-grandpa" }
|
||||
grandpa_primitives = { package = "substrate-finality-grandpa-primitives", path = "../../core/finality-grandpa/primitives" }
|
||||
sr-primitives = { path = "../../core/sr-primitives" }
|
||||
@@ -44,6 +44,7 @@ system = { package = "srml-system", path = "../../srml/system" }
|
||||
balances = { package = "srml-balances", path = "../../srml/balances" }
|
||||
|
||||
[dev-dependencies]
|
||||
babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] }
|
||||
consensus-common = { package = "substrate-consensus-common", path = "../../core/consensus/common" }
|
||||
service-test = { package = "substrate-service-test", path = "../../core/service/test" }
|
||||
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
|
||||
//! Substrate chain configurations.
|
||||
|
||||
use babe_primitives::AuthorityId as BabeId;
|
||||
use primitives::{ed25519, sr25519, Pair, crypto::UncheckedInto};
|
||||
use node_primitives::{AccountId, AuraId, Balance};
|
||||
use node_primitives::{AccountId, Balance};
|
||||
use node_runtime::{
|
||||
GrandpaConfig, BalancesConfig, ContractsConfig, ElectionsConfig, DemocracyConfig,
|
||||
CouncilConfig, AuraConfig, ImOnlineConfig, IndicesConfig, SessionConfig, StakingConfig,
|
||||
SudoConfig, TechnicalCommitteeConfig, SystemConfig, WASM_BINARY, Perbill, SessionKeys,
|
||||
StakerStatus, DAYS, DOLLARS, MILLICENTS,
|
||||
BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
|
||||
ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, Perbill,
|
||||
SessionConfig, SessionKeys, StakerStatus, StakingConfig, SudoConfig, SystemConfig,
|
||||
TechnicalCommitteeConfig, DAYS, DOLLARS, MILLICENTS, WASM_BINARY,
|
||||
};
|
||||
pub use node_runtime::GenesisConfig;
|
||||
use substrate_service;
|
||||
@@ -40,8 +41,11 @@ pub fn flaming_fir_config() -> Result<ChainSpec, String> {
|
||||
ChainSpec::from_embedded(include_bytes!("../res/flaming-fir.json"))
|
||||
}
|
||||
|
||||
fn session_keys(key: ed25519::Public) -> SessionKeys {
|
||||
SessionKeys { ed25519: key }
|
||||
fn session_keys(ed_key: ed25519::Public, sr_key: sr25519::Public) -> SessionKeys {
|
||||
SessionKeys {
|
||||
ed25519: ed_key,
|
||||
sr25519: sr_key,
|
||||
}
|
||||
}
|
||||
|
||||
fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
@@ -51,7 +55,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, AuraId, GrandpaId)> = vec![(
|
||||
let initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId)> = vec![(
|
||||
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
|
||||
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(),
|
||||
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
|
||||
@@ -116,7 +120,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
.collect::<Vec<_>>(),
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (x.0.clone(), session_keys(x.2.clone()))).collect::<Vec<_>>(),
|
||||
keys: initial_authorities.iter().map(|x| {
|
||||
(x.0.clone(), session_keys(x.3.clone(), x.2.clone()))
|
||||
}).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
current_era: 0,
|
||||
@@ -124,7 +130,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
validator_count: 7,
|
||||
offline_slash_grace: 4,
|
||||
minimum_validator_count: 4,
|
||||
stakers: initial_authorities.iter().map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)).collect(),
|
||||
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(),
|
||||
}),
|
||||
democracy: Some(DemocracyConfig::default()),
|
||||
@@ -149,8 +157,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
sudo: Some(SudoConfig {
|
||||
key: endowed_accounts[0].clone(),
|
||||
}),
|
||||
aura: Some(AuraConfig {
|
||||
authorities: initial_authorities.iter().map(|x| x.2.clone()).collect(),
|
||||
babe: Some(BabeConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(),
|
||||
}),
|
||||
im_online: Some(ImOnlineConfig {
|
||||
gossip_at: 0,
|
||||
@@ -184,9 +192,9 @@ pub fn get_account_id_from_seed(seed: &str) -> AccountId {
|
||||
.public()
|
||||
}
|
||||
|
||||
/// Helper function to generate AuraId from seed
|
||||
pub fn get_aura_id_from_seed(seed: &str) -> AuraId {
|
||||
ed25519::Pair::from_string(&format!("//{}", seed), None)
|
||||
/// Helper function to generate BabeId from seed
|
||||
pub fn get_babe_id_from_seed(seed: &str) -> BabeId {
|
||||
sr25519::Pair::from_string(&format!("//{}", seed), None)
|
||||
.expect("static values are valid; qed")
|
||||
.public()
|
||||
}
|
||||
@@ -199,18 +207,18 @@ pub fn get_grandpa_id_from_seed(seed: &str) -> GrandpaId {
|
||||
}
|
||||
|
||||
/// Helper function to generate stash, controller and session key from seed
|
||||
pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, AuraId, GrandpaId) {
|
||||
pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, BabeId, GrandpaId) {
|
||||
(
|
||||
get_account_id_from_seed(&format!("{}//stash", seed)),
|
||||
get_account_id_from_seed(seed),
|
||||
get_aura_id_from_seed(seed),
|
||||
get_babe_id_from_seed(seed),
|
||||
get_grandpa_id_from_seed(seed)
|
||||
)
|
||||
}
|
||||
|
||||
/// Helper function to create GenesisConfig for testing
|
||||
pub fn testnet_genesis(
|
||||
initial_authorities: Vec<(AccountId, AccountId, AuraId, GrandpaId)>,
|
||||
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
enable_println: bool,
|
||||
@@ -250,7 +258,9 @@ pub fn testnet_genesis(
|
||||
vesting: vec![],
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (x.0.clone(), session_keys(x.2.clone()))).collect::<Vec<_>>(),
|
||||
keys: initial_authorities.iter().map(|x| {
|
||||
(x.0.clone(), session_keys(x.3.clone(), x.2.clone()))
|
||||
}).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
current_era: 0,
|
||||
@@ -258,7 +268,9 @@ pub fn testnet_genesis(
|
||||
validator_count: 2,
|
||||
offline_slash: Perbill::zero(),
|
||||
offline_slash_grace: 0,
|
||||
stakers: initial_authorities.iter().map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)).collect(),
|
||||
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(),
|
||||
}),
|
||||
democracy: Some(DemocracyConfig::default()),
|
||||
@@ -288,8 +300,8 @@ pub fn testnet_genesis(
|
||||
sudo: Some(SudoConfig {
|
||||
key: root_key,
|
||||
}),
|
||||
aura: Some(AuraConfig {
|
||||
authorities: initial_authorities.iter().map(|x| x.2.clone()).collect(),
|
||||
babe: Some(BabeConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(),
|
||||
}),
|
||||
im_online: Some(ImOnlineConfig{
|
||||
gossip_at: 0,
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use aura::{import_queue, start_aura, AuraImportQueue, SlotDuration};
|
||||
use babe::{import_queue, start_babe, BabeImportQueue, Config};
|
||||
use babe_primitives::AuthorityPair as BabePair;
|
||||
use client::{self, LongestChain};
|
||||
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
|
||||
use node_executor;
|
||||
use primitives::Pair;
|
||||
use grandpa_primitives::AuthorityPair as GrandpaPair;
|
||||
use futures::prelude::*;
|
||||
use node_primitives::{AuraPair, Block};
|
||||
use node_primitives::Block;
|
||||
use node_runtime::{GenesisConfig, RuntimeApi};
|
||||
use substrate_service::{
|
||||
FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
|
||||
@@ -47,19 +48,40 @@ construct_simple_protocol! {
|
||||
pub struct NodeProtocol where Block = Block { }
|
||||
}
|
||||
|
||||
type BabeBlockImportForService<F> = babe::BabeBlockImport<
|
||||
FullBackend<F>,
|
||||
FullExecutor<F>,
|
||||
<F as crate::ServiceFactory>::Block,
|
||||
grandpa::BlockImportForService<F>,
|
||||
<F as crate::ServiceFactory>::RuntimeApi,
|
||||
client::Client<
|
||||
FullBackend<F>,
|
||||
FullExecutor<F>,
|
||||
<F as crate::ServiceFactory>::Block,
|
||||
<F as crate::ServiceFactory>::RuntimeApi
|
||||
>,
|
||||
>;
|
||||
|
||||
/// Node specific configuration
|
||||
pub struct NodeConfig<F: substrate_service::ServiceFactory> {
|
||||
/// grandpa connection to import block
|
||||
/// GRANDPA and BABE connection to import block.
|
||||
// FIXME #1134 rather than putting this on the config, let's have an actual intermediate setup state
|
||||
pub grandpa_import_setup: Option<(grandpa::BlockImportForService<F>, grandpa::LinkHalfForService<F>)>,
|
||||
pub import_setup: Option<(
|
||||
BabeBlockImportForService<F>,
|
||||
grandpa::LinkHalfForService<F>,
|
||||
babe::BabeLink,
|
||||
)>,
|
||||
/// Tasks that were created by previous setup steps and should be spawned.
|
||||
pub tasks_to_spawn: Option<Vec<Box<dyn Future<Item = (), Error = ()> + Send>>>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
}
|
||||
|
||||
impl<F> Default for NodeConfig<F> where F: substrate_service::ServiceFactory {
|
||||
fn default() -> NodeConfig<F> {
|
||||
NodeConfig {
|
||||
grandpa_import_setup: None,
|
||||
import_setup: None,
|
||||
inherent_data_providers: InherentDataProviders::new(),
|
||||
tasks_to_spawn: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +89,7 @@ impl<F> Default for NodeConfig<F> where F: substrate_service::ServiceFactory {
|
||||
construct_service_factory! {
|
||||
struct Factory {
|
||||
Block = Block,
|
||||
ConsensusPair = AuraPair,
|
||||
ConsensusPair = BabePair,
|
||||
FinalityPair = GrandpaPair,
|
||||
RuntimeApi = RuntimeApi,
|
||||
NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) },
|
||||
@@ -83,11 +105,22 @@ construct_service_factory! {
|
||||
FullComponents::<Factory>::new(config) },
|
||||
AuthoritySetup = {
|
||||
|mut service: Self::FullService| {
|
||||
let (block_import, link_half) = service.config.custom.grandpa_import_setup.take()
|
||||
let (block_import, link_half, babe_link) = service.config.custom.import_setup.take()
|
||||
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
|
||||
|
||||
if let Some(aura_key) = service.authority_key() {
|
||||
info!("Using aura key {}", aura_key.public());
|
||||
// spawn any futures that were created in the previous setup steps
|
||||
if let Some(tasks) = service.config.custom.tasks_to_spawn.take() {
|
||||
for task in tasks {
|
||||
service.spawn_task(
|
||||
task.select(service.on_exit())
|
||||
.map(|_| ())
|
||||
.map_err(|_| ())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(babe_key) = service.authority_key() {
|
||||
info!("Using BABE key {}", babe_key.public());
|
||||
|
||||
let proposer = Arc::new(substrate_basic_authorship::ProposerFactory {
|
||||
client: service.client(),
|
||||
@@ -98,18 +131,21 @@ construct_service_factory! {
|
||||
let select_chain = service.select_chain()
|
||||
.ok_or(ServiceError::SelectChainRequired)?;
|
||||
|
||||
let aura = start_aura(
|
||||
SlotDuration::get_or_compute(&*client)?,
|
||||
Arc::new(aura_key),
|
||||
let babe_config = babe::BabeParams {
|
||||
config: Config::get_or_compute(&*client)?,
|
||||
local_key: Arc::new(babe_key),
|
||||
client,
|
||||
select_chain,
|
||||
block_import,
|
||||
proposer,
|
||||
service.network(),
|
||||
service.config.custom.inherent_data_providers.clone(),
|
||||
service.config.force_authoring,
|
||||
)?;
|
||||
let select = aura.select(service.on_exit()).then(|_| Ok(()));
|
||||
env: proposer,
|
||||
sync_oracle: service.network(),
|
||||
inherent_data_providers: service.config.custom.inherent_data_providers.clone(),
|
||||
force_authoring: service.config.force_authoring,
|
||||
time_source: babe_link,
|
||||
};
|
||||
|
||||
let babe = start_babe(babe_config)?;
|
||||
let select = babe.select(service.on_exit()).then(|_| Ok(()));
|
||||
service.spawn_task(Box::new(select));
|
||||
}
|
||||
|
||||
@@ -158,27 +194,30 @@ construct_service_factory! {
|
||||
},
|
||||
LightService = LightComponents<Self>
|
||||
{ |config| <LightComponents<Factory>>::new(config) },
|
||||
FullImportQueue = AuraImportQueue<Self::Block>
|
||||
FullImportQueue = BabeImportQueue<Self::Block>
|
||||
{ |config: &mut FactoryFullConfiguration<Self> , client: Arc<FullClient<Self>>, select_chain: Self::SelectChain| {
|
||||
let slot_duration = SlotDuration::get_or_compute(&*client)?;
|
||||
let (block_import, link_half) =
|
||||
grandpa::block_import::<_, _, _, RuntimeApi, FullClient<Self>, _>(
|
||||
client.clone(), client.clone(), select_chain
|
||||
)?;
|
||||
let justification_import = block_import.clone();
|
||||
|
||||
config.custom.grandpa_import_setup = Some((block_import.clone(), link_half));
|
||||
|
||||
import_queue::<_, _, AuraPair>(
|
||||
slot_duration,
|
||||
Box::new(block_import),
|
||||
let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue(
|
||||
Config::get_or_compute(&*client)?,
|
||||
block_import,
|
||||
Some(Box::new(justification_import)),
|
||||
None,
|
||||
client.clone(),
|
||||
client,
|
||||
config.custom.inherent_data_providers.clone(),
|
||||
).map_err(Into::into)
|
||||
)?;
|
||||
|
||||
config.custom.import_setup = Some((babe_block_import.clone(), link_half, babe_link));
|
||||
config.custom.tasks_to_spawn = Some(vec![Box::new(pruning_task)]);
|
||||
|
||||
Ok(import_queue)
|
||||
}},
|
||||
LightImportQueue = AuraImportQueue<Self::Block>
|
||||
LightImportQueue = BabeImportQueue<Self::Block>
|
||||
{ |config: &FactoryFullConfiguration<Self>, client: Arc<LightClient<Self>>| {
|
||||
#[allow(deprecated)]
|
||||
let fetch_checker = client.backend().blockchain().fetcher()
|
||||
@@ -188,17 +227,22 @@ construct_service_factory! {
|
||||
let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, LightClient<Self>>(
|
||||
client.clone(), Arc::new(fetch_checker), client.clone()
|
||||
)?;
|
||||
|
||||
let finality_proof_import = block_import.clone();
|
||||
let finality_proof_request_builder = finality_proof_import.create_finality_proof_request_builder();
|
||||
|
||||
import_queue::<_, _, AuraPair>(
|
||||
SlotDuration::get_or_compute(&*client)?,
|
||||
Box::new(block_import),
|
||||
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
||||
let (import_queue, ..) = import_queue(
|
||||
Config::get_or_compute(&*client)?,
|
||||
block_import,
|
||||
None,
|
||||
Some(Box::new(finality_proof_import)),
|
||||
client.clone(),
|
||||
client,
|
||||
config.custom.inherent_data_providers.clone(),
|
||||
).map(|q| (q, finality_proof_request_builder)).map_err(Into::into)
|
||||
)?;
|
||||
|
||||
Ok((import_queue, finality_proof_request_builder))
|
||||
}},
|
||||
SelectChain = LongestChain<FullBackend<Self>, Self::Block>
|
||||
{ |config: &FactoryFullConfiguration<Self>, client: Arc<FullClient<Self>>| {
|
||||
@@ -216,25 +260,27 @@ construct_service_factory! {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
use aura::CompatibleDigestItem;
|
||||
use babe::CompatibleDigestItem;
|
||||
use consensus_common::{Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy};
|
||||
use node_primitives::DigestItem;
|
||||
use node_runtime::{BalancesCall, Call, CENTS, SECS_PER_BLOCK, UncheckedExtrinsic};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use primitives::{
|
||||
crypto::Pair as CryptoPair, ed25519::Pair, blake2_256,
|
||||
crypto::Pair as CryptoPair, blake2_256,
|
||||
sr25519::Public as AddressPublic, H256,
|
||||
};
|
||||
use sr_primitives::{generic::{BlockId, Era, Digest}, traits::Block, OpaqueExtrinsic};
|
||||
use timestamp;
|
||||
use finality_tracker;
|
||||
use keyring::{ed25519::Keyring as AuthorityKeyring, sr25519::Keyring as AccountKeyring};
|
||||
use keyring::{AccountKeyring, Sr25519Keyring};
|
||||
use substrate_service::ServiceFactory;
|
||||
use service_test::SyncService;
|
||||
use crate::service::Factory;
|
||||
|
||||
#[cfg(feature = "rhd")]
|
||||
fn test_sync() {
|
||||
use primitives::ed25519::Pair;
|
||||
|
||||
use {service_test, Factory};
|
||||
use client::{BlockImportParams, BlockOrigin};
|
||||
|
||||
@@ -294,7 +340,7 @@ mod tests {
|
||||
fn test_sync() {
|
||||
let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
|
||||
|
||||
let alice = Arc::new(AuthorityKeyring::Alice.pair());
|
||||
let alice = Arc::new(Sr25519Keyring::Alice.pair());
|
||||
let mut slot_num = 1u64;
|
||||
let block_factory = |service: &SyncService<<Factory as ServiceFactory>::FullService>| {
|
||||
let service = service.get();
|
||||
@@ -305,7 +351,6 @@ mod tests {
|
||||
.create_inherent_data()
|
||||
.expect("Creates inherent data.");
|
||||
inherent_data.replace_data(finality_tracker::INHERENT_IDENTIFIER, &1u64);
|
||||
inherent_data.replace_data(timestamp::INHERENT_IDENTIFIER, &(slot_num * SECS_PER_BLOCK));
|
||||
|
||||
let parent_id = BlockId::number(service.client().info().chain.best_number);
|
||||
let parent_header = service.client().header(&parent_id).unwrap().unwrap();
|
||||
@@ -315,7 +360,26 @@ mod tests {
|
||||
});
|
||||
|
||||
let mut digest = Digest::<H256>::default();
|
||||
digest.push(<DigestItem as CompatibleDigestItem<Pair>>::aura_pre_digest(slot_num));
|
||||
|
||||
// even though there's only one authority some slots might be empty,
|
||||
// so we must keep trying the next slots until we can claim one.
|
||||
let babe_pre_digest = loop {
|
||||
inherent_data.replace_data(timestamp::INHERENT_IDENTIFIER, &(slot_num * SECS_PER_BLOCK));
|
||||
if let Some(babe_pre_digest) = babe::test_helpers::claim_slot(
|
||||
&*service.client(),
|
||||
&parent_id,
|
||||
slot_num,
|
||||
&alice,
|
||||
(3, 10),
|
||||
) {
|
||||
break babe_pre_digest;
|
||||
}
|
||||
|
||||
slot_num += 1;
|
||||
};
|
||||
|
||||
digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(babe_pre_digest));
|
||||
|
||||
let proposer = proposer_factory.init(&parent_header).unwrap();
|
||||
let new_block = proposer.propose(
|
||||
inherent_data,
|
||||
@@ -329,7 +393,7 @@ mod tests {
|
||||
// add it to a digest item.
|
||||
let to_sign = pre_hash.encode();
|
||||
let signature = alice.sign(&to_sign[..]);
|
||||
let item = <DigestItem as CompatibleDigestItem<Pair>>::aura_seal(
|
||||
let item = <DigestItem as CompatibleDigestItem>::babe_seal(
|
||||
signature,
|
||||
);
|
||||
slot_num += 1;
|
||||
|
||||
@@ -39,7 +39,7 @@ mod tests {
|
||||
use super::Executor;
|
||||
use substrate_executor::{WasmExecutor, NativeExecutionDispatch};
|
||||
use parity_codec::{Encode, Decode, Joiner};
|
||||
use keyring::{AuthorityKeyring, AccountKeyring};
|
||||
use keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring};
|
||||
use runtime_support::{Hashable, StorageValue, StorageMap, traits::{Currency, Get}};
|
||||
use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities};
|
||||
use primitives::{
|
||||
@@ -314,15 +314,19 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
fn to_session_keys(ring: &AuthorityKeyring) -> SessionKeys {
|
||||
fn to_session_keys(
|
||||
ed25519_keyring: &Ed25519Keyring,
|
||||
sr25519_keyring: &Sr25519Keyring,
|
||||
) -> SessionKeys {
|
||||
SessionKeys {
|
||||
ed25519: ring.to_owned().into(),
|
||||
ed25519: ed25519_keyring.to_owned().into(),
|
||||
sr25519: sr25519_keyring.to_owned().into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalities<Blake2Hasher> {
|
||||
let mut ext = TestExternalities::new_with_code_with_children(code, GenesisConfig {
|
||||
aura: Some(Default::default()),
|
||||
babe: Some(Default::default()),
|
||||
system: Some(SystemConfig {
|
||||
changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration {
|
||||
digest_interval: 2,
|
||||
@@ -346,9 +350,18 @@ mod tests {
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
keys: vec![
|
||||
(alice(), to_session_keys(&AuthorityKeyring::Alice)),
|
||||
(bob(), to_session_keys(&AuthorityKeyring::Bob)),
|
||||
(charlie(), to_session_keys(&AuthorityKeyring::Charlie)),
|
||||
(alice(), to_session_keys(
|
||||
&Ed25519Keyring::Alice,
|
||||
&Sr25519Keyring::Alice,
|
||||
)),
|
||||
(bob(), to_session_keys(
|
||||
&Ed25519Keyring::Bob,
|
||||
&Sr25519Keyring::Bob,
|
||||
)),
|
||||
(charlie(), to_session_keys(
|
||||
&Ed25519Keyring::Charlie,
|
||||
&Sr25519Keyring::Charlie,
|
||||
)),
|
||||
]
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
|
||||
@@ -44,16 +44,6 @@ pub type Balance = u128;
|
||||
/// Type used for expressing timestamp.
|
||||
pub type Moment = u64;
|
||||
|
||||
/// The aura crypto scheme defined via the keypair type.
|
||||
#[cfg(feature = "std")]
|
||||
pub type AuraPair = primitives::ed25519::Pair;
|
||||
|
||||
/// Identity of an Aura authority.
|
||||
pub type AuraId = primitives::ed25519::Public;
|
||||
|
||||
/// Signature for an Aura authority.
|
||||
pub type AuraSignature = primitives::ed25519::Signature;
|
||||
|
||||
/// Index of a transaction in the chain.
|
||||
pub type Index = u64;
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ runtime_primitives = { package = "sr-primitives", path = "../../core/sr-primitiv
|
||||
offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false }
|
||||
version = { package = "sr-version", path = "../../core/sr-version", default-features = false }
|
||||
support = { package = "srml-support", path = "../../srml/support", default-features = false }
|
||||
aura = { package = "srml-aura", path = "../../srml/aura", default-features = false }
|
||||
authorship = { package = "srml-authorship", path = "../../srml/authorship", default-features = false }
|
||||
babe = { package = "srml-babe", path = "../../srml/babe", default-features = false }
|
||||
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false }
|
||||
balances = { package = "srml-balances", path = "../../srml/balances", default-features = false }
|
||||
contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false }
|
||||
collective = { package = "srml-collective", path = "../../srml/collective", default-features = false }
|
||||
@@ -35,7 +36,6 @@ treasury = { package = "srml-treasury", path = "../../srml/treasury", default-fe
|
||||
sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false }
|
||||
im-online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false }
|
||||
node-primitives = { path = "../primitives", default-features = false }
|
||||
consensus_aura = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default-features = false }
|
||||
rustc-hex = { version = "2.0", optional = true }
|
||||
serde = { version = "1.0", optional = true }
|
||||
substrate-keyring = { path = "../../core/keyring", optional = true }
|
||||
@@ -54,8 +54,9 @@ std = [
|
||||
"rstd/std",
|
||||
"runtime_primitives/std",
|
||||
"support/std",
|
||||
"aura/std",
|
||||
"authorship/std",
|
||||
"babe/std",
|
||||
"babe-primitives/std",
|
||||
"balances/std",
|
||||
"contracts/std",
|
||||
"collective/std",
|
||||
@@ -76,7 +77,6 @@ std = [
|
||||
"serde",
|
||||
"safe-mix/std",
|
||||
"client/std",
|
||||
"consensus_aura/std",
|
||||
"rustc-hex",
|
||||
"substrate-keyring",
|
||||
"offchain-primitives/std",
|
||||
|
||||
@@ -26,9 +26,10 @@ use support::{
|
||||
};
|
||||
use substrate_primitives::u32_trait::{_1, _2, _3, _4};
|
||||
use node_primitives::{
|
||||
AccountId, AccountIndex, AuraId, Balance, BlockNumber, Hash, Index,
|
||||
AccountId, AccountIndex, Balance, BlockNumber, Hash, Index,
|
||||
Moment, Signature,
|
||||
};
|
||||
use babe::{AuthorityId as BabeId};
|
||||
use grandpa::fg_primitives::{self, ScheduledChange};
|
||||
use client::{
|
||||
block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult},
|
||||
@@ -137,9 +138,12 @@ impl system::Trait for Runtime {
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
}
|
||||
|
||||
impl aura::Trait for Runtime {
|
||||
type HandleReport = aura::StakingSlasher<Runtime>;
|
||||
type AuthorityId = AuraId;
|
||||
parameter_types! {
|
||||
pub const EpochDuration: u64 = 10 * MINUTES;
|
||||
}
|
||||
|
||||
impl babe::Trait for Runtime {
|
||||
type EpochDuration = EpochDuration;
|
||||
}
|
||||
|
||||
impl indices::Trait for Runtime {
|
||||
@@ -177,7 +181,7 @@ parameter_types! {
|
||||
}
|
||||
impl timestamp::Trait for Runtime {
|
||||
type Moment = Moment;
|
||||
type OnTimestampSet = Aura;
|
||||
type OnTimestampSet = Babe;
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
}
|
||||
|
||||
@@ -193,17 +197,14 @@ impl authorship::Trait for Runtime {
|
||||
type EventHandler = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const Period: BlockNumber = 10 * MINUTES;
|
||||
pub const Offset: BlockNumber = 0;
|
||||
}
|
||||
|
||||
type SessionHandlers = (Grandpa, Aura, ImOnline);
|
||||
type SessionHandlers = (Grandpa, Babe, ImOnline);
|
||||
|
||||
impl_opaque_keys! {
|
||||
pub struct SessionKeys {
|
||||
#[id(key_types::ED25519)]
|
||||
pub ed25519: GrandpaId,
|
||||
#[id(key_types::SR25519)]
|
||||
pub sr25519: BabeId,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +217,7 @@ impl_opaque_keys! {
|
||||
impl session::Trait for Runtime {
|
||||
type OnSessionEnding = Staking;
|
||||
type SessionHandler = SessionHandlers;
|
||||
type ShouldEndSession = session::PeriodicSessions<Period, Offset>;
|
||||
type ShouldEndSession = Babe;
|
||||
type Event = Event;
|
||||
type Keys = SessionKeys;
|
||||
type ValidatorId = AccountId;
|
||||
@@ -378,12 +379,12 @@ impl sudo::Trait for Runtime {
|
||||
}
|
||||
|
||||
impl im_online::Trait for Runtime {
|
||||
type AuthorityId = AuraId;
|
||||
type AuthorityId = BabeId;
|
||||
type Call = Call;
|
||||
type Event = Event;
|
||||
type SessionsPerEra = SessionsPerEra;
|
||||
type UncheckedExtrinsic = UncheckedExtrinsic;
|
||||
type IsValidAuthorityId = Aura;
|
||||
type IsValidAuthorityId = Babe;
|
||||
}
|
||||
|
||||
impl grandpa::Trait for Runtime {
|
||||
@@ -408,7 +409,7 @@ construct_runtime!(
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
System: system::{Module, Call, Storage, Config, Event},
|
||||
Aura: aura::{Module, Call, Storage, Config<T>, Inherent(Timestamp)},
|
||||
Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
|
||||
Timestamp: timestamp::{Module, Call, Storage, Inherent},
|
||||
Authorship: authorship::{Module, Call, Storage},
|
||||
Indices: indices,
|
||||
@@ -525,12 +526,23 @@ impl_runtime_apis! {
|
||||
}
|
||||
}
|
||||
|
||||
impl consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||
fn slot_duration() -> u64 {
|
||||
Aura::slot_duration()
|
||||
impl babe_primitives::BabeApi<Block> for Runtime {
|
||||
fn startup_data() -> babe_primitives::BabeConfiguration {
|
||||
babe_primitives::BabeConfiguration {
|
||||
median_required_blocks: 1000,
|
||||
slot_duration: Babe::slot_duration(),
|
||||
c: (3, 10),
|
||||
}
|
||||
}
|
||||
fn authorities() -> Vec<AuraId> {
|
||||
Aura::authorities()
|
||||
|
||||
fn epoch() -> babe_primitives::Epoch {
|
||||
babe_primitives::Epoch {
|
||||
start_slot: Babe::epoch_start_slot(),
|
||||
authorities: Babe::authorities(),
|
||||
epoch_index: Babe::epoch_index(),
|
||||
randomness: Babe::randomness(),
|
||||
duration: EpochDuration::get(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user