15
15
// See the License for the specific language governing permissions and
16
16
// limitations under the License.
17
17
18
- //! # Timestamp Module
18
+ //! # Timestamp Pallet
19
19
//!
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.
21
21
//!
22
22
//! - [`timestamp::Config`](./trait.Config.html)
23
23
//! - [`Call`](./enum.Call.html)
24
- //! - [`Module `](./struct.Module .html)
24
+ //! - [`Pallet `](./struct.Pallet .html)
25
25
//!
26
26
//! ## Overview
27
27
//!
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.
29
29
//!
30
30
//! It uses inherents for timestamp data, which is provided by the block author and validated/verified
31
31
//! by other validators. The timestamp can be set only once per block and must be set each block.
32
32
//! There could be a constraint on how much time must pass before setting the new timestamp.
33
33
//!
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
35
35
//! an approach based on block numbers. The block number based time measurement can cause issues
36
36
//! because of cumulative calculation errors and hence should be avoided.
37
37
//!
52
52
//!
53
53
//! ## Usage
54
54
//!
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.
56
56
//!
57
57
//! ### Prerequisites
58
58
//!
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
60
60
//! trait from the timestamp trait.
61
61
//!
62
62
//! ### Get current timestamp
83
83
//!
84
84
//! ### Example from the FRAME
85
85
//!
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.
88
88
//!
89
- //! ## Related Modules
89
+ //! ## Related Pallets
90
90
//!
91
91
//! * [Session](../pallet_session/index.html)
92
92
@@ -96,54 +96,83 @@ mod benchmarking;
96
96
pub mod weights;
97
97
98
98
use sp_std:: { result, cmp} ;
99
- use sp_inherents:: { ProvideInherent , InherentData , InherentIdentifier } ;
99
+ use sp_inherents:: InherentData ;
100
100
#[ cfg( feature = "std" ) ]
101
101
use 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 } ;
107
103
use sp_runtime:: {
108
104
RuntimeString ,
109
105
traits:: {
110
106
AtLeast32Bit , Zero , SaturatedConversion , Scale ,
111
107
}
112
108
} ;
113
- use frame_system:: ensure_none;
114
109
use sp_timestamp:: {
115
110
InherentError , INHERENT_IDENTIFIER , InherentType ,
116
111
OnTimestampSet ,
117
112
} ;
118
113
pub use weights:: WeightInfo ;
119
114
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:: * ;
125
116
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 :: * ;
128
122
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 ;
134
129
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 > ;
138
132
139
- decl_module ! {
140
- pub struct Module <T : Config > for enum Call where origin: T :: Origin {
141
133
/// The minimum period between blocks. Beware that this is different to the *expected* period
142
134
/// that the block production apparatus provides. Your chosen consensus system will generally
143
135
/// work with this to determine a sensible block time. e.g. For Aura, it will be double this
144
136
/// 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
+ }
146
173
174
+ #[ pallet:: call]
175
+ impl < T : Config > Pallet < T > {
147
176
/// Set the current time.
148
177
///
149
178
/// This call should be invoked exactly once per block. It will panic at the finalization
@@ -159,51 +188,65 @@ decl_module! {
159
188
/// - 1 storage read and 1 storage mutation (codec `O(1)`). (because of `DidUpdate::take` in `on_finalize`)
160
189
/// - 1 event handler `on_timestamp_set`. Must be `O(1)`.
161
190
/// # </weight>
162
- #[ weight = (
191
+ #[ pallet :: weight( (
163
192
T :: WeightInfo :: set( ) ,
164
193
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 {
167
196
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" ) ;
169
198
let prev = Self :: now ( ) ;
170
199
assert ! (
171
200
prev. is_zero( ) || now >= prev + T :: MinimumPeriod :: get( ) ,
172
201
"Timestamp must increment by at least <MinimumPeriod> between sequential blocks"
173
202
) ;
174
- < Self as Store > :: Now :: put( now) ;
175
- < Self as Store > :: DidUpdate :: put( true ) ;
203
+ Now :: < T > :: put ( now) ;
204
+ DidUpdate :: < T > :: put ( true ) ;
176
205
177
206
<T :: OnTimestampSet as OnTimestampSet < _ > >:: on_timestamp_set ( now) ;
178
- }
179
207
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 ( ) )
184
209
}
210
+ }
185
211
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 ( ) ) )
192
225
}
193
- }
194
- }
195
226
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 ;
200
229
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
+ }
203
246
}
204
247
}
205
248
206
- impl < T : Config > Module < T > {
249
+ impl < T : Config > Pallet < T > {
207
250
/// Get the current time for the current block.
208
251
///
209
252
/// NOTE: if this function is called prior to setting the timestamp,
@@ -215,7 +258,7 @@ impl<T: Config> Module<T> {
215
258
/// Set the timestamp to something in particular. Only used for tests.
216
259
#[ cfg( feature = "std" ) ]
217
260
pub fn set_timestamp ( now : T :: Moment ) {
218
- < Self as Store > :: Now :: put ( now) ;
261
+ Now :: < T > :: put ( now) ;
219
262
}
220
263
}
221
264
@@ -225,42 +268,7 @@ fn extract_inherent_data(data: &InherentData) -> Result<InherentType, RuntimeStr
225
268
. ok_or_else ( || "Timestamp inherent data is not provided." . into ( ) )
226
269
}
227
270
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 > {
264
272
type Moment = T :: Moment ;
265
273
266
274
/// Before the first set of now with inherent the value returned is zero.
@@ -272,7 +280,7 @@ impl<T: Config> Time for Module<T> {
272
280
/// Before the timestamp inherent is applied, it returns the time of previous block.
273
281
///
274
282
/// On genesis the time returned is not valid.
275
- impl < T : Config > UnixTime for Module < T > {
283
+ impl < T : Config > UnixTime for Pallet < T > {
276
284
fn now ( ) -> core:: time:: Duration {
277
285
// now is duration since unix epoch in millisecond as documented in
278
286
// `sp_timestamp::InherentDataProvider`.
0 commit comments