@@ -34,7 +34,7 @@ use cumulus_relay_chain_interface::RelayChainInterface;
3434
3535use polkadot_node_primitives:: { CollationResult , MaybeCompressedPoV } ;
3636use polkadot_overseer:: Handle as OverseerHandle ;
37- use polkadot_primitives:: { CollatorPair , Id as ParaId } ;
37+ use polkadot_primitives:: { Block as PBlock , CollatorPair , Header as PHeader , Id as ParaId } ;
3838
3939use futures:: prelude:: * ;
4040use sc_client_api:: { backend:: AuxStore , BlockBackend , BlockOf } ;
@@ -58,6 +58,7 @@ use sp_runtime::{
5858 traits:: { Block as BlockT , HashFor , Header as HeaderT , Member } ,
5959} ;
6060use sp_state_machine:: StorageChanges ;
61+ use sp_timestamp:: Timestamp ;
6162use std:: { convert:: TryFrom , error:: Error , fmt:: Debug , hash:: Hash , sync:: Arc , time:: Duration } ;
6263
6364/// Parameters for [`run_bare_relay_driven`].
@@ -72,10 +73,57 @@ pub struct Params<BI, CIDP, Client, RClient, SO, Proposer, CS> {
7273 pub para_id : ParaId ,
7374 pub overseer_handle : OverseerHandle ,
7475 pub slot_duration : SlotDuration ,
76+ pub relay_chain_slot_duration : SlotDuration ,
7577 pub proposer : Proposer ,
7678 pub collator_service : CS ,
7779}
7880
81+ /// Run async-backing-friendly Aura.
82+ pub async fn run_async_backing_driven < Block , P , BI , CIDP , Client , RClient , SO , Proposer , CS > (
83+ params : Params < BI , CIDP , Client , RClient , SO , Proposer , CS > ,
84+ ) where
85+ Block : BlockT ,
86+ Client : ProvideRuntimeApi < Block >
87+ + BlockOf
88+ + AuxStore
89+ + HeaderBackend < Block >
90+ + BlockBackend < Block >
91+ + Send
92+ + Sync
93+ + ' static ,
94+ Client :: Api : AuraApi < Block , P :: Public > + CollectCollationInfo < Block > ,
95+ RClient : RelayChainInterface ,
96+ CIDP : CreateInherentDataProviders < Block , ( ) > + ' static ,
97+ BI : BlockImport < Block > + ParachainBlockImportMarker + Send + Sync + ' static ,
98+ SO : SyncOracle + Send + Sync + Clone + ' static ,
99+ Proposer : ProposerInterface < Block , Transaction = BI :: Transaction > ,
100+ Proposer :: Transaction : Sync ,
101+ CS : CollatorServiceInterface < Block > ,
102+ P : Pair + Send + Sync ,
103+ P :: Public : AppPublic + Hash + Member + Encode + Decode ,
104+ P :: Signature : TryFrom < Vec < u8 > > + Hash + Member + Encode + Decode ,
105+ {
106+ let mut proposer = params. proposer ;
107+ let mut block_import = params. block_import ;
108+
109+ let mut import_notifications = match params. relay_client . import_notification_stream ( ) . await {
110+ Ok ( s) => s,
111+ Err ( err) => {
112+ tracing:: error!(
113+ target: crate :: LOG_TARGET ,
114+ ?err,
115+ "Failed to initialize consensus: no relay chain import notification stream"
116+ ) ;
117+
118+ return
119+ } ,
120+ } ;
121+
122+ while let Some ( relay_parent_header) = import_notifications. next ( ) . await {
123+ let relay_parent = relay_parent_header. hash ( ) ;
124+ }
125+ }
126+
79127/// Run bare Aura consensus as a relay-chain-driven collator.
80128pub async fn run_bare_relay_driven < Block , P , BI , CIDP , Client , RClient , SO , Proposer , CS > (
81129 params : Params < BI , CIDP , Client , RClient , SO , Proposer , CS > ,
@@ -120,23 +168,38 @@ pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Prop
120168 } } ;
121169 }
122170
171+ macro_rules! try_request {
172+ ( $x: expr) => { {
173+ match $x {
174+ Ok ( x) => x,
175+ Err ( e) => reject_with_error!( e) ,
176+ }
177+ } } ;
178+ }
179+
123180 let validation_data = request. persisted_validation_data ( ) ;
124181
125- let parent_header = match Block :: Header :: decode ( & mut & validation_data. parent_head . 0 [ ..] ) {
126- Ok ( x) => x,
127- Err ( e) => reject_with_error ! ( e) ,
128- } ;
182+ let parent_header =
183+ try_request ! ( Block :: Header :: decode( & mut & validation_data. parent_head. 0 [ ..] ) ) ;
129184
130185 let parent_hash = parent_header. hash ( ) ;
131186
132187 if !params. collator_service . check_block_status ( parent_hash, & parent_header) {
133188 continue
134189 }
135190
191+ let relay_parent_header = match params. relay_client . header ( * request. relay_parent ( ) ) . await {
192+ Err ( e) => reject_with_error ! ( e) ,
193+ Ok ( None ) => continue , // sanity: would be inconsistent to get `None` here
194+ Ok ( Some ( h) ) => h,
195+ } ;
196+
136197 let claim = match claim_slot :: < _ , _ , P > (
137198 & * params. para_client ,
138199 parent_hash,
200+ & relay_parent_header,
139201 params. slot_duration ,
202+ params. relay_chain_slot_duration ,
140203 & params. keystore ,
141204 )
142205 . await
@@ -146,51 +209,45 @@ pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Prop
146209 Err ( e) => reject_with_error ! ( e) ,
147210 } ;
148211
149- let ( parachain_inherent_data, other_inherent_data) = match create_inherent_data (
150- * request. relay_parent ( ) ,
151- & validation_data,
152- parent_hash,
153- params. para_id ,
154- & params. relay_client ,
155- & params. create_inherent_data_providers ,
156- )
157- . await
158- {
159- Ok ( x) => x,
160- Err ( e) => reject_with_error ! ( e) ,
161- } ;
162-
163- let proposal = match proposer
164- . propose (
165- & parent_header,
166- & parachain_inherent_data,
167- other_inherent_data,
168- Digest { logs : vec ! [ claim. pre_digest] } ,
169- // TODO [https://github.com/paritytech/cumulus/issues/2439]
170- // We should call out to a pluggable interface that provides
171- // the proposal duration.
172- Duration :: from_millis ( 500 ) ,
173- // Set the block limit to 50% of the maximum PoV size.
174- //
175- // TODO: If we got benchmarking that includes the proof size,
176- // we should be able to use the maximum pov size.
177- Some ( ( validation_data. max_pov_size / 2 ) as usize ) ,
212+ let ( parachain_inherent_data, other_inherent_data) = try_request ! (
213+ create_inherent_data(
214+ * request. relay_parent( ) ,
215+ & validation_data,
216+ parent_hash,
217+ params. para_id,
218+ claim. timestamp,
219+ & params. relay_client,
220+ & params. create_inherent_data_providers,
178221 )
179222 . await
180- {
181- Ok ( p) => p,
182- Err ( e) => reject_with_error ! ( e) ,
183- } ;
223+ ) ;
224+
225+ let proposal = try_request ! (
226+ proposer
227+ . propose(
228+ & parent_header,
229+ & parachain_inherent_data,
230+ other_inherent_data,
231+ Digest { logs: vec![ claim. pre_digest] } ,
232+ // TODO [https://github.com/paritytech/cumulus/issues/2439]
233+ // We should call out to a pluggable interface that provides
234+ // the proposal duration.
235+ Duration :: from_millis( 500 ) ,
236+ // Set the block limit to 50% of the maximum PoV size.
237+ //
238+ // TODO: If we got benchmarking that includes the proof size,
239+ // we should be able to use the maximum pov size.
240+ Some ( ( validation_data. max_pov_size / 2 ) as usize ) ,
241+ )
242+ . await
243+ ) ;
184244
185- let sealed_importable = match seal :: < _ , _ , P > (
245+ let sealed_importable = try_request ! ( seal:: <_, _, P >(
186246 proposal. block,
187247 proposal. storage_changes,
188248 & claim. author_pub,
189249 & params. keystore,
190- ) {
191- Ok ( s) => s,
192- Err ( e) => reject_with_error ! ( e) ,
193- } ;
250+ ) ) ;
194251
195252 let post_hash = sealed_importable. post_hash ( ) ;
196253 let block = Block :: new (
@@ -202,9 +259,7 @@ pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Prop
202259 . clone ( ) ,
203260 ) ;
204261
205- if let Err ( e) = block_import. import_block ( sealed_importable) . await {
206- reject_with_error ! ( e) ;
207- }
262+ try_request ! ( block_import. import_block( sealed_importable) . await ) ;
208263
209264 let response = if let Some ( ( collation, b) ) = params. collator_service . build_collation (
210265 & parent_header,
@@ -246,12 +301,15 @@ fn slot_now(slot_duration: SlotDuration) -> Slot {
246301struct SlotClaim < Pub > {
247302 author_pub : Pub ,
248303 pre_digest : sp_runtime:: DigestItem ,
304+ timestamp : Timestamp ,
249305}
250306
251307async fn claim_slot < B , C , P > (
252308 client : & C ,
253309 parent_hash : B :: Hash ,
310+ relay_parent_header : & PHeader ,
254311 slot_duration : SlotDuration ,
312+ relay_chain_slot_duration : SlotDuration ,
255313 keystore : & KeystorePtr ,
256314) -> Result < Option < SlotClaim < P :: Public > > , Box < dyn Error > >
257315where
@@ -265,8 +323,18 @@ where
265323 // load authorities
266324 let authorities = client. runtime_api ( ) . authorities ( parent_hash) . map_err ( Box :: new) ?;
267325
268- // Determine the current slot.
269- let slot_now = slot_now ( slot_duration) ;
326+ // Determine the current slot and timestamp based on the relay-parent's.
327+ let ( slot_now, timestamp) =
328+ match sc_consensus_babe:: find_pre_digest :: < PBlock > ( relay_parent_header) {
329+ Ok ( babe_pre_digest) => {
330+ let t =
331+ Timestamp :: new ( relay_chain_slot_duration. as_millis ( ) * * babe_pre_digest. slot ( ) ) ;
332+ let slot = Slot :: from_timestamp ( t, slot_duration) ;
333+
334+ ( slot, t)
335+ } ,
336+ Err ( _) => return Ok ( None ) ,
337+ } ;
270338
271339 // Try to claim the slot locally.
272340 let author_pub = {
@@ -280,14 +348,17 @@ where
280348 // Produce the pre-digest.
281349 let pre_digest = aura_internal:: pre_digest :: < P > ( slot_now) ;
282350
283- Ok ( Some ( SlotClaim { author_pub, pre_digest } ) )
351+ Ok ( Some ( SlotClaim { author_pub, pre_digest, timestamp } ) )
284352}
285353
354+ // This explicitly creates the inherent data for parachains, as well as overriding the
355+ // timestamp based on the slot number.
286356async fn create_inherent_data < B : BlockT > (
287357 relay_parent : PHash ,
288358 validation_data : & PersistedValidationData ,
289359 parent_hash : B :: Hash ,
290360 para_id : ParaId ,
361+ timestamp : Timestamp ,
291362 relay_chain_interface : & impl RelayChainInterface ,
292363 create_inherent_data_providers : & impl CreateInherentDataProviders < B , ( ) > ,
293364) -> Result < ( ParachainInherentData , InherentData ) , Box < dyn Error > > {
@@ -305,14 +376,16 @@ async fn create_inherent_data<B: BlockT>(
305376 return Err ( format ! ( "Could not create paras inherent data at {:?}" , relay_parent) . into ( ) ) ,
306377 } ;
307378
308- let other_inherent_data = create_inherent_data_providers
379+ let mut other_inherent_data = create_inherent_data_providers
309380 . create_inherent_data_providers ( parent_hash, ( ) )
310381 . map_err ( |e| e as Box < dyn Error > )
311382 . await ?
312383 . create_inherent_data ( )
313384 . await
314385 . map_err ( Box :: new) ?;
315386
387+ other_inherent_data. replace_data ( sp_timestamp:: INHERENT_IDENTIFIER , & timestamp) ;
388+
316389 Ok ( ( paras_inherent_data, other_inherent_data) )
317390}
318391
0 commit comments