Rework inherent data client side (#8526)

* Lol

* Yeah

* Moare

* adaasda

* Convert AURA to new pallet macro

* AURA: Switch to `CurrentSlot` instead of `LastTimestamp`

This switches AURA to use `CurrentSlot` instead of `LastTimestamp`.

* Add missing file

* Update frame/aura/src/migrations.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Remove the runtime side provide inherent code

* Use correct weight

* Add TODO

* Remove the Inherent from AURA

* 🤦

* Remove unused stuff

* Update primitives authorship

* Fix babe inherent data provider

* Fix consensus-uncles

* Fix BABE

* Do some further changes to authorship primitives... :D

* More work

* Make it compile the happy path

* Make it async!

* Take hash

* More stuff

* Hacks

* Revert "Hacks"

This reverts commit cfffad88668cfdebf632a59c4fbfada001ef8251.

* Fix

* Make `execute_block` return the final block header

* Move Aura digest stuff

* Make it possible to disable equivocation checking

* Fix fix fix

* Some refactorings

* Comment

* Fixes fixes fixes

* More cleanups

* Some love

* Better love

* Make slot duration being exposed as `Duration` to the outside

* Some slot info love

* Add `build_aura_worker` utility function

* Copy copy copy

* Some stuff

* Start fixing pow

* Fix pow

* Remove some bounds

* More work

* Make grandpa work

* Make slots use `async_trait`

* Introduce `SharedData`

* Add test and fix bugs

* Switch to `SharedData`

* Make grandpa tests working

* More Babe work

* Make grandpa work

* Introduce `SharedData`

* Add test and fix bugs

* Switch to `SharedData`

* Make grandpa tests working

* More Babe work

* Make it async

* Fix fix

* Use `async_trait` in sc-consensus-slots

This makes the code a little bit easier to read and also expresses that
there can always only be one call at a time to `on_slot`.

* Make grandpa tests compile

* More Babe tests work

* Fix network test

* Start fixing service test

* Finish service-test

* Fix sc-consensus-aura

* Fix fix fix

* More fixes

* Make everything compile *yeah*

* Make manual-seal compile

* More fixes

* Start fixing Aura

* Fix Aura tests

* Fix Babe tests

* Make everything compile

* Move code around and switch to async_trait

* Fix Babe

* Docs docs docs

* Move to FRAME

* Fix fix fix

* Make everything compile

* Last cleanups

* Fix integration test

* Change slot usage of the timestamp

* We really need to switch to `impl-trait-for-tuples`

* Update primitives/inherents/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update primitives/inherents/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update primitives/inherents/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Some extra logging

* Remove dbg!

* Update primitives/consensus/common/src/import_queue/basic_queue.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Bastian Köcher
2021-05-03 16:39:25 +02:00
committed by GitHub
parent ef07c3be0d
commit 2675741a09
52 changed files with 1506 additions and 1178 deletions
-2
View File
@@ -14,7 +14,6 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
sp-inherents = { version = "3.0.0", default-features = false, path = "../../primitives/inherents" }
sp-authorship = { version = "3.0.0", default-features = false, path = "../../primitives/authorship" }
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
@@ -31,7 +30,6 @@ serde = { version = "1.0.101" }
default = ["std"]
std = [
"codec/std",
"sp-inherents/std",
"sp-runtime/std",
"sp-std/std",
"frame-support/std",
+6 -7
View File
@@ -21,13 +21,13 @@
#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::{result, prelude::*};
use sp_std::collections::btree_set::BTreeSet;
use frame_support::dispatch;
use frame_support::traits::{FindAuthor, VerifySeal, Get};
use sp_std::{result, prelude::*, collections::btree_set::BTreeSet};
use frame_support::{
dispatch, traits::{FindAuthor, VerifySeal, Get},
inherent::{InherentData, ProvideInherent, InherentIdentifier},
};
use codec::{Encode, Decode};
use sp_runtime::traits::{Header as HeaderT, One, Zero};
use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData};
use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError};
const MAX_UNCLES: usize = 10;
@@ -293,8 +293,7 @@ impl<T: Config> Pallet<T> {
uncle: &T::Header,
existing_uncles: I,
accumulator: &mut <T::FilterUncle as FilterUncle<T::Header, T::AccountId>>::Accumulator,
) -> Result<Option<T::AccountId>, dispatch::DispatchError>
{
) -> Result<Option<T::AccountId>, dispatch::DispatchError> {
let now = <frame_system::Pallet<T>>::block_number();
let (minimum_height, maximum_height) = {
+1 -1
View File
@@ -619,7 +619,7 @@ mod tests {
}
}
impl<T: Config> sp_inherents::ProvideInherent for Module<T> {
impl<T: Config> frame_support::inherent::ProvideInherent for Module<T> {
type Call = Call<T>;
type Error = sp_inherents::MakeFatalError<()>;
const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234";
+60 -4
View File
@@ -19,14 +19,70 @@
pub use crate::sp_std::vec::Vec;
#[doc(hidden)]
pub use crate::sp_runtime::traits::{Block as BlockT, Extrinsic};
#[doc(hidden)]
pub use sp_inherents::{
InherentData, ProvideInherent, CheckInherentsResult, IsFatalError, InherentIdentifier,
MakeFatalError,
InherentData, CheckInherentsResult, IsFatalError, InherentIdentifier, MakeFatalError,
};
/// A pallet that provides or verifies an inherent extrinsic.
///
/// The pallet may provide the inherent, verify an inherent, or both provide and verify.
pub trait ProvideInherent {
/// The call type of the pallet.
type Call;
/// The error returned by `check_inherent`.
type Error: codec::Encode + IsFatalError;
/// The inherent identifier used by this inherent.
const INHERENT_IDENTIFIER: self::InherentIdentifier;
/// Create an inherent out of the given `InherentData`.
fn create_inherent(data: &InherentData) -> Option<Self::Call>;
/// Determines whether this inherent is required in this block.
///
/// - `Ok(None)` indicates that this inherent is not required in this block. The default
/// implementation returns this.
///
/// - `Ok(Some(e))` indicates that this inherent is required in this block. The
/// `impl_outer_inherent!`, will call this function from its `check_extrinsics`.
/// If the inherent is not present, it will return `e`.
///
/// - `Err(_)` indicates that this function failed and further operations should be aborted.
///
/// NOTE: If inherent is required then the runtime asserts that the block contains at least
/// one inherent for which:
/// * type is [`Self::Call`],
/// * [`Self::is_inherent`] returns true.
fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> { Ok(None) }
/// Check whether the given inherent is valid. Checking the inherent is optional and can be
/// omitted by using the default implementation.
///
/// When checking an inherent, the first parameter represents the inherent that is actually
/// included in the block by its author. Whereas the second parameter represents the inherent
/// data that the verifying node calculates.
///
/// NOTE: A block can contains multiple inherent.
fn check_inherent(_: &Self::Call, _: &InherentData) -> Result<(), Self::Error> {
Ok(())
}
/// Return whether the call is an inherent call.
///
/// NOTE: Signed extrinsics are not inherent, but signed extrinsic with the given call variant
/// can be dispatched.
///
/// # Warning
///
/// In FRAME, inherent are enforced to be before other extrinsics, for this reason,
/// pallets with unsigned transactions **must ensure** that no unsigned transaction call
/// is an inherent call, when implementing `ValidateUnsigned::validate_unsigned`.
/// Otherwise block producer can produce invalid blocks by including them after non inherent.
fn is_inherent(call: &Self::Call) -> bool;
}
/// Implement the outer inherent.
/// All given modules need to implement `ProvideInherent`.
/// All given modules need to implement [`ProvideInherent`].
///
/// # Example
///
+3 -3
View File
@@ -1229,8 +1229,8 @@ pub mod tests {
pub mod pallet_prelude {
pub use sp_std::marker::PhantomData;
#[cfg(feature = "std")]
pub use frame_support::traits::GenesisBuild;
pub use frame_support::{
pub use crate::traits::GenesisBuild;
pub use crate::{
EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, DebugNoBound, CloneNoBound, Twox256,
Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, ensure,
RuntimeDebug, storage,
@@ -1241,7 +1241,7 @@ pub mod pallet_prelude {
storage::bounded_vec::{BoundedVec, BoundedVecValue},
};
pub use codec::{Encode, Decode};
pub use sp_inherents::{InherentData, InherentIdentifier, ProvideInherent};
pub use crate::inherent::{InherentData, InherentIdentifier, ProvideInherent};
pub use sp_runtime::{
traits::{MaybeSerializeDeserialize, Member, ValidateUnsigned},
transaction_validity::{
-2
View File
@@ -17,7 +17,6 @@ codec = { package = "parity-scale-codec", version = "2.0.0", default-features =
sp-io = { version = "3.0.0", path = "../../../primitives/io", default-features = false }
sp-state-machine = { version = "0.9.0", optional = true, path = "../../../primitives/state-machine" }
frame-support = { version = "3.0.0", default-features = false, path = "../" }
sp-inherents = { version = "3.0.0", default-features = false, path = "../../../primitives/inherents" }
sp-runtime = { version = "3.0.0", default-features = false, path = "../../../primitives/runtime" }
sp-core = { version = "3.0.0", default-features = false, path = "../../../primitives/core" }
sp-std = { version = "3.0.0", default-features = false, path = "../../../primitives/std" }
@@ -35,7 +34,6 @@ std = [
"sp-io/std",
"frame-support/std",
"frame-system/std",
"sp-inherents/std",
"sp-core/std",
"sp-std/std",
"sp-runtime/std",
@@ -26,8 +26,8 @@ use frame_support::{
StorageEntryMetadata, StorageHasher,
},
StorageValue, StorageMap, StorageDoubleMap,
inherent::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError},
};
use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError};
use sp_core::{H256, sr25519};
mod system;
@@ -112,7 +112,7 @@ mod module1 {
T::BlockNumber: From<u32>
{
type Call = Call<T, I>;
type Error = MakeFatalError<sp_inherents::Error>;
type Error = MakeFatalError<()>;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(_data: &InherentData) -> Option<Self::Call> {
@@ -176,7 +176,7 @@ mod module2 {
impl<T: Config<I>, I: Instance> ProvideInherent for Module<T, I> {
type Call = Call<T, I>;
type Error = MakeFatalError<sp_inherents::Error>;
type Error = MakeFatalError<()>;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(_data: &InherentData) -> Option<Self::Call> {
+2 -2
View File
@@ -299,13 +299,13 @@ pub mod pallet {
pub enum InherentError {
}
impl sp_inherents::IsFatalError for InherentError {
impl frame_support::inherent::IsFatalError for InherentError {
fn is_fatal_error(&self) -> bool {
unimplemented!();
}
}
pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall";
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"testpall";
}
// Test that a pallet with non generic event and generic genesis_config is correctly handled
@@ -181,13 +181,13 @@ pub mod pallet {
pub enum InherentError {
}
impl sp_inherents::IsFatalError for InherentError {
impl frame_support::inherent::IsFatalError for InherentError {
fn is_fatal_error(&self) -> bool {
unimplemented!();
}
}
pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall";
pub const INHERENT_IDENTIFIER: frame_support::inherent::InherentIdentifier = *b"testpall";
}
// Test that a instantiable pallet with a generic genesis_config is correctly handled
@@ -67,18 +67,21 @@ impl<T: Trait> sp_runtime::traits::ValidateUnsigned for Module<T> {
}
}
pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"12345678";
pub const INHERENT_IDENTIFIER: frame_support::inherent::InherentIdentifier = *b"12345678";
impl<T: Trait> sp_inherents::ProvideInherent for Module<T> {
impl<T: Trait> frame_support::inherent::ProvideInherent for Module<T> {
type Call = Call<T>;
type Error = sp_inherents::MakeFatalError<sp_inherents::Error>;
const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = INHERENT_IDENTIFIER;
type Error = frame_support::inherent::MakeFatalError<()>;
const INHERENT_IDENTIFIER: frame_support::inherent::InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(_data: &sp_inherents::InherentData) -> Option<Self::Call> {
fn create_inherent(_data: &frame_support::inherent::InherentData) -> Option<Self::Call> {
unimplemented!();
}
fn check_inherent(_: &Self::Call, _: &sp_inherents::InherentData) -> std::result::Result<(), Self::Error> {
fn check_inherent(
_: &Self::Call,
_: &frame_support::inherent::InherentData,
) -> std::result::Result<(), Self::Error> {
unimplemented!();
}
+8 -17
View File
@@ -96,14 +96,8 @@ mod benchmarking;
pub mod weights;
use sp_std::{result, cmp};
use sp_inherents::InherentData;
use frame_support::traits::{Time, UnixTime, OnTimestampSet};
use sp_runtime::{
RuntimeString,
traits::{
AtLeast32Bit, Zero, SaturatedConversion, Scale,
}
};
use sp_runtime::traits::{AtLeast32Bit, Zero, SaturatedConversion, Scale};
use sp_timestamp::{
InherentError, INHERENT_IDENTIFIER, InherentType,
};
@@ -213,8 +207,9 @@ pub mod pallet {
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let inherent_data = extract_inherent_data(data)
.expect("Gets and decodes timestamp inherent data");
let inherent_data = data.get_data::<InherentType>(&INHERENT_IDENTIFIER)
.expect("Timestamp inherent data not correctly encoded")
.expect("Timestamp inherent data must be provided");
let data = (*inherent_data).saturated_into::<T::Moment>();
let next_time = cmp::max(data, Self::now() + T::MinimumPeriod::get());
@@ -230,11 +225,13 @@ pub mod pallet {
_ => return Ok(()),
};
let data = extract_inherent_data(data).map_err(|e| InherentError::Other(e))?;
let data = data.get_data::<InherentType>(&INHERENT_IDENTIFIER)
.expect("Timestamp inherent data not correctly encoded")
.expect("Timestamp inherent data must be provided");
let minimum = (Self::now() + T::MinimumPeriod::get()).saturated_into::<u64>();
if t > *(data + MAX_TIMESTAMP_DRIFT_MILLIS) {
Err(InherentError::Other("Timestamp too far in future to accept".into()))
Err(InherentError::TooFarInFuture)
} else if t < minimum {
Err(InherentError::ValidAtTimestamp(minimum.into()))
} else {
@@ -264,12 +261,6 @@ impl<T: Config> Pallet<T> {
}
}
fn extract_inherent_data(data: &InherentData) -> Result<InherentType, RuntimeString> {
data.get_data::<InherentType>(&INHERENT_IDENTIFIER)
.map_err(|_| RuntimeString::from("Invalid timestamp inherent data encoding."))?
.ok_or_else(|| "Timestamp inherent data is not provided.".into())
}
impl<T: Config> Time for Pallet<T> {
type Moment = T::Moment;