diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 25bcac940d..2e00f515d3 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -4546,7 +4546,6 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", - "sp-timestamp", ] [[package]] @@ -4611,7 +4610,6 @@ dependencies = [ "sp-session", "sp-staking", "sp-std", - "sp-timestamp", ] [[package]] @@ -9042,7 +9040,6 @@ dependencies = [ name = "sp-timestamp" version = "3.0.0" dependencies = [ - "impl-trait-for-tuples", "parity-scale-codec", "sp-api", "sp-inherents", diff --git a/substrate/client/consensus/aura/src/lib.rs b/substrate/client/consensus/aura/src/lib.rs index bdeb4f15f3..cce58304d0 100644 --- a/substrate/client/consensus/aura/src/lib.rs +++ b/substrate/client/consensus/aura/src/lib.rs @@ -54,7 +54,7 @@ use sp_api::ProvideRuntimeApi; use sp_core::crypto::Pair; use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; use sp_inherents::{InherentDataProviders, InherentData}; -use sp_timestamp::{TimestampInherentData, InherentType as TimestampInherent}; +use sp_timestamp::TimestampInherentData; use sc_consensus_slots::{SlotInfo, SlotCompatible, StorageChanges, BackoffAuthoringBlocksStrategy}; use sc_telemetry::TelemetryHandle; use sp_consensus_slots::Slot; @@ -111,12 +111,12 @@ impl SlotCompatible for AuraSlotCompatible { fn extract_timestamp_and_slot( &self, data: &InherentData, - ) -> Result<(TimestampInherent, AuraInherent, std::time::Duration), sp_consensus::Error> { + ) -> Result<(u64, AuraInherent, std::time::Duration), sp_consensus::Error> { data.timestamp_inherent_data() .and_then(|t| data.aura_inherent_data().map(|a| (t, a))) .map_err(Into::into) .map_err(sp_consensus::Error::InherentData) - .map(|(x, y)| (x, y, Default::default())) + .map(|(x, y)| (*x, y, Default::default())) } } diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs index 1ea38820c9..3d72c43636 100644 --- a/substrate/client/consensus/babe/src/lib.rs +++ b/substrate/client/consensus/babe/src/lib.rs @@ -97,7 +97,7 @@ use sp_consensus::{ SelectChain, SlotData, import_queue::{Verifier, BasicQueue, DefaultImportQueue, CacheKeyId}, }; use sp_consensus_babe::inherents::BabeInherentData; -use sp_timestamp::{TimestampInherentData, InherentType as TimestampInherent}; +use sp_timestamp::TimestampInherentData; use sc_client_api::{ backend::AuxStore, BlockchainEvents, ProvideUncles, }; @@ -919,13 +919,13 @@ impl SlotCompatible for TimeSource { fn extract_timestamp_and_slot( &self, data: &InherentData, - ) -> Result<(TimestampInherent, Slot, std::time::Duration), sp_consensus::Error> { + ) -> Result<(u64, Slot, std::time::Duration), sp_consensus::Error> { trace!(target: "babe", "extract timestamp"); data.timestamp_inherent_data() .and_then(|t| data.babe_inherent_data().map(|a| (t, a))) .map_err(Into::into) .map_err(sp_consensus::Error::InherentData) - .map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default())) + .map(|(x, y)| (*x, y, self.0.lock().0.take().unwrap_or_default())) } } diff --git a/substrate/client/consensus/manual-seal/src/consensus/babe.rs b/substrate/client/consensus/manual-seal/src/consensus/babe.rs index 247a8d9091..7fe51c7b79 100644 --- a/substrate/client/consensus/manual-seal/src/consensus/babe.rs +++ b/substrate/client/consensus/manual-seal/src/consensus/babe.rs @@ -221,7 +221,7 @@ impl ConsensusDataProvider for BabeConsensusDataProvider if !has_authority { log::info!(target: "manual-seal", "authority not found"); - let slot = inherents.timestamp_inherent_data()? / self.config.slot_duration; + let slot = *inherents.timestamp_inherent_data()? / self.config.slot_duration; // manually hard code epoch descriptor epoch_descriptor = match epoch_descriptor { ViableEpochDescriptor::Signaled(identifier, _header) => { @@ -293,7 +293,10 @@ impl ProvideInherentData for SlotTimestampProvider { fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), sp_inherents::Error> { // we update the time here. - let duration: InherentType = self.time.fetch_add(self.slot_duration, atomic::Ordering::SeqCst); + let duration: InherentType = self.time.fetch_add( + self.slot_duration, + atomic::Ordering::SeqCst, + ).into(); inherent_data.put_data(INHERENT_IDENTIFIER, &duration)?; Ok(()) } diff --git a/substrate/client/consensus/pow/src/lib.rs b/substrate/client/consensus/pow/src/lib.rs index 19f339cf10..482bc80170 100644 --- a/substrate/client/consensus/pow/src/lib.rs +++ b/substrate/client/consensus/pow/src/lib.rs @@ -352,7 +352,7 @@ impl BlockImport for PowBlockImport { fn execute_block(block: Block); } +/// A trait which is called when the timestamp is set in the runtime. +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait OnTimestampSet { + /// Called when the timestamp is set. + fn on_timestamp_set(moment: Moment); +} + #[cfg(test)] mod tests { use super::*; diff --git a/substrate/frame/timestamp/src/lib.rs b/substrate/frame/timestamp/src/lib.rs index 0deef258ed..2ef24a696a 100644 --- a/substrate/frame/timestamp/src/lib.rs +++ b/substrate/frame/timestamp/src/lib.rs @@ -97,7 +97,7 @@ pub mod weights; use sp_std::{result, cmp}; use sp_inherents::InherentData; -use frame_support::traits::{Time, UnixTime}; +use frame_support::traits::{Time, UnixTime, OnTimestampSet}; use sp_runtime::{ RuntimeString, traits::{ @@ -106,7 +106,6 @@ use sp_runtime::{ }; use sp_timestamp::{ InherentError, INHERENT_IDENTIFIER, InherentType, - OnTimestampSet, }; pub use weights::WeightInfo; @@ -214,16 +213,17 @@ pub mod pallet { const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(data: &InherentData) -> Option { - let data: T::Moment = extract_inherent_data(data) - .expect("Gets and decodes timestamp inherent data") - .saturated_into(); + let inherent_data = extract_inherent_data(data) + .expect("Gets and decodes timestamp inherent data"); + let data = (*inherent_data).saturated_into::(); let next_time = cmp::max(data, Self::now() + T::MinimumPeriod::get()); Some(Call::set(next_time.into())) } fn check_inherent(call: &Self::Call, data: &InherentData) -> result::Result<(), Self::Error> { - const MAX_TIMESTAMP_DRIFT_MILLIS: u64 = 30 * 1000; + const MAX_TIMESTAMP_DRIFT_MILLIS: sp_timestamp::Timestamp = + sp_timestamp::Timestamp::new(30 * 1000); let t: u64 = match call { Call::set(ref t) => t.clone().saturated_into::(), @@ -233,10 +233,10 @@ pub mod pallet { let data = extract_inherent_data(data).map_err(|e| InherentError::Other(e))?; let minimum = (Self::now() + T::MinimumPeriod::get()).saturated_into::(); - if t > data + MAX_TIMESTAMP_DRIFT_MILLIS { + if t > *(data + MAX_TIMESTAMP_DRIFT_MILLIS) { Err(InherentError::Other("Timestamp too far in future to accept".into())) } else if t < minimum { - Err(InherentError::ValidAtTimestamp(minimum)) + Err(InherentError::ValidAtTimestamp(minimum.into())) } else { Ok(()) } diff --git a/substrate/primitives/consensus/aura/src/inherents.rs b/substrate/primitives/consensus/aura/src/inherents.rs index 35f686d934..750b13c77f 100644 --- a/substrate/primitives/consensus/aura/src/inherents.rs +++ b/substrate/primitives/consensus/aura/src/inherents.rs @@ -88,7 +88,7 @@ impl ProvideInherentData for InherentDataProvider { use sp_timestamp::TimestampInherentData; let timestamp = inherent_data.timestamp_inherent_data()?; - let slot = timestamp / self.slot_duration; + let slot = *timestamp / self.slot_duration; inherent_data.put_data(INHERENT_IDENTIFIER, &slot) } diff --git a/substrate/primitives/consensus/babe/src/inherents.rs b/substrate/primitives/consensus/babe/src/inherents.rs index 2f1a716114..8aeab94df3 100644 --- a/substrate/primitives/consensus/babe/src/inherents.rs +++ b/substrate/primitives/consensus/babe/src/inherents.rs @@ -83,7 +83,7 @@ impl ProvideInherentData for InherentDataProvider { fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> { let timestamp = inherent_data.timestamp_inherent_data()?; - let slot = timestamp / self.slot_duration; + let slot = *timestamp / self.slot_duration; inherent_data.put_data(INHERENT_IDENTIFIER, &slot) } diff --git a/substrate/primitives/std/with_std.rs b/substrate/primitives/std/with_std.rs index b044eb2912..8a283e8fe3 100644 --- a/substrate/primitives/std/with_std.rs +++ b/substrate/primitives/std/with_std.rs @@ -37,6 +37,7 @@ pub use std::sync; pub use std::result; pub use std::slice; pub use std::str; +pub use core::time; pub use std::vec; pub mod collections { diff --git a/substrate/primitives/std/without_std.rs b/substrate/primitives/std/without_std.rs index 697a0787e5..38c3a8421d 100755 --- a/substrate/primitives/std/without_std.rs +++ b/substrate/primitives/std/without_std.rs @@ -39,6 +39,7 @@ pub use core::result; pub use core::slice; // Allow interpreting vectors of bytes as strings, but not constructing them. pub use core::str; +pub use core::time; // We are trying to avoid certain things here, such as `core::string` // (if you need `String` you are probably doing something wrong, since // runtime doesn't require anything human readable). diff --git a/substrate/primitives/timestamp/Cargo.toml b/substrate/primitives/timestamp/Cargo.toml index 53fb37d4de..f3e9a331cf 100644 --- a/substrate/primitives/timestamp/Cargo.toml +++ b/substrate/primitives/timestamp/Cargo.toml @@ -18,7 +18,6 @@ sp-std = { version = "3.0.0", default-features = false, path = "../std" } sp-runtime = { version = "3.0.0", default-features = false, path = "../runtime" } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } sp-inherents = { version = "3.0.0", default-features = false, path = "../inherents" } -impl-trait-for-tuples = "0.2.1" wasm-timer = { version = "0.2", optional = true } [features] diff --git a/substrate/primitives/timestamp/src/lib.rs b/substrate/primitives/timestamp/src/lib.rs index 59f792678c..e6ef62b5c5 100644 --- a/substrate/primitives/timestamp/src/lib.rs +++ b/substrate/primitives/timestamp/src/lib.rs @@ -19,9 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::Encode; -#[cfg(feature = "std")] -use codec::Decode; +use codec::{Encode, Decode}; #[cfg(feature = "std")] use sp_inherents::ProvideInherentData; use sp_inherents::{InherentIdentifier, IsFatalError, InherentData}; @@ -30,8 +28,83 @@ use sp_runtime::RuntimeString; /// The identifier for the `timestamp` inherent. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0"; + /// The type of the inherent. -pub type InherentType = u64; +pub type InherentType = Timestamp; + +/// Unit type wrapper that represents a timestamp. +/// +/// Such a timestamp is the time since the UNIX_EPOCH in milliseconds at a given point in time. +#[derive(Debug, Encode, Decode, Eq, Clone, Copy, Default, Ord)] +pub struct Timestamp(u64); + +impl Timestamp { + /// Create new `Self`. + pub const fn new(inner: u64) -> Self { + Self(inner) + } +} + +impl sp_std::ops::Deref for Timestamp { + type Target = u64; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl core::ops::Add for Timestamp { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self(self.0 + other.0) + } +} + +impl core::ops::Add for Timestamp { + type Output = Self; + + fn add(self, other: u64) -> Self { + Self(self.0 + other) + } +} + +impl + Copy> core::cmp::PartialEq for Timestamp { + fn eq(&self, eq: &T) -> bool { + self.0 == (*eq).into() + } +} + +impl + Copy> core::cmp::PartialOrd for Timestamp { + fn partial_cmp(&self, other: &T) -> Option { + self.0.partial_cmp(&(*other).into()) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for Timestamp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From for Timestamp { + fn from(timestamp: u64) -> Self { + Timestamp(timestamp) + } +} + +impl From for u64 { + fn from(timestamp: Timestamp) -> u64 { + timestamp.0 + } +} + +impl From for Timestamp { + fn from(duration: sp_std::time::Duration) -> Self { + Timestamp(duration.as_millis() as u64) + } +} /// Errors that can occur while checking the timestamp inherent. #[derive(Encode, sp_runtime::RuntimeDebug)] @@ -99,8 +172,7 @@ impl ProvideInherentData for InherentDataProvider { .map_err(|_| { "Current time is before unix epoch".into() }).and_then(|d| { - let duration: InherentType = d.as_millis() as u64; - inherent_data.put_data(INHERENT_IDENTIFIER, &duration) + inherent_data.put_data(INHERENT_IDENTIFIER, &InherentType::from(d)) }) } @@ -109,9 +181,3 @@ impl ProvideInherentData for InherentDataProvider { } } - -/// A trait which is called when the timestamp is set. -#[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait OnTimestampSet { - fn on_timestamp_set(moment: Moment); -}