Convert timestamp to unit type wrapper (#8333)

The timestamp inherent type was up to now just a simple `u64`. This
worked, but doesn't give you that much guarantees at compile time about
the type. This pr changes that by converting this type to a unit type
wrapper, similar to what we have done for `Slot`.

This is required for some future pr that touches quite a lot of the
inherents stuff :)

Besides this unit wrapper type, this pr also moves the `OnTimestampSet`
trait to `frame_support::traits`.
This commit is contained in:
Bastian Köcher
2021-03-11 23:33:34 +01:00
committed by GitHub
parent 39f3b77f4b
commit 5d73e960da
17 changed files with 113 additions and 43 deletions
@@ -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)
}
@@ -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)
}
+1
View File
@@ -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 {
+1
View File
@@ -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).
@@ -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]
+78 -12
View File
@@ -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<u64> for Timestamp {
type Output = Self;
fn add(self, other: u64) -> Self {
Self(self.0 + other)
}
}
impl<T: Into<u64> + Copy> core::cmp::PartialEq<T> for Timestamp {
fn eq(&self, eq: &T) -> bool {
self.0 == (*eq).into()
}
}
impl<T: Into<u64> + Copy> core::cmp::PartialOrd<T> for Timestamp {
fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
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<u64> for Timestamp {
fn from(timestamp: u64) -> Self {
Timestamp(timestamp)
}
}
impl From<Timestamp> for u64 {
fn from(timestamp: Timestamp) -> u64 {
timestamp.0
}
}
impl From<sp_std::time::Duration> 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<Moment> {
fn on_timestamp_set(moment: Moment);
}