1818
1919//! Utility for the upgrade from shell to a parachain runtime that implements Aura.
2020use astar_primitives:: * ;
21- use cumulus_primitives_core:: relay_chain:: PersistedValidationData ;
22- use cumulus_primitives_core:: RelayParentOffsetApi ;
21+ use cumulus_primitives_core:: relay_chain:: { self , PersistedValidationData } ;
22+ use cumulus_primitives_core:: { ParaId , RelayParentOffsetApi } ;
2323use cumulus_test_relay_sproof_builder:: RelayStateSproofBuilder ;
2424use fc_rpc:: pending:: ConsensusDataProvider ;
25- use sc_client_api:: { AuxStore , UsageProvider } ;
25+ use parity_scale_codec:: { Decode , Encode } ;
26+ use sc_client_api:: { AuxStore , Backend , StorageProvider , UsageProvider } ;
2627use sc_consensus:: { import_queue:: Verifier as VerifierT , BlockImportParams } ;
2728use sp_api:: { ApiExt , ProvideRuntimeApi } ;
29+ use sp_blockchain:: HeaderBackend ;
2830use sp_consensus_aura:: {
2931 digests:: CompatibleDigestItem ,
3032 sr25519:: { AuthorityId as AuraId , AuthoritySignature } ,
3133 AuraApi ,
3234} ;
35+ use sp_core:: { hashing:: twox_128, storage:: StorageKey } ;
3336use sp_inherents:: { CreateInherentDataProviders , Error , InherentData } ;
3437use sp_runtime:: {
3538 traits:: { Block as BlockT , Header as HeaderT } ,
@@ -122,33 +125,61 @@ where
122125 }
123126}
124127
128+ /// Relay chain slot duration, used to mock a relay slot matching the pending block's para slot.
129+ const RELAY_CHAIN_SLOT_DURATION_MILLIS : u64 = 6000 ;
130+
125131/// Shiden genesis did not start with AuraApi, therefore this implementation makes sure to return
126132/// inherent data after AuraApi becomes available.
127133/// This is currently required by EVM RPC.
128- pub struct PendingCrateInherentDataProvider < B , C > {
134+ pub struct PendingCrateInherentDataProvider < B , C , BE > {
129135 client : Arc < C > ,
130- phantom_data : PhantomData < B > ,
136+ para_id : ParaId ,
137+ phantom_data : PhantomData < fn ( ) -> ( B , BE ) > ,
131138}
132139
133- impl < B , C > PendingCrateInherentDataProvider < B , C >
134- where
135- B : BlockT ,
136- C : AuxStore + ProvideRuntimeApi < B > + UsageProvider < B > + Send + Sync ,
137- C :: Api : AuraApi < B , AuraId > ,
138- {
139- pub fn new ( client : Arc < C > ) -> Self {
140+ impl < B , C , BE > PendingCrateInherentDataProvider < B , C , BE > {
141+ pub fn new ( client : Arc < C > , para_id : ParaId ) -> Self {
140142 Self {
141143 client,
144+ para_id,
142145 phantom_data : Default :: default ( ) ,
143146 }
144147 }
145148}
146149
150+ impl < B , C , BE > PendingCrateInherentDataProvider < B , C , BE >
151+ where
152+ B : BlockT ,
153+ BE : Backend < B > ,
154+ C : StorageProvider < B , BE > ,
155+ {
156+ /// Reads `ParachainSystem::LastDmqMqcHead` at `parent`, so the mocked DMQ head matches it.
157+ fn last_dmq_mqc_head (
158+ & self ,
159+ parent : B :: Hash ,
160+ ) -> Result < relay_chain:: Hash , Box < dyn std:: error:: Error + Send + Sync > > {
161+ let key = [ twox_128 ( b"ParachainSystem" ) , twox_128 ( b"LastDmqMqcHead" ) ] . concat ( ) ;
162+ Ok ( self
163+ . client
164+ . storage ( parent, & StorageKey ( key) ) ?
165+ . map ( |data| relay_chain:: Hash :: decode ( & mut & data. 0 [ ..] ) )
166+ . transpose ( ) ?
167+ . unwrap_or_default ( ) )
168+ }
169+ }
170+
147171#[ async_trait:: async_trait]
148- impl < B , C > CreateInherentDataProviders < B , ( ) > for PendingCrateInherentDataProvider < B , C >
172+ impl < B , C , BE > CreateInherentDataProviders < B , ( ) > for PendingCrateInherentDataProvider < B , C , BE >
149173where
150174 B : BlockT ,
151- C : AuxStore + ProvideRuntimeApi < B > + UsageProvider < B > + Send + Sync ,
175+ BE : Backend < B > ,
176+ C : AuxStore
177+ + ProvideRuntimeApi < B >
178+ + UsageProvider < B >
179+ + HeaderBackend < B >
180+ + StorageProvider < B , BE >
181+ + Send
182+ + Sync ,
152183 C :: Api : AuraApi < B , AuraId > + RelayParentOffsetApi < B > ,
153184{
154185 type InherentDataProviders = (
@@ -181,9 +212,17 @@ where
181212 * timestamp,
182213 slot_duration,
183214 ) ;
184- // Create a dummy parachain inherent data provider which is required to pass
185- // the checks by the para chain system. We use dummy values because in the 'pending context'
186- // neither do we have access to the real values nor do we need them.
215+ // Mock relay state that passes the parachain-system and aura-ext checks on top of `parent`.
216+ let sproof_builder = RelayStateSproofBuilder {
217+ para_id : self . para_id ,
218+ current_slot : ( next_slot / RELAY_CHAIN_SLOT_DURATION_MILLIS ) . into ( ) ,
219+ included_para_head : self
220+ . client
221+ . header ( parent) ?
222+ . map ( |header| header. encode ( ) . into ( ) ) ,
223+ dmq_mqc_head : Some ( self . last_dmq_mqc_head ( parent) ?) ,
224+ ..Default :: default ( )
225+ } ;
187226 let ( relay_parent_storage_root, relay_chain_state, relay_parent_descendants) = if self
188227 . client
189228 . runtime_api ( )
@@ -195,9 +234,9 @@ where
195234 . runtime_api ( )
196235 . relay_parent_offset ( parent)
197236 . expect ( "API present, call should succeed; qed" ) ;
198- RelayStateSproofBuilder :: default ( ) . into_state_root_proof_and_descendants ( offset. into ( ) )
237+ sproof_builder . into_state_root_proof_and_descendants ( offset. into ( ) )
199238 } else {
200- let ( root, proof) = RelayStateSproofBuilder :: default ( ) . into_state_root_and_proof ( ) ;
239+ let ( root, proof) = sproof_builder . into_state_root_and_proof ( ) ;
201240 ( root, proof, Default :: default ( ) )
202241 } ;
203242 let vfp = PersistedValidationData {
0 commit comments