Skip to content

Commit

Permalink
Pass finality proof verification context to the call builder (parityt…
Browse files Browse the repository at this point in the history
…ech#2823)

* pass verification context to the build_submit_finality_proof_call

* current_set_id -> context
  • Loading branch information
svyatonik authored Feb 6, 2024
1 parent 5ceb05f commit e17af18
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 18 deletions.
16 changes: 11 additions & 5 deletions bridges/relays/lib-substrate-relay/src/finality/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -110,11 +110,12 @@ impl<P: SubstrateFinalitySyncPipeline> FinalitySyncPipeline for FinalitySyncPipe

/// Different ways of building `submit_finality_proof` calls.
pub trait SubmitFinalityProofCallBuilder<P: SubstrateFinalitySyncPipeline> {
/// 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<HeaderOf<P::SourceChain>>,
proof: SubstrateFinalityProof<P>,
context: <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<P::SourceChain>>::FinalityVerificationContext,
) -> CallOf<P::TargetChain>;
}

Expand All @@ -132,12 +133,16 @@ where
I: 'static,
R::BridgedChain: bp_runtime::Chain<Header = HeaderOf<P::SourceChain>>,
CallOf<P::TargetChain>: From<BridgeGrandpaCall<R, I>>,
P::FinalityEngine:
Engine<P::SourceChain, FinalityProof = GrandpaJustification<HeaderOf<P::SourceChain>>>,
P::FinalityEngine: Engine<
P::SourceChain,
FinalityProof = GrandpaJustification<HeaderOf<P::SourceChain>>,
FinalityVerificationContext = JustificationVerificationContext,
>,
{
fn build_submit_finality_proof_call(
header: SyncHeader<HeaderOf<P::SourceChain>>,
proof: GrandpaJustification<HeaderOf<P::SourceChain>>,
_context: JustificationVerificationContext,
) -> CallOf<P::TargetChain> {
BridgeGrandpaCall::<R, I>::submit_finality_proof {
finality_target: Box::new(header.into_inner()),
Expand Down Expand Up @@ -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
> {
Expand Down
10 changes: 6 additions & 4 deletions bridges/relays/lib-substrate-relay/src/finality/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,15 @@ impl<P: SubstrateFinalitySyncPipeline> TargetClient<FinalitySyncPipelineAdapter<
header: SyncHeader<HeaderOf<P::SourceChain>>,
mut proof: SubstrateFinalityProof<P>,
) -> Result<Self::TransactionTracker, Error> {
// 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,
Expand Down
14 changes: 9 additions & 5 deletions bridges/relays/lib-substrate-relay/src/finality_base/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,15 @@ pub trait Engine<C: Chain>: Send {
source_client.subscribe_finality_justifications::<Self::FinalityClient>().await
}

/// Optimize finality proof before sending it to the target node.
async fn optimize_proof<TargetChain: Chain>(
/// 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<TargetChain: Chain>(
target_client: &Client<TargetChain>,
header: &C::Header,
proof: &mut Self::FinalityProof,
) -> Result<(), SubstrateError>;
) -> Result<Self::FinalityVerificationContext, SubstrateError>;

/// Checks whether the given `header` and its finality `proof` fit the maximal expected
/// call size limit. If result is `MaxExpectedCallSizeCheck::Exceeds { .. }`, this
Expand Down Expand Up @@ -212,11 +215,11 @@ impl<C: ChainWithGrandpa> Engine<C> for Grandpa<C> {
bp_header_chain::storage_keys::pallet_operating_mode_key(C::WITH_CHAIN_GRANDPA_PALLET_NAME)
}

async fn optimize_proof<TargetChain: Chain>(
async fn verify_and_optimize_proof<TargetChain: Chain>(
target_client: &Client<TargetChain>,
header: &C::Header,
proof: &mut Self::FinalityProof,
) -> Result<(), SubstrateError> {
) -> Result<Self::FinalityVerificationContext, SubstrateError> {
let verification_context = Grandpa::<C>::finality_verification_context(
target_client,
target_client.best_header().await?.hash(),
Expand All @@ -231,6 +234,7 @@ impl<C: ChainWithGrandpa> Engine<C> for Grandpa<C> {
&verification_context,
proof,
)
.map(|_| verification_context)
.map_err(|e| {
SubstrateError::Custom(format!(
"Failed to optimize {} GRANDPA jutification for header {:?}: {:?}",
Expand Down
14 changes: 10 additions & 4 deletions bridges/relays/lib-substrate-relay/src/on_demand/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,13 @@ impl<P: SubstrateFinalitySyncPipeline> OnDemandRelay<P::SourceChain, P::TargetCh
finality_source.prove_block_finality(current_required_header).await?;
let header_id = header.id();

// optimize justification before including it into the call
P::FinalityEngine::optimize_proof(&self.target_client, &header, &mut proof).await?;
// verify and optimize justification before including it into the call
let context = P::FinalityEngine::verify_and_optimize_proof(
&self.target_client,
&header,
&mut proof,
)
.await?;

// now we have the header and its proof, but we want to minimize our losses, so let's
// check if we'll get the full refund for submitting this header
Expand Down Expand Up @@ -185,8 +190,9 @@ impl<P: SubstrateFinalitySyncPipeline> OnDemandRelay<P::SourceChain, P::TargetCh
);

// and then craft the submit-proof call
let call =
P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call(header, proof);
let call = P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call(
header, proof, context,
);

return Ok((header_id, vec![call]));
}
Expand Down

0 comments on commit e17af18

Please sign in to comment.