1#![cfg_attr(not(feature = "std"), no_std)]
21
22use codec::Encode;
23#[cfg(feature = "std")]
24use codec::Decode;
25#[cfg(feature = "std")]
26use tp_inherents::ProvideInherentData;
27use tp_inherents::{InherentIdentifier, IsFatalError, InherentData};
28
29use tp_runtime::RuntimeString;
30
31pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0";
33pub type InherentType = u64;
35
36#[derive(Encode, tp_runtime::RuntimeDebug)]
38#[cfg_attr(feature = "std", derive(Decode))]
39pub enum InherentError {
40 ValidAtTimestamp(InherentType),
43 Other(RuntimeString),
45}
46
47impl IsFatalError for InherentError {
48 fn is_fatal_error(&self) -> bool {
49 match self {
50 InherentError::ValidAtTimestamp(_) => false,
51 InherentError::Other(_) => true,
52 }
53 }
54}
55
56impl InherentError {
57 #[cfg(feature = "std")]
59 pub fn try_from(id: &InherentIdentifier, data: &[u8]) -> Option<Self> {
60 if id == &INHERENT_IDENTIFIER {
61 <InherentError as codec::Decode>::decode(&mut &data[..]).ok()
62 } else {
63 None
64 }
65 }
66}
67
68pub trait TimestampInherentData {
70 fn timestamp_inherent_data(&self) -> Result<InherentType, tp_inherents::Error>;
72}
73
74impl TimestampInherentData for InherentData {
75 fn timestamp_inherent_data(&self) -> Result<InherentType, tp_inherents::Error> {
76 self.get_data(&INHERENT_IDENTIFIER)
77 .and_then(|r| r.ok_or_else(|| "Timestamp inherent data not found".into()))
78 }
79}
80
81#[cfg(feature = "std")]
83pub struct InherentDataProvider;
84
85#[cfg(feature = "std")]
86impl ProvideInherentData for InherentDataProvider {
87 fn inherent_identifier(&self) -> &'static InherentIdentifier {
88 &INHERENT_IDENTIFIER
89 }
90
91 fn provide_inherent_data(
92 &self,
93 inherent_data: &mut InherentData,
94 ) -> Result<(), tp_inherents::Error> {
95 use wasm_timer::SystemTime;
96
97 let now = SystemTime::now();
98 now.duration_since(SystemTime::UNIX_EPOCH)
99 .map_err(|_| {
100 "Current time is before unix epoch".into()
101 }).and_then(|d| {
102 let duration: InherentType = d.as_millis() as u64;
103 inherent_data.put_data(INHERENT_IDENTIFIER, &duration)
104 })
105 }
106
107 fn error_to_string(&self, error: &[u8]) -> Option<String> {
108 InherentError::try_from(&INHERENT_IDENTIFIER, error).map(|e| format!("{:?}", e))
109 }
110}
111
112
113#[impl_trait_for_tuples::impl_for_tuples(30)]
115pub trait OnTimestampSet<Moment> {
116 fn on_timestamp_set(moment: Moment);
117}