1515// See the License for the specific language governing permissions and
1616// limitations under the License.
1717
18- //! # Timestamp Module
18+ //! # Timestamp Pallet
1919//!
20- //! The Timestamp module provides functionality to get and set the on-chain time.
20+ //! The Timestamp pallet provides functionality to get and set the on-chain time.
2121//!
2222//! - [`timestamp::Config`](./trait.Config.html)
2323//! - [`Call`](./enum.Call.html)
24- //! - [`Module `](./struct.Module .html)
24+ //! - [`Pallet `](./struct.Pallet .html)
2525//!
2626//! ## Overview
2727//!
28- //! The Timestamp module allows the validators to set and validate a timestamp with each block.
28+ //! The Timestamp pallet allows the validators to set and validate a timestamp with each block.
2929//!
3030//! It uses inherents for timestamp data, which is provided by the block author and validated/verified
3131//! by other validators. The timestamp can be set only once per block and must be set each block.
3232//! There could be a constraint on how much time must pass before setting the new timestamp.
3333//!
34- //! **NOTE:** The Timestamp module is the recommended way to query the on-chain time instead of using
34+ //! **NOTE:** The Timestamp pallet is the recommended way to query the on-chain time instead of using
3535//! an approach based on block numbers. The block number based time measurement can cause issues
3636//! because of cumulative calculation errors and hence should be avoided.
3737//!
5252//!
5353//! ## Usage
5454//!
55- //! The following example shows how to use the Timestamp module in your custom module to query the current timestamp.
55+ //! The following example shows how to use the Timestamp pallet in your custom pallet to query the current timestamp.
5656//!
5757//! ### Prerequisites
5858//!
59- //! Import the Timestamp module into your custom module and derive the module configuration
59+ //! Import the Timestamp pallet into your custom pallet and derive the pallet configuration
6060//! trait from the timestamp trait.
6161//!
6262//! ### Get current timestamp
8383//!
8484//! ### Example from the FRAME
8585//!
86- //! The [Session module ](https://github.com/paritytech/substrate/blob/master/frame/session/src/lib.rs) uses
87- //! the Timestamp module for session management.
86+ //! The [Session pallet ](https://github.com/paritytech/substrate/blob/master/frame/session/src/lib.rs) uses
87+ //! the Timestamp pallet for session management.
8888//!
89- //! ## Related Modules
89+ //! ## Related Pallets
9090//!
9191//! * [Session](../pallet_session/index.html)
9292
@@ -96,54 +96,83 @@ mod benchmarking;
9696pub mod weights;
9797
9898use sp_std:: { result, cmp} ;
99- use sp_inherents:: { ProvideInherent , InherentData , InherentIdentifier } ;
99+ use sp_inherents:: InherentData ;
100100#[ cfg( feature = "std" ) ]
101101use frame_support:: debug;
102- use frame_support:: {
103- Parameter , decl_storage, decl_module,
104- traits:: { Time , UnixTime , Get } ,
105- weights:: { DispatchClass , Weight } ,
106- } ;
102+ use frame_support:: traits:: { Time , UnixTime } ;
107103use sp_runtime:: {
108104 RuntimeString ,
109105 traits:: {
110106 AtLeast32Bit , Zero , SaturatedConversion , Scale ,
111107 }
112108} ;
113- use frame_system:: ensure_none;
114109use sp_timestamp:: {
115110 InherentError , INHERENT_IDENTIFIER , InherentType ,
116111 OnTimestampSet ,
117112} ;
118113pub use weights:: WeightInfo ;
119114
120- /// The module configuration trait
121- pub trait Config : frame_system:: Config {
122- /// Type used for expressing timestamp.
123- type Moment : Parameter + Default + AtLeast32Bit
124- + Scale < Self :: BlockNumber , Output = Self :: Moment > + Copy ;
115+ pub use pallet:: * ;
125116
126- /// Something which can be notified when the timestamp is set. Set this to `()` if not needed.
127- type OnTimestampSet : OnTimestampSet < Self :: Moment > ;
117+ #[ frame_support:: pallet]
118+ pub mod pallet {
119+ use frame_support:: pallet_prelude:: * ;
120+ use frame_system:: pallet_prelude:: * ;
121+ use super :: * ;
128122
129- /// The minimum period between blocks. Beware that this is different to the *expected* period
130- /// that the block production apparatus provides. Your chosen consensus system will generally
131- /// work with this to determine a sensible block time. e.g. For Aura, it will be double this
132- /// period on default settings.
133- type MinimumPeriod : Get < Self :: Moment > ;
123+ /// The pallet configuration trait
124+ #[ pallet:: config]
125+ pub trait Config : frame_system:: Config {
126+ /// Type used for expressing timestamp.
127+ type Moment : Parameter + Default + AtLeast32Bit
128+ + Scale < Self :: BlockNumber , Output = Self :: Moment > + Copy ;
134129
135- /// Weight information for extrinsics in this pallet.
136- type WeightInfo : WeightInfo ;
137- }
130+ /// Something which can be notified when the timestamp is set. Set this to `()` if not needed.
131+ type OnTimestampSet : OnTimestampSet < Self :: Moment > ;
138132
139- decl_module ! {
140- pub struct Module <T : Config > for enum Call where origin: T :: Origin {
141133 /// The minimum period between blocks. Beware that this is different to the *expected* period
142134 /// that the block production apparatus provides. Your chosen consensus system will generally
143135 /// work with this to determine a sensible block time. e.g. For Aura, it will be double this
144136 /// period on default settings.
145- const MinimumPeriod : T :: Moment = T :: MinimumPeriod :: get( ) ;
137+ #[ pallet:: constant]
138+ type MinimumPeriod : Get < Self :: Moment > ;
139+
140+ /// Weight information for extrinsics in this pallet.
141+ type WeightInfo : WeightInfo ;
142+ }
143+
144+ #[ pallet:: pallet]
145+ #[ pallet:: generate_store( pub ( super ) trait Store ) ]
146+ pub struct Pallet < T > ( PhantomData < T > ) ;
147+
148+ /// Current time for the current block.
149+ #[ pallet:: storage]
150+ #[ pallet:: getter( fn now) ]
151+ pub type Now < T : Config > = StorageValue < _ , T :: Moment , ValueQuery > ;
152+
153+ /// Did the timestamp get updated in this block?
154+ #[ pallet:: storage]
155+ pub ( super ) type DidUpdate < T : Config > = StorageValue < _ , bool , ValueQuery > ;
156+
157+ #[ pallet:: hooks]
158+ impl < T : Config > Hooks < BlockNumberFor < T > > for Pallet < T > {
159+ /// dummy `on_initialize` to return the weight used in `on_finalize`.
160+ fn on_initialize ( _n : BlockNumberFor < T > ) -> Weight {
161+ // weight of `on_finalize`
162+ T :: WeightInfo :: on_finalize ( )
163+ }
164+
165+ /// # <weight>
166+ /// - `O(1)`
167+ /// - 1 storage deletion (codec `O(1)`).
168+ /// # </weight>
169+ fn on_finalize ( _n : BlockNumberFor < T > ) {
170+ assert ! ( DidUpdate :: <T >:: take( ) , "Timestamp must be updated once in the block" ) ;
171+ }
172+ }
146173
174+ #[ pallet:: call]
175+ impl < T : Config > Pallet < T > {
147176 /// Set the current time.
148177 ///
149178 /// This call should be invoked exactly once per block. It will panic at the finalization
@@ -159,51 +188,65 @@ decl_module! {
159188 /// - 1 storage read and 1 storage mutation (codec `O(1)`). (because of `DidUpdate::take` in `on_finalize`)
160189 /// - 1 event handler `on_timestamp_set`. Must be `O(1)`.
161190 /// # </weight>
162- #[ weight = (
191+ #[ pallet :: weight( (
163192 T :: WeightInfo :: set( ) ,
164193 DispatchClass :: Mandatory
165- ) ]
166- fn set( origin, #[ compact] now: T :: Moment ) {
194+ ) ) ]
195+ pub ( super ) fn set ( origin : OriginFor < T > , #[ pallet :: compact] now : T :: Moment ) -> DispatchResultWithPostInfo {
167196 ensure_none ( origin) ?;
168- assert!( !< Self as Store > :: DidUpdate :: exists( ) , "Timestamp must be updated only once in the block" ) ;
197+ assert ! ( !DidUpdate :: < T > :: exists( ) , "Timestamp must be updated only once in the block" ) ;
169198 let prev = Self :: now ( ) ;
170199 assert ! (
171200 prev. is_zero( ) || now >= prev + T :: MinimumPeriod :: get( ) ,
172201 "Timestamp must increment by at least <MinimumPeriod> between sequential blocks"
173202 ) ;
174- < Self as Store > :: Now :: put( now) ;
175- < Self as Store > :: DidUpdate :: put( true ) ;
203+ Now :: < T > :: put ( now) ;
204+ DidUpdate :: < T > :: put ( true ) ;
176205
177206 <T :: OnTimestampSet as OnTimestampSet < _ > >:: on_timestamp_set ( now) ;
178- }
179207
180- /// dummy `on_initialize` to return the weight used in `on_finalize`.
181- fn on_initialize( ) -> Weight {
182- // weight of `on_finalize`
183- T :: WeightInfo :: on_finalize( )
208+ Ok ( ( ) . into ( ) )
184209 }
210+ }
185211
186- /// # <weight>
187- /// - `O(1)`
188- /// - 1 storage deletion (codec `O(1)`).
189- /// # </weight>
190- fn on_finalize( ) {
191- assert!( <Self as Store >:: DidUpdate :: take( ) , "Timestamp must be updated once in the block" ) ;
212+ #[ pallet:: inherent]
213+ impl < T : Config > ProvideInherent for Pallet < T > {
214+ type Call = Call < T > ;
215+ type Error = InherentError ;
216+ const INHERENT_IDENTIFIER : InherentIdentifier = INHERENT_IDENTIFIER ;
217+
218+ fn create_inherent ( data : & InherentData ) -> Option < Self :: Call > {
219+ let data: T :: Moment = extract_inherent_data ( data)
220+ . expect ( "Gets and decodes timestamp inherent data" )
221+ . saturated_into ( ) ;
222+
223+ let next_time = cmp:: max ( data, Self :: now ( ) + T :: MinimumPeriod :: get ( ) ) ;
224+ Some ( Call :: set ( next_time. into ( ) ) )
192225 }
193- }
194- }
195226
196- decl_storage ! {
197- trait Store for Module <T : Config > as Timestamp {
198- /// Current time for the current block.
199- pub Now get( fn now) : T :: Moment ;
227+ fn check_inherent ( call : & Self :: Call , data : & InherentData ) -> result:: Result < ( ) , Self :: Error > {
228+ const MAX_TIMESTAMP_DRIFT_MILLIS : u64 = 30 * 1000 ;
200229
201- /// Did the timestamp get updated in this block?
202- DidUpdate : bool ;
230+ let t: u64 = match call {
231+ Call :: set( ref t) => t. clone ( ) . saturated_into :: < u64 > ( ) ,
232+ _ => return Ok ( ( ) ) ,
233+ } ;
234+
235+ let data = extract_inherent_data ( data) . map_err ( |e| InherentError :: Other ( e) ) ?;
236+
237+ let minimum = ( Self :: now ( ) + T :: MinimumPeriod :: get ( ) ) . saturated_into :: < u64 > ( ) ;
238+ if t > data + MAX_TIMESTAMP_DRIFT_MILLIS {
239+ Err ( InherentError :: Other ( "Timestamp too far in future to accept" . into ( ) ) )
240+ } else if t < minimum {
241+ Err ( InherentError :: ValidAtTimestamp ( minimum) )
242+ } else {
243+ Ok ( ( ) )
244+ }
245+ }
203246 }
204247}
205248
206- impl < T : Config > Module < T > {
249+ impl < T : Config > Pallet < T > {
207250 /// Get the current time for the current block.
208251 ///
209252 /// NOTE: if this function is called prior to setting the timestamp,
@@ -215,7 +258,7 @@ impl<T: Config> Module<T> {
215258 /// Set the timestamp to something in particular. Only used for tests.
216259 #[ cfg( feature = "std" ) ]
217260 pub fn set_timestamp ( now : T :: Moment ) {
218- < Self as Store > :: Now :: put ( now) ;
261+ Now :: < T > :: put ( now) ;
219262 }
220263}
221264
@@ -225,42 +268,7 @@ fn extract_inherent_data(data: &InherentData) -> Result<InherentType, RuntimeStr
225268 . ok_or_else ( || "Timestamp inherent data is not provided." . into ( ) )
226269}
227270
228- impl < T : Config > ProvideInherent for Module < T > {
229- type Call = Call < T > ;
230- type Error = InherentError ;
231- const INHERENT_IDENTIFIER : InherentIdentifier = INHERENT_IDENTIFIER ;
232-
233- fn create_inherent ( data : & InherentData ) -> Option < Self :: Call > {
234- let data: T :: Moment = extract_inherent_data ( data)
235- . expect ( "Gets and decodes timestamp inherent data" )
236- . saturated_into ( ) ;
237-
238- let next_time = cmp:: max ( data, Self :: now ( ) + T :: MinimumPeriod :: get ( ) ) ;
239- Some ( Call :: set ( next_time. into ( ) ) )
240- }
241-
242- fn check_inherent ( call : & Self :: Call , data : & InherentData ) -> result:: Result < ( ) , Self :: Error > {
243- const MAX_TIMESTAMP_DRIFT_MILLIS : u64 = 30 * 1000 ;
244-
245- let t: u64 = match call {
246- Call :: set( ref t) => t. clone ( ) . saturated_into :: < u64 > ( ) ,
247- _ => return Ok ( ( ) ) ,
248- } ;
249-
250- let data = extract_inherent_data ( data) . map_err ( |e| InherentError :: Other ( e) ) ?;
251-
252- let minimum = ( Self :: now ( ) + T :: MinimumPeriod :: get ( ) ) . saturated_into :: < u64 > ( ) ;
253- if t > data + MAX_TIMESTAMP_DRIFT_MILLIS {
254- Err ( InherentError :: Other ( "Timestamp too far in future to accept" . into ( ) ) )
255- } else if t < minimum {
256- Err ( InherentError :: ValidAtTimestamp ( minimum) )
257- } else {
258- Ok ( ( ) )
259- }
260- }
261- }
262-
263- impl < T : Config > Time for Module < T > {
271+ impl < T : Config > Time for Pallet < T > {
264272 type Moment = T :: Moment ;
265273
266274 /// Before the first set of now with inherent the value returned is zero.
@@ -272,7 +280,7 @@ impl<T: Config> Time for Module<T> {
272280/// Before the timestamp inherent is applied, it returns the time of previous block.
273281///
274282/// On genesis the time returned is not valid.
275- impl < T : Config > UnixTime for Module < T > {
283+ impl < T : Config > UnixTime for Pallet < T > {
276284 fn now ( ) -> core:: time:: Duration {
277285 // now is duration since unix epoch in millisecond as documented in
278286 // `sp_timestamp::InherentDataProvider`.
0 commit comments