New sessions, kill consensus module (#2802)

* Draft of new sessions

* Reintroduce tuple impls

* Move staking module to new session API

* More work on staking and grandpa.

* Use iterator to avoid cloning and tuple macro

* Make runtime build again

* Polish the OpaqueKeys devex

* Move consensus logic into system & aura.

* Fix up system module

* Get build mostly going. Stuck at service.rs

* Building again

* Update srml/staking/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Refactoring out Consensus module, AuthorityIdOf, &c.

* Refactored out DigestItem::AuthoritiesChanged. Building.

* Remove tentative code

* Remove invalid comment

* Make Seal opaque and introduce nice methods for handling opaque items.

* Start to use proper digest for Aura authorities tracking.

* Fix up grandpa, remove system::Raw/Log

* Refactor Grandpa to use new logging infrastructure.

Also make authorityid/sessionkey static. Switch over to storing
authorities in a straight Vec.

* Building again

* Tidy up some AuthorityIds

* Expunge most of the rest of the AuthorityKey confusion.

Also, de-generify Babe and re-generify Aura.

* Remove cruft

* Untangle last of the `AuthorityId`s.

* Sort out finality_tracker

* Refactor median getting

* Apply suggestions from code review

Co-Authored-By: Robert Habermeier <rphmeier@gmail.com>

* Session tests works

* Update core/sr-primitives/src/generic/digest.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Session tests works

* Fix for staking from @dvc94ch

* log an error

* fix test runtime build

* Some test fixes

* Staking mock update to new session api.

* Fix build.

* Move OpaqueKeys to primitives.

* Use on_initialize instead of check_rotate_session.

* Update tests to new staking api.

* fixup mock

* Fix bond_extra_and_withdraw_unbonded_works.

* Fix bond_with_little_staked_value_bounded_by_slot_stake.

* Fix bond_with_no_staked_value.

* Fix change_controller_works.

* Fix less_than_needed_candidates_works.

* Fix multi_era_reward_should_work.

* Fix nominating_and_rewards_should_work.

* Fix nominators_also_get_slashed.

* Fix phragmen_large_scale_test.

* Fix phragmen_poc_works.

* Fix phragmen_score_should_be_accurate_on_large_stakes.

* Fix phragmen_should_not_overflow.

* Fix reward_destination_works.

* Fix rewards_should_work.

* Fix sessions_and_eras_should_work.

* Fix slot_stake_is_least_staked_validator.

* Fix too_many_unbond_calls_should_not_work.

* Fix wrong_vote_is_null.

* Fix runtime.

* Fix wasm runtime build.

* Update Cargo.lock

* Fix warnings.

* Fix grandpa tests.

* Fix test-runtime build.

* Fix template node build.

* Fix stuff.

* Update Cargo.lock to fix CI

* Re-add missing AuRa logs

Runtimes are required to know about every digest they receive ― they
panic otherwise.  This re-adds support for AuRa pre-runtime digests.

* Update core/consensus/babe/src/digest.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Kill log trait and all that jazz.

* Refactor staking tests.

* Fix ci runtime wasm check.

* Line length 120.

* Make tests build again

* Remove trailing commas in function declarations

The `extern_functions!` macro doesn’t like them, perhaps due to a bug in
rustc.

* Fix type error

* Fix compilation errors

* Fix a test

* Another couple of fixes

* Fix another test

* More test fixes

* Another test fix

* Bump runtime.

* Wrap long line

* Fix build, remove redundant code.

* Issue to track TODO

* Leave the benchmark code alone.

* Fix missing `std::time::{Instant, Duration}`

* Indentation

* Aura ConsensusLog as enum
This commit is contained in:
Gavin Wood
2019-06-14 16:34:34 +02:00
committed by GitHub
parent 0f44a28ce3
commit bda8641892
128 changed files with 2646 additions and 3671 deletions
+82 -55
View File
@@ -22,8 +22,9 @@ use runtime_io;
#[cfg(feature = "std")] use std::fmt::{Debug, Display};
#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned};
use substrate_primitives::{self, Hasher, Blake2Hasher};
use crate::codec::{Codec, Encode, HasCompact};
use crate::codec::{Codec, Encode, Decode, HasCompact};
use crate::transaction_validity::TransactionValidity;
use crate::generic::{Digest, DigestItem};
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
@@ -406,7 +407,8 @@ tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W,
pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived
// traits must be fulfilled by all type parameters.
/// The hash type produced.
type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default;
type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy
+ Default + Encode + Decode;
/// The associated hash_db Hasher type.
type Hasher: Hasher<Out=Self::Output>;
@@ -502,7 +504,7 @@ impl CheckEqual for substrate_primitives::H256 {
}
}
impl<I> CheckEqual for I where I: DigestItem {
impl<H: PartialEq + Eq + MaybeDebug> CheckEqual for super::generic::DigestItem<H> where H: Encode {
#[cfg(feature = "std")]
fn check_equal(&self, other: &Self) {
if self != other {
@@ -609,8 +611,6 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDe
type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
/// Hashing algorithm
type Hashing: Hash<Output = Self::Hash>;
/// Digest type
type Digest: Digest<Hash = Self::Hash> + Codec;
/// Creates new header.
fn new(
@@ -618,7 +618,7 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDe
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
digest: Digest<Self::Hash>,
) -> Self;
/// Returns a reference to the header number.
@@ -642,9 +642,9 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDe
fn set_parent_hash(&mut self, hash: Self::Hash);
/// Returns a reference to the digest.
fn digest(&self) -> &Self::Digest;
fn digest(&self) -> &Digest<Self::Hash>;
/// Get a mutable reference to the digest.
fn digest_mut(&mut self) -> &mut Self::Digest;
fn digest_mut(&mut self) -> &mut Digest<Self::Hash>;
/// Returns the hash of the header.
fn hash(&self) -> Self::Hash {
@@ -690,11 +690,9 @@ pub type HashFor<B> = <<B as Block>::Header as Header>::Hashing;
/// Extract the number type for a block.
pub type NumberFor<B> = <<B as Block>::Header as Header>::Number;
/// Extract the digest type for a block.
pub type DigestFor<B> = <<B as Block>::Header as Header>::Digest;
pub type DigestFor<B> = Digest<<<B as Block>::Header as Header>::Hash>;
/// Extract the digest item type for a block.
pub type DigestItemFor<B> = <DigestFor<B> as Digest>::Item;
/// Extract the authority ID type for a block.
pub type AuthorityIdFor<B> = <DigestItemFor<B> as DigestItem>::AuthorityId;
pub type DigestItemFor<B> = DigestItem<<<B as Block>::Header as Header>::Hash>;
/// A "checkable" piece of information, used by the standard Substrate Executive in order to
/// check the validity of a piece of extrinsic information, usually by verifying the signature.
@@ -749,49 +747,6 @@ pub trait Applyable: Sized + Send + Sync {
fn deconstruct(self) -> (Self::Call, Option<Self::AccountId>);
}
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Codec`.
pub trait Digest: Member + MaybeSerializeDebugButNotDeserialize + Default {
/// Hash of the items.
type Hash: Member;
/// Digest item type.
type Item: DigestItem<Hash = Self::Hash>;
/// Get reference to all digest items.
fn logs(&self) -> &[Self::Item];
/// Push new digest item.
fn push(&mut self, item: Self::Item);
/// Pop a digest item.
fn pop(&mut self) -> Option<Self::Item>;
/// Get reference to the first digest item that matches the passed predicate.
fn log<T: ?Sized, F: Fn(&Self::Item) -> Option<&T>>(&self, predicate: F) -> Option<&T> {
self.logs().iter()
.filter_map(predicate)
.next()
}
}
/// Single digest item. Could be any type that implements `Member` and provides methods
/// for casting member to 'system' log items, known to substrate.
///
/// If the runtime does not supports some 'system' items, use `()` as a stub.
pub trait DigestItem: Codec + Member + MaybeSerializeDebugButNotDeserialize {
/// `ChangesTrieRoot` payload.
type Hash: Member;
/// `AuthorityChange` payload.
type AuthorityId: Member + MaybeHash + crate::codec::Encode + crate::codec::Decode;
/// Returns `Some` if the entry is the `AuthoritiesChange` entry.
fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]>;
/// Returns `Some` if the entry is the `ChangesTrieRoot` entry.
fn as_changes_trie_root(&self) -> Option<&Self::Hash>;
/// Returns `Some` if this entry is the `PreRuntime` entry.
fn as_pre_runtime(&self) -> Option<(super::ConsensusEngineId, &[u8])>;
}
/// Auxiliary wrapper that holds an api instance and binds it to the given lifetime.
pub struct ApiRef<'a, T>(T, rstd::marker::PhantomData<&'a ()>);
@@ -861,3 +816,75 @@ pub trait ValidateUnsigned {
/// Changes made to storage should be discarded by caller.
fn validate_unsigned(call: &Self::Call) -> TransactionValidity;
}
/// Opaque datatype that may be destructured into a series of raw byte slices (which represent
/// individual keys).
pub trait OpaqueKeys {
/// Return the number of encoded keys.
fn count() -> usize { 0 }
/// Get the raw bytes of key with index `i`.
fn get_raw(&self, i: usize) -> &[u8];
/// Get the decoded key with index `i`.
fn get<T: Decode>(&self, i: usize) -> Option<T> { T::decode(&mut self.get_raw(i)) }
/// Verify a proof of ownership for the keys.
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool { true }
}
/// Calls a given macro a number of times with a set of fixed params and an incrementing numeral.
/// e.g.
/// ```nocompile
/// count!(println ("{}",) foo, bar, baz);
/// // Will result in three `println!`s: "0", "1" and "2".
/// ```
#[macro_export]
macro_rules! count {
($f:ident ($($x:tt)*) ) => ();
($f:ident ($($x:tt)*) $x1:tt) => { $f!($($x)* 0); };
($f:ident ($($x:tt)*) $x1:tt, $x2:tt) => { $f!($($x)* 0); $f!($($x)* 1); };
($f:ident ($($x:tt)*) $x1:tt, $x2:tt, $x3:tt) => { $f!($($x)* 0); $f!($($x)* 1); $f!($($x)* 2); };
($f:ident ($($x:tt)*) $x1:tt, $x2:tt, $x3:tt, $x4:tt) => {
$f!($($x)* 0); $f!($($x)* 1); $f!($($x)* 2); $f!($($x)* 3);
};
($f:ident ($($x:tt)*) $x1:tt, $x2:tt, $x3:tt, $x4:tt, $x5:tt) => {
$f!($($x)* 0); $f!($($x)* 1); $f!($($x)* 2); $f!($($x)* 3); $f!($($x)* 4);
};
}
#[macro_export]
/// Just implement `OpaqueKeys` for a given tuple-struct.
/// Would be much nicer for this to be converted to `derive` code.
macro_rules! impl_opaque_keys {
(
pub struct $name:ident ( $( $t:ty ),* $(,)* );
) => {
impl_opaque_keys! {
pub struct $name ( $( $t ,)* );
impl OpaqueKeys for _ {}
}
};
(
pub struct $name:ident ( $( $t:ty ),* $(,)* );
impl OpaqueKeys for _ {
$($rest:tt)*
}
) => {
#[derive(Default, Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct $name($( pub $t ,)*);
impl $crate::traits::OpaqueKeys for $name {
fn count() -> usize {
let mut c = 0;
$( let _: $t; c += 1; )*
c
}
fn get_raw(&self, i: usize) -> &[u8] {
$crate::count!(impl_opaque_keys (!! self i) $($t),*);
&[]
}
$($rest)*
}
};
( !! $self:ident $param_i:ident $i:tt) => {
if $param_i == $i { return $self.$i.as_ref() }
}
}