From 35dd102ce9d9a4a8e1713168b29b89c7139825ac Mon Sep 17 00:00:00 2001 From: Ross Bulat Date: Sun, 19 Feb 2023 14:49:54 +0700 Subject: [PATCH] Revert "pallet-timestamp: Remove `ValidAtTimestamp` error variant (#13346)" This reverts commit ab31a6c35195d12fb2d0ae1e429caae997a83152. --- frame/timestamp/src/lib.rs | 2 +- primitives/timestamp/src/lib.rs | 44 +++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 61a46125a423b..6e9c887824d17 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -255,7 +255,7 @@ pub mod pallet { if t > *(data + MAX_TIMESTAMP_DRIFT_MILLIS) { Err(InherentError::TooFarInFuture) } else if t < minimum { - Err(InherentError::TooEarly) + Err(InherentError::ValidAtTimestamp(minimum.into())) } else { Ok(()) } diff --git a/primitives/timestamp/src/lib.rs b/primitives/timestamp/src/lib.rs index 0ec079816c10a..14b06779340f2 100644 --- a/primitives/timestamp/src/lib.rs +++ b/primitives/timestamp/src/lib.rs @@ -134,12 +134,10 @@ impl From for Timestamp { #[derive(Encode, sp_runtime::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Decode, thiserror::Error))] pub enum InherentError { - /// The time between the blocks is too short. - #[cfg_attr( - feature = "std", - error("The time since the last timestamp is lower than the minimum period.") - )] - TooEarly, + /// The timestamp is valid in the future. + /// This is a non-fatal-error and will not stop checking the inherents. + #[cfg_attr(feature = "std", error("Block will be valid at {0}."))] + ValidAtTimestamp(InherentType), /// The block timestamp is too far in the future #[cfg_attr(feature = "std", error("The timestamp of the block is too far in the future."))] TooFarInFuture, @@ -148,7 +146,7 @@ pub enum InherentError { impl IsFatalError for InherentError { fn is_fatal_error(&self) -> bool { match self { - InherentError::TooEarly => true, + InherentError::ValidAtTimestamp(_) => false, InherentError::TooFarInFuture => true, } } @@ -242,8 +240,34 @@ impl sp_inherents::InherentDataProvider for InherentDataProvider { identifier: &InherentIdentifier, error: &[u8], ) -> Option> { - Some(Err(sp_inherents::Error::Application(Box::from(InherentError::try_from( - identifier, error, - )?)))) + if *identifier != INHERENT_IDENTIFIER { + return None + } + + match InherentError::try_from(&INHERENT_IDENTIFIER, error)? { + InherentError::ValidAtTimestamp(valid) => { + let max_drift = self.max_drift; + let timestamp = self.timestamp; + // halt import until timestamp is valid. + // reject when too far ahead. + if valid > timestamp + max_drift { + return Some(Err(sp_inherents::Error::Application(Box::from( + InherentError::TooFarInFuture, + )))) + } + + let diff = valid.checked_sub(timestamp).unwrap_or_default(); + log::info!( + target: "timestamp", + "halting for block {} milliseconds in the future", + diff.0, + ); + + futures_timer::Delay::new(diff.as_duration()).await; + + Some(Ok(())) + }, + o => Some(Err(sp_inherents::Error::Application(Box::from(o)))), + } } }