Add another condition to the reject-obsolete-parachain-heads extension (#1505)

* add another condition to the reject-obsolete-parachain-heads extension

* add tracing to obsolete-tx-extensions

* fix tests

* extension_rejects_header_from_new_relay_block_with_same_hash

* fmt

* fix benchmarks
This commit is contained in:
Svyatoslav Nikolsky
2022-07-14 15:18:15 +03:00
committed by Bastian Köcher
parent e9d7adf8fd
commit ea1f46ff45
13 changed files with 225 additions and 92 deletions
@@ -18,7 +18,7 @@
//! parachain finality proofs synchronization pipelines.
use async_trait::async_trait;
use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
use pallet_bridge_parachains::{
Call as BridgeParachainsCall, Config as BridgeParachainsConfig, RelayBlockHash,
RelayBlockHasher, RelayBlockNumber,
@@ -71,7 +71,7 @@ pub trait SubmitParachainHeadsCallBuilder<P: SubstrateParachainsPipeline>:
/// function of bridge parachains module at the target chain.
fn build_submit_parachain_heads_call(
at_relay_block: HeaderIdOf<P::SourceRelayChain>,
parachains: Vec<ParaId>,
parachains: Vec<(ParaId, ParaHash)>,
parachain_heads_proof: ParaHeadsProof,
) -> CallOf<P::TargetChain>;
}
@@ -97,7 +97,7 @@ where
{
fn build_submit_parachain_heads_call(
at_relay_block: HeaderIdOf<P::SourceRelayChain>,
parachains: Vec<ParaId>,
parachains: Vec<(ParaId, ParaHash)>,
parachain_heads_proof: ParaHeadsProof,
) -> CallOf<P::TargetChain> {
BridgeParachainsCall::<R, I>::submit_parachain_heads {
@@ -160,23 +160,46 @@ where
&self,
at_block: HeaderIdOf<P::SourceRelayChain>,
parachains: &[ParaId],
) -> Result<ParaHeadsProof, Self::Error> {
let storage_keys = parachains
.iter()
.map(|para_id| {
parachain_head_storage_key_at_source(
P::SourceRelayChain::PARAS_PALLET_NAME,
*para_id,
)
})
.collect();
) -> Result<(ParaHeadsProof, Vec<ParaHash>), Self::Error> {
if parachains.len() != 1 || parachains[0].0 != P::SOURCE_PARACHAIN_PARA_ID {
return Err(SubstrateError::Custom(format!(
"Trying to prove unexpected parachains {:?}. Expected {:?}",
parachains,
P::SOURCE_PARACHAIN_PARA_ID,
)))
}
let parachain = parachains[0];
let storage_key =
parachain_head_storage_key_at_source(P::SourceRelayChain::PARAS_PALLET_NAME, parachain);
let parachain_heads_proof = self
.client
.prove_storage(storage_keys, at_block.1)
.prove_storage(vec![storage_key.clone()], at_block.1)
.await?
.iter_nodes()
.collect();
Ok(ParaHeadsProof(parachain_heads_proof))
// why we're reading parachain head here once again (it has already been read at the
// `parachain_head`)? that's because `parachain_head` sometimes returns obsolete parachain
// head and loop sometimes asks to prove this obsolete head and gets other (actual) head
// instead
//
// => since we want to provide proper hashes in our `submit_parachain_heads` call, we're
// rereading actual value here
let parachain_head = self
.client
.raw_storage_value(storage_key, Some(at_block.1))
.await?
.map(|h| ParaHead::decode(&mut &h.0[..]))
.transpose()?
.ok_or_else(|| {
SubstrateError::Custom(format!(
"Failed to read expected parachain {:?} head at {:?}",
parachain, at_block
))
})?;
let parachain_head_hash = parachain_head.hash();
Ok((ParaHeadsProof(parachain_heads_proof), vec![parachain_head_hash]))
}
}
@@ -28,7 +28,7 @@ use bp_parachains::{
best_parachain_head_hash_storage_key_at_target, imported_parachain_head_storage_key_at_target,
BestParaHeadHash,
};
use bp_polkadot_core::parachains::{ParaHead, ParaHeadsProof, ParaId};
use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId};
use codec::{Decode, Encode};
use parachains_relay::{
parachains_loop::TargetClient, parachains_loop_metrics::ParachainsLoopMetrics,
@@ -166,7 +166,7 @@ where
async fn submit_parachain_heads_proof(
&self,
at_relay_block: HeaderIdOf<P::SourceRelayChain>,
updated_parachains: Vec<ParaId>,
updated_parachains: Vec<(ParaId, ParaHash)>,
proof: ParaHeadsProof,
) -> Result<(), Self::Error> {
let genesis_hash = *self.client.genesis_hash();