Rewrite Inherent data (#1488)

* Implement new inherent data

* Fixes compilation on wasm

* Fixes after rebase

* Switch back to generate inherent stuff by macro

* Update after rebase

* Apply suggestions from code review

Co-Authored-By: bkchr <bkchr@users.noreply.github.com>

* Fix compilation after rebase

* Address grumbles

* Remove `InherentDataProviders` from `Client`

* Update wasm files after rebase

* Address grumbles

* Fixes compilation after latest merge

* Last fix
This commit is contained in:
Bastian Köcher
2019-01-22 17:52:08 +01:00
committed by GitHub
parent b14917e63f
commit 70b1af7b1e
55 changed files with 1513 additions and 661 deletions
+109 -19
View File
@@ -18,8 +18,6 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[allow(unused_imports)]
#[macro_use]
extern crate sr_std as rstd;
#[macro_use]
@@ -31,9 +29,10 @@ extern crate srml_support as runtime_support;
extern crate sr_primitives as primitives;
extern crate srml_system as system;
extern crate srml_timestamp as timestamp;
pub extern crate srml_timestamp as timestamp;
extern crate srml_staking as staking;
extern crate substrate_primitives;
extern crate substrate_inherents as inherents;
#[cfg(test)]
extern crate srml_consensus as consensus;
@@ -48,15 +47,93 @@ extern crate lazy_static;
#[cfg(test)]
extern crate parking_lot;
use rstd::prelude::*;
use rstd::{result, prelude::*};
use runtime_support::storage::StorageValue;
use runtime_support::dispatch::Result;
use primitives::traits::{As, Zero};
use timestamp::OnTimestampSet;
#[cfg(feature = "std")]
use timestamp::TimestampInherentData;
#[cfg(feature = "std")]
use parity_codec::Decode;
use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError};
#[cfg(feature = "std")]
use inherents::{InherentDataProviders, ProvideInherentData};
mod mock;
mod tests;
/// The aura inherent identifier.
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"auraslot";
/// The type of the aura inherent.
pub type InherentType = u64;
/// Auxiliary trait to extract aura inherent data.
pub trait AuraInherentData {
/// Get aura inherent data.
fn aura_inherent_data(&self) -> result::Result<InherentType, RuntimeString>;
/// Replace aura inherent data.
fn aura_replace_inherent_data(&mut self, new: InherentType);
}
impl AuraInherentData for InherentData {
fn aura_inherent_data(&self) -> result::Result<InherentType, RuntimeString> {
self.get_data(&INHERENT_IDENTIFIER)
.and_then(|r| r.ok_or_else(|| "Aura inherent data not found".into()))
}
fn aura_replace_inherent_data(&mut self, new: InherentType) {
self.replace_data(INHERENT_IDENTIFIER, &new);
}
}
/// Provides the slot duration inherent data for `Aura`.
#[cfg(feature = "std")]
pub struct InherentDataProvider {
slot_duration: u64,
}
#[cfg(feature = "std")]
impl InherentDataProvider {
pub fn new(slot_duration: u64) -> Self {
Self {
slot_duration
}
}
}
#[cfg(feature = "std")]
impl ProvideInherentData for InherentDataProvider {
fn on_register(
&self,
providers: &InherentDataProviders,
) -> result::Result<(), RuntimeString> {
if !providers.has_provider(&timestamp::INHERENT_IDENTIFIER) {
// Add the timestamp inherent data provider, as we require it.
providers.register_provider(timestamp::InherentDataProvider)
} else {
Ok(())
}
}
fn inherent_identifier(&self) -> &'static inherents::InherentIdentifier {
&INHERENT_IDENTIFIER
}
fn provide_inherent_data(
&self,
inherent_data: &mut InherentData,
) -> result::Result<(), RuntimeString> {
let timestamp = inherent_data.timestamp_inherent_data()?;
let slot_num = timestamp / self.slot_duration;
inherent_data.put_data(INHERENT_IDENTIFIER, &slot_num)
}
fn error_to_string(&self, error: &[u8]) -> Option<String> {
RuntimeString::decode(&mut &error[..]).map(Into::into)
}
}
/// Something which can handle Aura consensus reports.
pub trait HandleReport {
fn handle_report(report: AuraReport);
@@ -133,20 +210,6 @@ impl<T: Trait> Module<T> {
<timestamp::Module<T>>::block_period().as_().saturating_mul(2)
}
/// Verify an inherent slot that is used in a block seal against a timestamp
/// extracted from the block.
// TODO: ensure `ProvideInherent` can deal with dependencies like this.
// https://github.com/paritytech/substrate/issues/1228
pub fn verify_inherent(timestamp: T::Moment, seal_slot: u64) -> Result {
let timestamp_based_slot = timestamp.as_() / Self::slot_duration();
if timestamp_based_slot == seal_slot {
Ok(())
} else {
Err("timestamp set in block doesn't match slot in seal".into())
}
}
fn on_timestamp_set<H: HandleReport>(now: T::Moment, slot_duration: T::Moment) {
let last = Self::last();
<Self as Store>::LastTimestamp::put(now.clone());
@@ -197,3 +260,30 @@ impl<T: staking::Trait + Trait> HandleReport for StakingSlasher<T> {
);
}
}
impl<T: Trait> ProvideInherent for Module<T> {
type Call = timestamp::Call<T>;
type Error = MakeFatalError<RuntimeString>;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(_: &InherentData) -> Option<Self::Call> {
None
}
fn check_inherent(call: &Self::Call, data: &InherentData) -> result::Result<(), Self::Error> {
let timestamp = match call {
timestamp::Call::set(ref timestamp) => timestamp.clone(),
_ => return Ok(()),
};
let timestamp_based_slot = timestamp.as_() / Self::slot_duration();
let seal_slot = data.aura_inherent_data()?;
if timestamp_based_slot == seal_slot {
Ok(())
} else {
Err(RuntimeString::from("timestamp set in block doesn't match slot in seal").into())
}
}
}
-3
View File
@@ -32,7 +32,6 @@ impl_outer_origin!{
pub struct Test;
impl consensus::Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
type Log = DigestItem;
type SessionKey = UintAuthorityId;
type InherentOfflineReport = ();
@@ -53,8 +52,6 @@ impl system::Trait for Test {
}
impl timestamp::Trait for Test {
const TIMESTAMP_SET_POSITION: u32 = 0;
type Moment = u64;
type OnTimestampSet = Aura;
}