99 sidechain_domain:: mainchain_epoch:: MainchainEpochDerivation ,
1010 sidechain_domain:: * ,
1111 sp_api:: ProvideRuntimeApi ,
12- sp_consensus_slots:: Slot ,
1312 sp_inherents:: { InherentData , InherentIdentifier } ,
1413 sp_runtime:: traits:: Block as BlockT ,
1514 sp_session_validator_management:: CommitteeMember as CommitteeMemberT ,
1918} ;
2019
2120#[ cfg( feature = "std" ) ]
22- pub use { sidechain_domain:: mainchain_epoch:: MainchainEpochConfig , sidechain_slots :: ScSlotConfig } ;
21+ pub use sidechain_domain:: mainchain_epoch:: MainchainEpochConfig ;
2322
2423#[ derive( Clone , Debug , Encode , Decode ) ]
2524/// Inherent data provider providing inputs for authority selection.
@@ -34,18 +33,18 @@ impl AriadneInherentDataProvider {
3433 ///
3534 /// Parameters:
3635 /// - `client`: runtime client capable of providing [SessionValidatorManagementApi] runtime API
37- /// - `sc_slot_config `: partner chain slot configuration
36+ /// - `sc_epoch_duration_millis `: duration of the Partner Chain epoch in milliseconds
3837 /// - `mc_epoch_config`: main chain epoch configuration
3938 /// - `parent_hash`: parent hash of the current block
40- /// - `slot `: slot of the current block
39+ /// - `timestamp_millis `: timestamp of current block in milliseconds
4140 /// - `data_source`: data source implementing [AuthoritySelectionDataSource]
4241 /// - `mc_reference_epoch`: latest stable mainchain epoch
4342 pub async fn new < Block , CommitteeMember , T > (
4443 client : & T ,
45- sc_slot_config : & ScSlotConfig ,
44+ sc_epoch_duration_millis : u64 ,
4645 mc_epoch_config : & MainchainEpochConfig ,
4746 parent_hash : <Block as BlockT >:: Hash ,
48- slot : Slot ,
47+ timestamp_millis : u64 ,
4948 data_source : & ( dyn AuthoritySelectionDataSource + Send + Sync ) ,
5049 mc_reference_epoch : McEpochNumber ,
5150 ) -> Result < Self , InherentProviderCreationError >
@@ -64,10 +63,10 @@ impl AriadneInherentDataProvider {
6463 {
6564 let for_mc_epoch = mc_epoch_for_next_ariadne_cidp (
6665 client,
67- sc_slot_config ,
66+ sc_epoch_duration_millis ,
6867 mc_epoch_config,
6968 parent_hash,
70- slot ,
69+ timestamp_millis ,
7170 ) ?;
7271
7372 let data_epoch = data_source. data_epoch ( for_mc_epoch) . await ?;
@@ -100,9 +99,6 @@ impl AriadneInherentDataProvider {
10099#[ derive( Debug , thiserror:: Error ) ]
101100/// Error type returned when creation of [AriadneInherentDataProvider] fails.
102101pub enum InherentProviderCreationError {
103- /// Slot represents a timestamp bigger than of [u64::MAX].
104- #[ error( "Slot represents a timestamp bigger than of u64::MAX" ) ]
105- SlotTooBig ,
106102 /// Couldn't convert timestamp to main chain epoch.
107103 #[ error( "Couldn't convert timestamp to main chain epoch: {0}" ) ]
108104 McEpochDerivationError ( #[ from] sidechain_domain:: mainchain_epoch:: EpochDerivationError ) ,
@@ -120,10 +116,10 @@ pub enum InherentProviderCreationError {
120116#[ cfg( feature = "std" ) ]
121117fn mc_epoch_for_next_ariadne_cidp < Block , CommitteeMember , T > (
122118 client : & T ,
123- sc_slot_config : & ScSlotConfig ,
119+ sc_epoch_duration_millis : u64 ,
124120 epoch_config : & MainchainEpochConfig ,
125121 parent_hash : <Block as BlockT >:: Hash ,
126- slot : Slot ,
122+ timestamp_millis : u64 ,
127123) -> Result < McEpochNumber , InherentProviderCreationError >
128124where
129125 Block : BlockT ,
@@ -138,34 +134,27 @@ where
138134 ScEpochNumber ,
139135 > ,
140136{
137+ use sp_core:: offchain:: Timestamp ;
138+
141139 let next_unset_epoch = client. runtime_api ( ) . get_next_unset_epoch_number ( parent_hash) ?;
142140
143- let for_sc_epoch_number = {
141+ let for_timestamp = {
144142 // A special case for the genesis committee (current epoch 0, next unset epoch 1).
145143 // The genesis committee epoch is initialized with 0, so in the very first block we need to provide
146- // the epoch number based on the current slot number
144+ // the epoch number based on the current timestamp
147145 if next_unset_epoch == ScEpochNumber ( 1 ) {
148- sc_slot_config. epoch_number ( slot)
146+ // We first convert the timestamp to PC epoch number and then use the starting time of this
147+ // to ensure that all timestamps within a PC epoch produce the same candidates. This is
148+ // necessary in case the boundaries of PC epochs and MC epochs do not align.
149+ let current_pc_epoch = timestamp_millis / sc_epoch_duration_millis;
150+ current_pc_epoch * sc_epoch_duration_millis
149151 } else {
150- next_unset_epoch
152+ next_unset_epoch. 0 * sc_epoch_duration_millis
151153 }
152154 } ;
153155
154- sc_epoch_to_mc_epoch ( for_sc_epoch_number, sc_slot_config, epoch_config)
155- }
156-
157- #[ cfg( feature = "std" ) ]
158- fn sc_epoch_to_mc_epoch (
159- sc_epoch : ScEpochNumber ,
160- sc_slot_config : & ScSlotConfig ,
161- epoch_config : & MainchainEpochConfig ,
162- ) -> Result < McEpochNumber , InherentProviderCreationError > {
163- let timestamp = sc_slot_config
164- . epoch_start_time ( sc_epoch)
165- . ok_or ( InherentProviderCreationError :: SlotTooBig ) ?;
166-
167156 epoch_config
168- . timestamp_to_mainchain_epoch ( timestamp )
157+ . timestamp_to_mainchain_epoch ( Timestamp :: from_unix_millis ( for_timestamp ) )
169158 . map_err ( InherentProviderCreationError :: McEpochDerivationError )
170159}
171160
@@ -205,24 +194,24 @@ mod tests {
205194 use crate :: ariadne_inherent_data_provider:: AriadneInherentDataProvider ;
206195 use crate :: mock:: MockAuthoritySelectionDataSource ;
207196 use crate :: runtime_api_mock:: * ;
208- use SlotDuration ;
209197 use sidechain_domain:: mainchain_epoch:: * ;
210- use sidechain_slots:: * ;
211198 use sp_core:: H256 ;
212199 use sp_core:: offchain:: Timestamp ;
213200
201+ const TIMESTAMP : u64 = 400_000 ;
202+
214203 #[ tokio:: test]
215204 async fn return_empty_ariadne_cidp_if_runtime_requests_too_new_epoch ( ) {
216205 // This is the epoch number that is too new
217206 let next_unset_epoch_number = ScEpochNumber ( 42 ) ;
218207 let mc_reference_epoch = McEpochNumber ( 1 ) ;
219208 let empty_ariadne_idp = AriadneInherentDataProvider :: new (
220209 & client ( next_unset_epoch_number) ,
221- & sc_slot_config ( ) ,
210+ sc_epoch_duration_millis ( ) ,
222211 & epoch_config ( ) ,
223212 H256 :: zero ( ) ,
224- // This is the slot that will be used to calculate current_epoch_number
225- Slot :: from ( 400u64 ) ,
213+ // This is the timestamp that will be used to calculate current_epoch_number
214+ TIMESTAMP ,
226215 & MockAuthoritySelectionDataSource :: default ( ) ,
227216 mc_reference_epoch,
228217 )
@@ -241,11 +230,11 @@ mod tests {
241230 let mc_reference_epoch = McEpochNumber ( 5 ) ;
242231 let ariadne_idp = AriadneInherentDataProvider :: new (
243232 & client ( next_unset_epoch_number) ,
244- & sc_slot_config ( ) ,
233+ sc_epoch_duration_millis ( ) ,
245234 & epoch_config ( ) ,
246235 H256 :: zero ( ) ,
247- // This is the slot that will be used to calculate current_epoch_number
248- Slot :: from ( 400u64 ) ,
236+ // This is the timestamp that will be used to calculate current_epoch_number
237+ TIMESTAMP ,
249238 & MockAuthoritySelectionDataSource :: default ( )
250239 . with_permissioned_candidates ( vec ! [ None , None , None , None , None ] )
251240 . with_num_permissioned_candidates ( 3 ) ,
@@ -266,11 +255,11 @@ mod tests {
266255 let mc_reference_epoch = McEpochNumber ( 5 ) ;
267256 let ariadne_idp = AriadneInherentDataProvider :: new (
268257 & client ( next_unset_epoch_number) ,
269- & sc_slot_config ( ) ,
258+ sc_epoch_duration_millis ( ) ,
270259 & epoch_config ( ) ,
271260 H256 :: zero ( ) ,
272- // This is the slot that will be used to calculate current_epoch_number
273- Slot :: from ( 400u64 ) ,
261+ // This is the timestamp that will be used to calculate current_epoch_number
262+ TIMESTAMP ,
274263 & MockAuthoritySelectionDataSource :: default ( )
275264 . with_permissioned_candidates ( vec ! [ None , None , None , None , None ] )
276265 . with_num_permissioned_candidates ( 0 ) ,
@@ -282,11 +271,8 @@ mod tests {
282271 assert ! ( ariadne_idp. unwrap( ) . data. is_some( ) ) ;
283272 }
284273
285- fn sc_slot_config ( ) -> ScSlotConfig {
286- ScSlotConfig {
287- slots_per_epoch : SlotsPerEpoch ( 10 ) ,
288- slot_duration : SlotDuration :: from_millis ( 1000 ) ,
289- }
274+ fn sc_epoch_duration_millis ( ) -> u64 {
275+ 60 * 60 * 1000
290276 }
291277
292278 fn client ( next_unset_epoch_number : ScEpochNumber ) -> TestApi {
@@ -297,11 +283,7 @@ mod tests {
297283 MainchainEpochConfig {
298284 first_epoch_timestamp_millis : Timestamp :: from_unix_millis ( 0 ) ,
299285 first_epoch_number : 0 ,
300- epoch_duration_millis : Duration :: from_millis (
301- u64:: from ( sc_slot_config ( ) . slots_per_epoch . 0 )
302- * sc_slot_config ( ) . slot_duration . as_millis ( )
303- * 10 ,
304- ) ,
286+ epoch_duration_millis : Duration :: from_millis ( 10 * sc_epoch_duration_millis ( ) ) ,
305287 first_slot_number : 0 ,
306288 slot_duration_millis : Duration :: from_millis ( 1000 ) ,
307289 }
0 commit comments