>,
proof: SubstrateFinalityProof,
+ context: <
::FinalityEngine as Engine>::FinalityVerificationContext,
) -> CallOf;
}
@@ -133,12 +134,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()),
@@ -172,6 +177,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/relays/lib-substrate-relay/src/finality/target.rs b/relays/lib-substrate-relay/src/finality/target.rs
index 38db0ee2fb..48c011f832 100644
--- a/relays/lib-substrate-relay/src/finality/target.rs
+++ b/relays/lib-substrate-relay/src/finality/target.rs
@@ -113,13 +113,15 @@ impl>
header: SyncHeader>,
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/relays/lib-substrate-relay/src/finality_base/engine.rs b/relays/lib-substrate-relay/src/finality_base/engine.rs
index b18cd0715a..f02a4f7096 100644
--- a/relays/lib-substrate-relay/src/finality_base/engine.rs
+++ b/relays/lib-substrate-relay/src/finality_base/engine.rs
@@ -118,12 +118,15 @@ pub trait Engine: Send {
source_client: &impl Client,
) -> Result, SubstrateError>;
- /// 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: &impl 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
@@ -217,11 +220,11 @@ impl Engine for Grandpa {
source_client.subscribe_grandpa_finality_justifications().await
}
- async fn optimize_proof(
+ async fn verify_and_optimize_proof(
target_client: &impl Client,
header: &C::Header,
proof: &mut Self::FinalityProof,
- ) -> Result<(), SubstrateError> {
+ ) -> Result {
let verification_context = Grandpa::::finality_verification_context(
target_client,
target_client.best_header_hash().await?,
@@ -236,6 +239,7 @@ impl Engine for Grandpa {
&verification_context,
proof,
)
+ .map(|_| verification_context)
.map_err(|e| {
SubstrateError::Custom(format!(
"Failed to optimize {} GRANDPA justification for header {:?}: {:?}",
diff --git a/relays/lib-substrate-relay/src/on_demand/headers.rs b/relays/lib-substrate-relay/src/on_demand/headers.rs
index fbab3c8a77..768ce4cb6e 100644
--- a/relays/lib-substrate-relay/src/on_demand/headers.rs
+++ b/relays/lib-substrate-relay/src/on_demand/headers.rs
@@ -155,8 +155,13 @@ impl<
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
@@ -194,8 +199,9 @@ impl<
);
// 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]));
}