Skip to content

Commit 9250f40

Browse files
authored
fix: slot moved backwards (#1711)
1 parent 5d09bd9 commit 9250f40

3 files changed

Lines changed: 68 additions & 21 deletions

File tree

‎bin/collator/src/parachain/service.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ where
473473
subscription,
474474
pubsub_notification_sinks.clone(),
475475
rpc_config.clone(),
476+
para_id,
476477
)
477478
.map_err(Into::into)
478479
})

‎bin/collator/src/parachain/shell_upgrade.rs‎

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,21 @@
1818

1919
//! Utility for the upgrade from shell to a parachain runtime that implements Aura.
2020
use 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};
2323
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
2424
use 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};
2627
use sc_consensus::{import_queue::Verifier as VerifierT, BlockImportParams};
2728
use sp_api::{ApiExt, ProvideRuntimeApi};
29+
use sp_blockchain::HeaderBackend;
2830
use sp_consensus_aura::{
2931
digests::CompatibleDigestItem,
3032
sr25519::{AuthorityId as AuraId, AuthoritySignature},
3133
AuraApi,
3234
};
35+
use sp_core::{hashing::twox_128, storage::StorageKey};
3336
use sp_inherents::{CreateInherentDataProviders, Error, InherentData};
3437
use 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>
149173
where
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 {

‎bin/collator/src/rpc.rs‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ pub fn create_full<C, P, BE>(
197197
>,
198198
>,
199199
tracing_config: EvmTracingConfig,
200+
para_id: ParaId,
200201
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
201202
where
202203
C: ProvideRuntimeApi<Block>
@@ -228,7 +229,12 @@ where
228229
let client = Arc::clone(&deps.client);
229230
let graph = Arc::clone(&deps.graph);
230231

231-
let mut io = create_full_rpc(deps, subscription_task_executor, pubsub_notification_sinks)?;
232+
let mut io = create_full_rpc(
233+
deps,
234+
subscription_task_executor,
235+
pubsub_notification_sinks,
236+
para_id,
237+
)?;
232238

233239
if tracing_config.enable_txpool {
234240
io.merge(TxPool::new(Arc::clone(&client), graph).into_rpc())?;
@@ -379,6 +385,7 @@ fn create_full_rpc<C, P, BE>(
379385
fc_mapping_sync::EthereumBlockNotification<Block>,
380386
>,
381387
>,
388+
para_id: ParaId,
382389
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
383390
where
384391
C: ProvideRuntimeApi<Block>
@@ -409,7 +416,7 @@ where
409416
deps,
410417
subscription_task_executor,
411418
pubsub_notification_sinks,
412-
crate::parachain::PendingCrateInherentDataProvider::new,
419+
|client| crate::parachain::PendingCrateInherentDataProvider::new(client, para_id),
413420
)
414421
}
415422

0 commit comments

Comments
 (0)