babe: Introduce secondary slots (Aurababeous) (#3380)

* babe: initial implementation of secondary slots

* babe: validate secondary slot author

* babe: implement weight based fork choice

* babe: remove unused

* aura: cleanup unused imports

* babe: pass in parent weight when authoring and verifying

* babe: use epoch randomness for picking secondary slot authors

* babe: fix tests

* babe: fix wasm build

* babe: node-side code for disabling secondary slots

* babe: allow enabling/disabling secondary slots from runtime

* babe: fix test

* babe: use blake2_256 for secondary slot assignment

* babe: run block initialization in should_end_session

* node: increase slot duration to 6s

* babe: add docs

* node: bump spec_version

* Apply suggestions from code review

Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* babe: simplify secondary slot assignment calculation

* babe: remove unnecessary comment

* node: bump spec_version

* babe: fix bad merge
This commit is contained in:
André Silva
2019-08-16 15:47:53 +02:00
committed by GitHub
parent f735d067c4
commit cb7527d2b2
12 changed files with 720 additions and 202 deletions
+31 -10
View File
@@ -20,14 +20,13 @@
// https://github.com/paritytech/substrate/issues/2532
#![allow(deprecated)]
use super::*;
use sr_primitives::generic::{self, DigestItem};
use babe_primitives::AuthorityPair;
use client::{LongestChain, block_builder::BlockBuilder};
use consensus_common::NoNetwork as DummyOracle;
use network::test::*;
use network::test::{Block as TestBlock, PeersClient};
use sr_primitives::traits::{Block as BlockT, DigestFor};
use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}};
use network::config::ProtocolConfig;
use tokio::runtime::current_thread;
use keyring::sr25519::Keyring;
@@ -35,7 +34,8 @@ use client::BlockchainEvents;
use test_client;
use log::debug;
use std::{time::Duration, borrow::Borrow, cell::RefCell};
type Item = generic::DigestItem<Hash>;
type Item = DigestItem<Hash>;
type Error = client::error::Error;
@@ -88,7 +88,14 @@ type TestHeader = <TestBlock as BlockT>::Header;
type TestExtrinsic = <TestBlock as BlockT>::Extrinsic;
pub struct TestVerifier {
inner: BabeVerifier<PeersFullClient, ()>,
inner: BabeVerifier<
test_client::Backend,
test_client::Executor,
TestBlock,
test_client::runtime::RuntimeApi,
PeersFullClient,
(),
>,
mutator: Mutator,
}
@@ -126,9 +133,9 @@ impl TestNetFactory for BabeTestNet {
fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig)
-> Self::Verifier
{
let api = client.as_full().expect("only full clients are used in test");
let client = client.as_full().expect("only full clients are used in test");
trace!(target: "babe", "Creating a verifier");
let config = Config::get_or_compute(&*api)
let config = Config::get_or_compute(&*client)
.expect("slot duration available");
let inherent_data_providers = InherentDataProviders::new();
register_babe_inherent_data_provider(
@@ -139,7 +146,8 @@ impl TestNetFactory for BabeTestNet {
TestVerifier {
inner: BabeVerifier {
api,
client: client.clone(),
api: client,
inherent_data_providers,
config,
time_source: Default::default(),
@@ -317,19 +325,32 @@ fn can_author_block() {
.expect("Generates authority pair");
let mut i = 0;
let epoch = Epoch {
let mut epoch = Epoch {
start_slot: 0,
authorities: vec![(pair.public(), 1)],
randomness: [0; 32],
epoch_index: 1,
duration: 100,
secondary_slots: true,
};
let parent_weight = 0;
// with secondary slots enabled it should never be empty
match claim_slot(i, parent_weight, &epoch, (3, 10), &keystore) {
None => i += 1,
Some(s) => debug!(target: "babe", "Authored block {:?}", s.0),
}
// otherwise with only vrf-based primary slots we might need to try a couple
// of times.
epoch.secondary_slots = false;
loop {
match claim_slot(i, &epoch.clone(), (3, 10), &keystore) {
match claim_slot(i, parent_weight, &epoch, (3, 10), &keystore) {
None => i += 1,
Some(s) => {
debug!(target: "babe", "Authored block {:?}", s.0);
break
break;
}
}
}