diff --git a/bridges/relays/lib-substrate-relay/src/finality/mod.rs b/bridges/relays/lib-substrate-relay/src/finality/mod.rs index b8cf27ea78fd..ea7c4e0362b8 100644 --- a/bridges/relays/lib-substrate-relay/src/finality/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/finality/mod.rs @@ -24,7 +24,7 @@ use crate::{ }; use async_trait::async_trait; -use bp_header_chain::justification::GrandpaJustification; +use bp_header_chain::justification::{GrandpaJustification, JustificationVerificationContext}; use finality_relay::{FinalityPipeline, FinalitySyncPipeline}; use pallet_bridge_grandpa::{Call as BridgeGrandpaCall, Config as BridgeGrandpaConfig}; use relay_substrate_client::{ @@ -110,11 +110,12 @@ impl FinalitySyncPipeline for FinalitySyncPipe /// Different ways of building `submit_finality_proof` calls. pub trait SubmitFinalityProofCallBuilder { - /// Given source chain header and its finality proofs, build call of `submit_finality_proof` - /// function of bridge GRANDPA module at the target chain. + /// Given source chain header, its finality proof and the current authority set id, build call + /// of `submit_finality_proof` function of bridge GRANDPA module at the target chain. fn build_submit_finality_proof_call( header: SyncHeader>, proof: SubstrateFinalityProof

, + context: <

::FinalityEngine as Engine>::FinalityVerificationContext, ) -> CallOf; } @@ -132,12 +133,16 @@ where I: 'static, R::BridgedChain: bp_runtime::Chain

>, CallOf: From>, - P::FinalityEngine: - Engine>>, + P::FinalityEngine: Engine< + P::SourceChain, + FinalityProof = GrandpaJustification>, + FinalityVerificationContext = JustificationVerificationContext, + >, { fn build_submit_finality_proof_call( header: SyncHeader>, proof: GrandpaJustification>, + _context: JustificationVerificationContext, ) -> CallOf { BridgeGrandpaCall::::submit_finality_proof { finality_target: Box::new(header.into_inner()), @@ -171,6 +176,7 @@ macro_rules! generate_submit_finality_proof_call_builder { <$pipeline as $crate::finality_base::SubstrateFinalityPipeline>::SourceChain > >, + _context: bp_header_chain::justification::JustificationVerificationContext, ) -> relay_substrate_client::CallOf< <$pipeline as $crate::finality_base::SubstrateFinalityPipeline>::TargetChain > { diff --git a/bridges/relays/lib-substrate-relay/src/finality/target.rs b/bridges/relays/lib-substrate-relay/src/finality/target.rs index 930f0360311c..18464d523f4f 100644 --- a/bridges/relays/lib-substrate-relay/src/finality/target.rs +++ b/bridges/relays/lib-substrate-relay/src/finality/target.rs @@ -108,13 +108,15 @@ impl TargetClient>, mut proof: SubstrateFinalityProof

, ) -> Result { - // runtime module at target chain may require optimized finality proof - P::FinalityEngine::optimize_proof(&self.client, &header, &mut proof).await?; + // verify and runtime module at target chain may require optimized finality proof + let context = + P::FinalityEngine::verify_and_optimize_proof(&self.client, &header, &mut proof).await?; // now we may submit optimized finality proof let mortality = self.transaction_params.mortality; - let call = - P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call(header, proof); + let call = P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call( + header, proof, context, + ); self.client .submit_and_watch_signed_extrinsic( &self.transaction_params.signer, diff --git a/bridges/relays/lib-substrate-relay/src/finality_base/engine.rs b/bridges/relays/lib-substrate-relay/src/finality_base/engine.rs index 831c1e7ad5b5..e517b0fd9b9a 100644 --- a/bridges/relays/lib-substrate-relay/src/finality_base/engine.rs +++ b/bridges/relays/lib-substrate-relay/src/finality_base/engine.rs @@ -118,12 +118,15 @@ pub trait Engine: Send { source_client.subscribe_finality_justifications::().await } - /// Optimize finality proof before sending it to the target node. - async fn optimize_proof( + /// Verify and optimize finality proof before sending it to the target node. + /// + /// Apart from optimization, we expect this method to perform all required checks + /// that the `header` and `proof` are valid at the current state of the target chain. + async fn verify_and_optimize_proof( target_client: &Client, header: &C::Header, proof: &mut Self::FinalityProof, - ) -> Result<(), SubstrateError>; + ) -> Result; /// Checks whether the given `header` and its finality `proof` fit the maximal expected /// call size limit. If result is `MaxExpectedCallSizeCheck::Exceeds { .. }`, this @@ -212,11 +215,11 @@ impl Engine for Grandpa { bp_header_chain::storage_keys::pallet_operating_mode_key(C::WITH_CHAIN_GRANDPA_PALLET_NAME) } - async fn optimize_proof( + async fn verify_and_optimize_proof( target_client: &Client, header: &C::Header, proof: &mut Self::FinalityProof, - ) -> Result<(), SubstrateError> { + ) -> Result { let verification_context = Grandpa::::finality_verification_context( target_client, target_client.best_header().await?.hash(), @@ -231,6 +234,7 @@ impl Engine for Grandpa { &verification_context, proof, ) + .map(|_| verification_context) .map_err(|e| { SubstrateError::Custom(format!( "Failed to optimize {} GRANDPA jutification for header {:?}: {:?}", diff --git a/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs b/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs index 0090dee3a03c..8b58552d292c 100644 --- a/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs +++ b/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs @@ -146,8 +146,13 @@ impl OnDemandRelay OnDemandRelay