diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 4f3afcbbf7..acf9b7e736 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -36,6 +36,7 @@ // Runtime-generated enums #![allow(clippy::large_enum_variant)] +use bp_header_chain::justification::GrandpaJustification; use bp_runtime::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf}; use codec::{Decode, Encode}; use finality_grandpa::voter_set::VoterSet; @@ -46,7 +47,6 @@ use serde::{Deserialize, Serialize}; use sp_finality_grandpa::{ConsensusLog, GRANDPA_ENGINE_ID}; use sp_runtime::traits::{BadOrigin, Header as HeaderT, Zero}; use sp_runtime::RuntimeDebug; -use sp_std::vec::Vec; #[cfg(test)] mod mock; @@ -111,7 +111,7 @@ pub mod pallet { pub fn submit_finality_proof( origin: OriginFor, finality_target: BridgedHeader, - justification: Vec, + justification: GrandpaJustification>, ) -> DispatchResultWithPostInfo { ensure_operational::()?; let _ = ensure_signed(origin)?; @@ -359,7 +359,7 @@ pub mod pallet { /// /// Will use the GRANDPA current authorities known to the pallet. pub(crate) fn verify_justification, I: 'static>( - justification: &[u8], + justification: &GrandpaJustification>, hash: BridgedBlockHash, number: BridgedBlockNumber, ) -> Result<(), sp_runtime::DispatchError> { @@ -515,7 +515,7 @@ pub(crate) fn find_forced_change( pub fn initialize_for_benchmarks, I: 'static>(header: BridgedHeader) { initialize_bridge::(InitializationData { header, - authority_list: Vec::new(), // we don't verify any proofs in external benchmarks + authority_list: sp_std::vec::Vec::new(), // we don't verify any proofs in external benchmarks set_id: 0, is_halted: false, }); @@ -555,7 +555,7 @@ mod tests { fn submit_finality_proof(header: u8) -> frame_support::dispatch::DispatchResultWithPostInfo { let header = test_header(header.into()); - let justification = make_default_justification(&header).encode(); + let justification = make_default_justification(&header); Module::::submit_finality_proof(Origin::signed(1), header, justification) } @@ -701,10 +701,7 @@ mod tests { run_test(|| { >::put(true); - assert_noop!( - Module::::submit_finality_proof(Origin::signed(1), test_header(1), vec![]), - Error::::Halted, - ); + assert_noop!(submit_finality_proof(1), Error::::Halted,); }) } @@ -731,7 +728,7 @@ mod tests { set_id: 2, ..Default::default() }; - let justification = make_justification_for_header(params).encode(); + let justification = make_justification_for_header(params); assert_err!( Module::::submit_finality_proof(Origin::signed(1), header, justification,), @@ -746,7 +743,8 @@ mod tests { initialize_substrate_bridge(); let header = test_header(1); - let justification = [1u8; 32].encode(); + let mut justification = make_default_justification(&header); + justification.round = 42; assert_err!( Module::::submit_finality_proof(Origin::signed(1), header, justification,), @@ -771,7 +769,7 @@ mod tests { assert_ok!(Module::::initialize(Origin::root(), init_data)); let header = test_header(1); - let justification = [1u8; 32].encode(); + let justification = make_default_justification(&header); assert_err!( Module::::submit_finality_proof(Origin::signed(1), header, justification,), @@ -805,7 +803,7 @@ mod tests { header.digest = change_log(0); // Create a valid justification for the header - let justification = make_default_justification(&header).encode(); + let justification = make_default_justification(&header); // Let's import our test header assert_ok!(Module::::submit_finality_proof( @@ -837,7 +835,7 @@ mod tests { header.digest = change_log(1); // Create a valid justification for the header - let justification = make_default_justification(&header).encode(); + let justification = make_default_justification(&header); // Should not be allowed to import this header assert_err!( @@ -858,7 +856,7 @@ mod tests { header.digest = forced_change_log(0); // Create a valid justification for the header - let justification = make_default_justification(&header).encode(); + let justification = make_default_justification(&header); // Should not be allowed to import this header assert_err!( @@ -917,7 +915,8 @@ mod tests { run_test(|| { let submit_invalid_request = || { let header = test_header(1); - let invalid_justification = vec![4, 2, 4, 2].encode(); + let mut invalid_justification = make_default_justification(&header); + invalid_justification.round = 42; Module::::submit_finality_proof(Origin::signed(1), header, invalid_justification) }; diff --git a/bridges/modules/substrate/src/verifier.rs b/bridges/modules/substrate/src/verifier.rs index f2e33e21e4..891864554b 100644 --- a/bridges/modules/substrate/src/verifier.rs +++ b/bridges/modules/substrate/src/verifier.rs @@ -215,6 +215,8 @@ where /// proof. If the header enacts an authority set change the change will be applied once the /// header has been finalized. pub fn import_finality_proof(&mut self, hash: H::Hash, proof: FinalityProof) -> Result<(), FinalizationError> { + use codec::Decode; + // Make sure that we've previously imported this header let header = self .storage @@ -233,11 +235,15 @@ where "We verified the correctness of the authority list during header import, before writing them to storage. This must always be valid.", ); + + let justification = bp_header_chain::justification::GrandpaJustification::::decode(&mut proof.0.as_slice()) + .map_err(|_| FinalizationError::InvalidJustification)?; + verify_justification::( (hash, *header.number()), current_authority_set.set_id, &voter_set, - &proof.0, + &justification, ) .map_err(|_| FinalizationError::InvalidJustification)?; log::trace!("Received valid justification for {:?}", header); diff --git a/bridges/primitives/header-chain/src/justification.rs b/bridges/primitives/header-chain/src/justification.rs index 67968258a5..1db15440fb 100644 --- a/bridges/primitives/header-chain/src/justification.rs +++ b/bridges/primitives/header-chain/src/justification.rs @@ -25,7 +25,7 @@ use frame_support::RuntimeDebug; use sp_finality_grandpa::{AuthorityId, AuthoritySignature, SetId}; use sp_runtime::traits::Header as HeaderT; use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; -use sp_std::prelude::Vec; +use sp_std::prelude::*; /// Justification verification error. #[derive(RuntimeDebug, PartialEq)] @@ -58,15 +58,11 @@ pub fn verify_justification( finalized_target: (Header::Hash, Header::Number), authorities_set_id: SetId, authorities_set: &VoterSet, - raw_justification: &[u8], + justification: &GrandpaJustification
, ) -> Result<(), Error> where Header::Number: finality_grandpa::BlockNumberOps, { - // Decode justification first - let justification = - GrandpaJustification::
::decode(&mut &*raw_justification).map_err(|_| Error::JustificationDecode)?; - // Ensure that it is justification for the expected header if (justification.commit.target_hash, justification.commit.target_number) != finalized_target { return Err(Error::InvalidJustificationTarget); @@ -130,7 +126,7 @@ where /// /// This particular proof is used to prove that headers on a bridged chain /// (so not our chain) have been finalized correctly. -#[derive(Encode, Decode, RuntimeDebug)] +#[derive(Encode, Decode, RuntimeDebug, Clone, PartialEq, Eq)] pub struct GrandpaJustification { /// The round (voting period) this justification is valid for. pub round: u64, @@ -140,6 +136,12 @@ pub struct GrandpaJustification { pub votes_ancestries: Vec
, } +impl crate::FinalityProof for GrandpaJustification { + fn target_header_number(&self) -> H::Number { + self.commit.target_number + } +} + /// A utility trait implementing `finality_grandpa::Chain` using a given set of headers. #[derive(RuntimeDebug)] struct AncestryChain { diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index e9f6cee9c9..ba47d614fa 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -94,6 +94,12 @@ impl HeaderChain for () { } } +/// Abstract finality proof that is justifying block finality. +pub trait FinalityProof: Clone + Send + Sync + Debug { + /// Return number of header that this proof is generated for. + fn target_header_number(&self) -> Number; +} + /// Find header digest that schedules next GRANDPA authorities set. pub fn find_grandpa_authorities_scheduled_change( header: &H, diff --git a/bridges/primitives/header-chain/tests/justification.rs b/bridges/primitives/header-chain/tests/justification.rs index 33808461f6..96bb6d442a 100644 --- a/bridges/primitives/header-chain/tests/justification.rs +++ b/bridges/primitives/header-chain/tests/justification.rs @@ -18,7 +18,6 @@ use bp_header_chain::justification::{verify_justification, Error}; use bp_test_utils::*; -use codec::Encode; type TestHeader = sp_runtime::testing::Header; @@ -38,7 +37,7 @@ fn valid_justification_accepted() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), - &make_justification_for_header::(params).encode() + &make_justification_for_header::(params) ), Ok(()), ); @@ -60,7 +59,7 @@ fn valid_justification_accepted_with_single_fork() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), - &make_justification_for_header::(params).encode() + &make_justification_for_header::(params) ), Ok(()), ); @@ -94,20 +93,12 @@ fn valid_justification_accepted_with_arbitrary_number_of_authorities() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set, - &make_justification_for_header::(params).encode() + &make_justification_for_header::(params) ), Ok(()), ); } -#[test] -fn justification_with_invalid_encoding_rejected() { - assert_eq!( - verify_justification::(header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), &[],), - Err(Error::JustificationDecode), - ); -} - #[test] fn justification_with_invalid_target_rejected() { assert_eq!( @@ -115,7 +106,7 @@ fn justification_with_invalid_target_rejected() { header_id::(2), TEST_GRANDPA_SET_ID, &voter_set(), - &make_default_justification::(&test_header(1)).encode(), + &make_default_justification::(&test_header(1)), ), Err(Error::InvalidJustificationTarget), ); @@ -131,7 +122,7 @@ fn justification_with_invalid_commit_rejected() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), - &justification.encode(), + &justification, ), Err(Error::InvalidJustificationCommit), ); @@ -147,7 +138,7 @@ fn justification_with_invalid_authority_signature_rejected() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), - &justification.encode(), + &justification, ), Err(Error::InvalidAuthoritySignature), ); @@ -163,7 +154,7 @@ fn justification_with_invalid_precommit_ancestry() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), - &justification.encode(), + &justification, ), Err(Error::InvalidPrecommitAncestries), ); @@ -186,7 +177,7 @@ fn justification_is_invalid_if_we_dont_meet_threshold() { header_id::(1), TEST_GRANDPA_SET_ID, &voter_set(), - &make_justification_for_header::(params).encode() + &make_justification_for_header::(params) ), Err(Error::InvalidJustificationCommit), ); diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 4c8c2047d2..2d81e5a4b6 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -17,7 +17,6 @@ //! Logic for checking Substrate storage proofs. use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; -use sp_core::H256; use sp_runtime::RuntimeDebug; use sp_std::vec::Vec; use sp_trie::{read_trie_value, Layout, MemoryDB, StorageProof}; @@ -67,7 +66,7 @@ pub enum Error { /// /// NOTE: This should only be used for **testing**. #[cfg(feature = "std")] -pub fn craft_valid_storage_proof() -> (H256, StorageProof) { +pub fn craft_valid_storage_proof() -> (sp_core::H256, StorageProof) { use sp_state_machine::{backend::Backend, prove_read, InMemoryBackend}; // construct storage proof @@ -106,7 +105,7 @@ pub mod tests { // checking proof against invalid commitment fails assert_eq!( - >::new(H256::random(), proof).err(), + >::new(sp_core::H256::random(), proof).err(), Some(Error::StorageRootMismatch) ); } diff --git a/bridges/relays/bin-substrate/src/finality_pipeline.rs b/bridges/relays/bin-substrate/src/finality_pipeline.rs index d58306f44f..0b035cd57f 100644 --- a/bridges/relays/bin-substrate/src/finality_pipeline.rs +++ b/bridges/relays/bin-substrate/src/finality_pipeline.rs @@ -18,11 +18,9 @@ use crate::finality_target::SubstrateFinalityTarget; +use bp_header_chain::justification::GrandpaJustification; use finality_relay::{FinalitySyncParams, FinalitySyncPipeline}; -use relay_substrate_client::{ - finality_source::{FinalitySource, Justification}, - BlockNumberOf, Chain, Client, HashOf, SyncHeader, -}; +use relay_substrate_client::{finality_source::FinalitySource, BlockNumberOf, Chain, Client, HashOf, SyncHeader}; use relay_utils::BlockNumberBase; use sp_core::Bytes; use std::{fmt::Debug, marker::PhantomData, time::Duration}; @@ -101,7 +99,7 @@ where type Hash = HashOf; type Number = BlockNumberOf; type Header = SyncHeader; - type FinalityProof = Justification; + type FinalityProof = GrandpaJustification; } /// Run Substrate-to-Substrate finality sync. @@ -116,7 +114,7 @@ where Hash = HashOf, Number = BlockNumberOf, Header = SyncHeader, - FinalityProof = Justification, + FinalityProof = GrandpaJustification, TargetChain = TargetChain, >, SourceChain: Clone + Chain, diff --git a/bridges/relays/bin-substrate/src/headers_initialize.rs b/bridges/relays/bin-substrate/src/headers_initialize.rs index bc191df3b7..07d6d0f06d 100644 --- a/bridges/relays/bin-substrate/src/headers_initialize.rs +++ b/bridges/relays/bin-substrate/src/headers_initialize.rs @@ -23,7 +23,7 @@ use bp_header_chain::{ find_grandpa_authorities_scheduled_change, - justification::{decode_justification_target, verify_justification}, + justification::{verify_justification, GrandpaJustification}, }; use codec::Decode; use finality_grandpa::voter_set::VoterSet; @@ -116,9 +116,12 @@ async fn prepare_initialization_data( })?; // Read initial header. + let justification: GrandpaJustification = Decode::decode(&mut &justification.0[..]) + .map_err(|err| format!("Failed to decode {} justification: {:?}", SourceChain::NAME, err))?; + let (initial_header_hash, initial_header_number) = - decode_justification_target::(&justification.0) - .map_err(|err| format!("Failed to decode {} justification: {:?}", SourceChain::NAME, err))?; + (justification.commit.target_hash, justification.commit.target_number); + let initial_header = source_header(&source_client, initial_header_hash).await?; log::trace!(target: "bridge", "Selected {} initial header: {}/{}", SourceChain::NAME, @@ -176,9 +179,10 @@ async fn prepare_initialization_data( (initial_header_hash, initial_header_number), initial_authorities_set_id, &authorities_for_verification, - &justification.0, + &justification, ) .is_ok(); + if is_valid_set_id { break; } diff --git a/bridges/relays/bin-substrate/src/rialto_millau/millau_headers_to_rialto.rs b/bridges/relays/bin-substrate/src/rialto_millau/millau_headers_to_rialto.rs index f85560bf19..43ae3954c3 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/millau_headers_to_rialto.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/millau_headers_to_rialto.rs @@ -18,10 +18,11 @@ use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; +use bp_header_chain::justification::GrandpaJustification; use codec::Encode; use relay_millau_client::{Millau, SyncHeader as MillauSyncHeader}; use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams}; -use relay_substrate_client::{finality_source::Justification, Chain, TransactionSignScheme}; +use relay_substrate_client::{Chain, TransactionSignScheme}; use sp_core::{Bytes, Pair}; /// Millau-to-Rialto finality sync pipeline. @@ -40,11 +41,9 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto { &self, transaction_nonce: ::Index, header: MillauSyncHeader, - proof: Justification, + proof: GrandpaJustification, ) -> Bytes { - let call = - rialto_runtime::BridgeGrandpaMillauCall::submit_finality_proof(header.into_inner(), proof.into_inner()) - .into(); + let call = rialto_runtime::BridgeGrandpaMillauCall::submit_finality_proof(header.into_inner(), proof).into(); let genesis_hash = *self.target_client.genesis_hash(); let transaction = Rialto::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); diff --git a/bridges/relays/bin-substrate/src/rialto_millau/rialto_headers_to_millau.rs b/bridges/relays/bin-substrate/src/rialto_millau/rialto_headers_to_millau.rs index 93a5e48b83..f18f108320 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/rialto_headers_to_millau.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/rialto_headers_to_millau.rs @@ -18,10 +18,11 @@ use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; +use bp_header_chain::justification::GrandpaJustification; use codec::Encode; use relay_millau_client::{Millau, SigningParams as MillauSigningParams}; use relay_rialto_client::{Rialto, SyncHeader as RialtoSyncHeader}; -use relay_substrate_client::{finality_source::Justification, Chain, TransactionSignScheme}; +use relay_substrate_client::{Chain, TransactionSignScheme}; use sp_core::{Bytes, Pair}; /// Rialto-to-Millau finality sync pipeline. @@ -40,12 +41,12 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau { &self, transaction_nonce: ::Index, header: RialtoSyncHeader, - proof: Justification, + proof: GrandpaJustification, ) -> Bytes { let call = millau_runtime::BridgeGrandpaRialtoCall::< millau_runtime::Runtime, millau_runtime::RialtoGrandpaInstance, - >::submit_finality_proof(header.into_inner(), proof.into_inner()) + >::submit_finality_proof(header.into_inner(), proof) .into(); let genesis_hash = *self.target_client.genesis_hash(); diff --git a/bridges/relays/bin-substrate/src/rialto_millau/westend_headers_to_millau.rs b/bridges/relays/bin-substrate/src/rialto_millau/westend_headers_to_millau.rs index 4aa6b569f0..f042c0bd39 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/westend_headers_to_millau.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/westend_headers_to_millau.rs @@ -18,9 +18,10 @@ use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; +use bp_header_chain::justification::GrandpaJustification; use codec::Encode; use relay_millau_client::{Millau, SigningParams as MillauSigningParams}; -use relay_substrate_client::{finality_source::Justification, Chain, TransactionSignScheme}; +use relay_substrate_client::{Chain, TransactionSignScheme}; use relay_westend_client::{SyncHeader as WestendSyncHeader, Westend}; use sp_core::{Bytes, Pair}; @@ -40,12 +41,12 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau { &self, transaction_nonce: ::Index, header: WestendSyncHeader, - proof: Justification, + proof: GrandpaJustification, ) -> Bytes { let call = millau_runtime::BridgeGrandpaWestendCall::< millau_runtime::Runtime, millau_runtime::WestendGrandpaInstance, - >::submit_finality_proof(header.into_inner(), proof.into_inner()) + >::submit_finality_proof(header.into_inner(), proof) .into(); let genesis_hash = *self.target_client.genesis_hash(); diff --git a/bridges/relays/client-substrate/src/finality_source.rs b/bridges/relays/client-substrate/src/finality_source.rs index 9b6c0975a4..3850093419 100644 --- a/bridges/relays/client-substrate/src/finality_source.rs +++ b/bridges/relays/client-substrate/src/finality_source.rs @@ -22,35 +22,14 @@ use crate::error::Error; use crate::sync_header::SyncHeader; use async_trait::async_trait; -use bp_header_chain::justification::decode_justification_target; -use finality_relay::{FinalityProof, FinalitySyncPipeline, SourceClient, SourceHeader}; +use bp_header_chain::justification::GrandpaJustification; +use codec::Decode; +use finality_relay::{FinalitySyncPipeline, SourceClient, SourceHeader}; use futures::stream::{unfold, Stream, StreamExt}; use relay_utils::relay_loop::Client as RelayClient; use sp_runtime::traits::Header as HeaderT; use std::{marker::PhantomData, pin::Pin}; -/// Wrapped raw Justification. -#[derive(Debug, Clone)] -pub struct Justification { - /// Header number decoded from the [`raw_justification`]. - target_header_number: Number, - /// Raw, encoded justification bytes. - raw_justification: sp_runtime::Justification, -} - -impl Justification { - /// Extract raw justification. - pub fn into_inner(self) -> sp_runtime::Justification { - self.raw_justification - } -} - -impl FinalityProof for Justification { - fn target_header_number(&self) -> Number { - self.target_header_number - } -} - /// Substrate node as finality source. pub struct FinalitySource { client: Client, @@ -94,11 +73,11 @@ where Hash = C::Hash, Number = C::BlockNumber, Header = SyncHeader, - FinalityProof = Justification, + FinalityProof = GrandpaJustification, >, P::Header: SourceHeader, { - type FinalityProofsStream = Pin> + Send>>; + type FinalityProofsStream = Pin> + Send>>; async fn best_finalized_block_number(&self) -> Result { // we **CAN** continue to relay finality proofs if source node is out of sync, because @@ -114,16 +93,14 @@ where ) -> Result<(P::Header, Option), Error> { let header_hash = self.client.block_hash_by_number(number).await?; let signed_block = self.client.get_block(Some(header_hash)).await?; - Ok(( - signed_block.header().into(), - signed_block - .justification() - .cloned() - .map(|raw_justification| Justification { - target_header_number: number, - raw_justification, - }), - )) + + let justification = signed_block + .justification() + .map(|raw_justification| GrandpaJustification::::decode(&mut raw_justification.as_slice())) + .transpose() + .map_err(Error::ResponseParseFailed)?; + + Ok((signed_block.header().into(), justification)) } async fn finality_proofs(&self) -> Result { @@ -132,9 +109,11 @@ where move |mut subscription| async move { loop { let next_justification = subscription.next().await?; - let decoded_target = decode_justification_target::(&next_justification.0); - let target_header_number = match decoded_target { - Ok((_, number)) => number, + let decoded_justification = + GrandpaJustification::::decode(&mut &next_justification.0[..]); + + let justification = match decoded_justification { + Ok(j) => j, Err(err) => { log::error!( target: "bridge", @@ -147,13 +126,7 @@ where } }; - return Some(( - Justification { - target_header_number, - raw_justification: next_justification.0, - }, - subscription, - )); + return Some((justification, subscription)); } }, ) diff --git a/bridges/relays/finality/Cargo.toml b/bridges/relays/finality/Cargo.toml index e70fb39d13..944da9837f 100644 --- a/bridges/relays/finality/Cargo.toml +++ b/bridges/relays/finality/Cargo.toml @@ -10,6 +10,7 @@ description = "Finality proofs relay" async-std = "1.6.5" async-trait = "0.1.40" backoff = "0.2" +bp-header-chain = { path = "../../primitives/header-chain" } futures = "0.3.5" headers-relay = { path = "../headers" } log = "0.4.11" diff --git a/bridges/relays/finality/src/lib.rs b/bridges/relays/finality/src/lib.rs index a246e4bd95..f587749976 100644 --- a/bridges/relays/finality/src/lib.rs +++ b/bridges/relays/finality/src/lib.rs @@ -21,6 +21,7 @@ pub use crate::finality_loop::{run, FinalitySyncParams, SourceClient, TargetClient}; +use bp_header_chain::FinalityProof; use std::fmt::Debug; mod finality_loop; @@ -50,9 +51,3 @@ pub trait SourceHeader: Clone + Debug + PartialEq + Send + Sync { /// Returns true if this header needs to be submitted to target node. fn is_mandatory(&self) -> bool; } - -/// Abstract finality proof that is justifying block finality. -pub trait FinalityProof: Clone + Send + Sync + Debug { - /// Return number of header that this proof is generated for. - fn target_header_number(&self) -> Number; -}