Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass finality proof verification context to the call builder #2823

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions 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
12 changes: 8 additions & 4 deletions relays/lib-substrate-relay/src/finality/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,17 @@ 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 current_set_id =
svyatonik marked this conversation as resolved.
Show resolved Hide resolved
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,
current_set_id,
);
self.client
.submit_and_watch_signed_extrinsic(
&self.transaction_params.signer,
Expand Down
14 changes: 9 additions & 5 deletions 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
16 changes: 12 additions & 4 deletions 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 current_set_id = P::FinalityEngine::verify_and_optimize_proof(
svyatonik marked this conversation as resolved.
Show resolved Hide resolved
&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,11 @@ 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,
current_set_id,
);

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