diff --git a/Cargo.lock b/Cargo.lock index 38e527abeac52..68bffcf789da9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2972,7 +2972,6 @@ version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", diff --git a/core/consensus/rhd/src/lib.rs b/core/consensus/rhd/src/lib.rs index 135fbd03a2d4e..8f0dfb194e05d 100644 --- a/core/consensus/rhd/src/lib.rs +++ b/core/consensus/rhd/src/lib.rs @@ -1177,7 +1177,7 @@ impl BaseProposer<::Block> for Proposer where &inherent, ) { Ok(Ok(())) => None, - Ok(Err(BlockBuilderError::TimestampInFuture(timestamp))) => Some(timestamp), + Ok(Err(BlockBuilderError::ValidAtTimestamp(timestamp))) => Some(timestamp), Ok(Err(e)) => { debug!(target: "rhd", "Invalid proposal (check_inherents): {:?}", e); return Box::new(future::ok(false)); diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index e07711668c18f..1e61ac0545a00 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -487,7 +487,10 @@ impl BasicInherentData { #[derive(Encode)] #[cfg_attr(feature = "std", derive(Decode))] pub enum CheckInherentError { - TimestampInFuture(u64), + /// The inherents are generally valid but a delay until the given timestamp + /// is required. + ValidAtTimestamp(u64), + /// Some other error has occurred. Other(RuntimeString), } diff --git a/srml/support/src/inherent.rs b/srml/support/src/inherent.rs index 4b2443138ca4d..925ba91cec532 100644 --- a/srml/support/src/inherent.rs +++ b/srml/support/src/inherent.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . #[doc(hidden)] -pub use rstd::{result::Result, vec::Vec}; +pub use rstd::{cmp, result::Result, vec::Vec}; #[doc(hidden)] pub use runtime_primitives::{ traits::{ProvideInherent, Block as BlockT}, CheckInherentError @@ -52,17 +52,32 @@ macro_rules! impl_outer_inherent { block: $block, data: $inherent ) -> $crate::inherent::Result<(), $crate::inherent::CheckInherentError> { + use $crate::inherent::CheckInherentError; + + let mut max_valid_after = None; $( - <$module_ty as $crate::inherent::ProvideInherent>::check_inherent( + let res = <$module_ty as $crate::inherent::ProvideInherent>::check_inherent( &block, data.$module, &|xt| match xt.function { Call::$module_ty(ref data) => Some(data), _ => None, }, - )?; + ); + + match res { + Err(CheckInherentError::ValidAtTimestamp(t)) => + max_valid_after = $crate::inherent::cmp::max(max_valid_after, Some(t)), + res => res? + } )* - Ok(()) + + // once everything else has checked out, take the maximum of + // all things which are timestamp-restricted. + match max_valid_after { + Some(t) => Err(CheckInherentError::ValidAtTimestamp(t)), + None => Ok(()) + } } } }; diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 8472bb89ca95a..b11e74e3eb460 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -6,7 +6,6 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -parity-codec-derive = { version = "2.1", default-features = false } parity-codec = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -28,7 +27,6 @@ std = [ "sr-primitives/std", "srml-consensus/std", "serde/std", - "parity-codec-derive/std", "parity-codec/std", "substrate-primitives/std", "srml-system/std", diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 422fd1faad738..fcfd26f12e0ca 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -46,8 +46,6 @@ extern crate sr_primitives as runtime_primitives; extern crate srml_system as system; extern crate srml_consensus as consensus; extern crate parity_codec as codec; -#[macro_use] -extern crate parity_codec_derive; use codec::HasCompact; use runtime_support::{StorageValue, Parameter}; @@ -136,7 +134,8 @@ impl ProvideInherent for Module { type Call = Call; fn create_inherent_extrinsics(data: Self::Inherent) -> Vec<(u32, Self::Call)> { - vec![(T::TIMESTAMP_SET_POSITION, Call::set(data.into()))] + let next_time = ::rstd::cmp::max(data, Self::now() + Self::block_period()); + vec![(T::TIMESTAMP_SET_POSITION, Call::set(next_time.into()))] } fn check_inherent Option<&Self::Call>>( @@ -152,8 +151,11 @@ impl ProvideInherent for Module { _ => return Err(CheckInherentError::Other("No valid timestamp inherent in block".into())), }.into().as_(); + let minimum = (Self::now() + Self::block_period()).as_(); if t > data.as_() + MAX_TIMESTAMP_DRIFT { - Err(CheckInherentError::TimestampInFuture(t)) + Err(CheckInherentError::Other("Timestamp too far in future to accept".into())) + } else if t < minimum { + Err(CheckInherentError::ValidAtTimestamp(minimum)) } else { Ok(()) }