Add basic equivocation detection pipeline schema (#2338) (#2341)

* Move finality Engine to finality_base folder

* Define SubstrateFinalityPipeline

Extract basic parts of SubstrateFinalitySyncPipeline into
SubstrateFinalityPipeline

* Add equivocation detection pipeline

* Fix comment
This commit is contained in:
Serban Iorga
2023-08-11 12:35:54 +03:00
committed by Bastian Köcher
parent 8ebef157a9
commit 9bfad80664
34 changed files with 234 additions and 47 deletions
@@ -0,0 +1,83 @@
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Types and functions intended to ease adding of new Substrate -> Substrate
//! equivocation detection pipelines.
use crate::finality_base::SubstrateFinalityPipeline;
use std::marker::PhantomData;
use crate::finality_base::engine::Engine;
use async_trait::async_trait;
use bp_runtime::{BlockNumberOf, HashOf};
use pallet_grandpa::{Call as GrandpaCall, Config as GrandpaConfig};
use relay_substrate_client::CallOf;
use sp_runtime::traits::{Block, Header};
/// Substrate -> Substrate equivocation detection pipeline.
#[async_trait]
pub trait SubstrateEquivocationDetectionPipeline: SubstrateFinalityPipeline {
/// How the `report_equivocation` call is built ?
type ReportEquivocationCallBuilder: ReportEquivocationCallBuilder<Self>;
}
type EquivocationProofOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain,
>>::EquivocationProof;
type KeyOwnerProofOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain,
>>::KeyOwnerProof;
/// Different ways of building `report_equivocation` calls.
pub trait ReportEquivocationCallBuilder<P: SubstrateEquivocationDetectionPipeline> {
/// Build a `report_equivocation` call to be executed on the source chain.
fn build_report_equivocation_call(
equivocation_proof: EquivocationProofOf<P>,
key_owner_proof: KeyOwnerProofOf<P>,
) -> CallOf<P::SourceChain>;
}
/// Building the `report_equivocation` call when having direct access to the target chain runtime.
pub struct DirectReportGrandpaEquivocationCallBuilder<P, R> {
_phantom: PhantomData<(P, R)>,
}
impl<P, R> ReportEquivocationCallBuilder<P> for DirectReportGrandpaEquivocationCallBuilder<P, R>
where
P: SubstrateEquivocationDetectionPipeline,
P::FinalityEngine: Engine<
P::SourceChain,
EquivocationProof = sp_consensus_grandpa::EquivocationProof<
HashOf<P::SourceChain>,
BlockNumberOf<P::SourceChain>,
>,
>,
R: frame_system::Config<Hash = HashOf<P::SourceChain>>
+ GrandpaConfig<KeyOwnerProof = KeyOwnerProofOf<P>>,
<R::Block as Block>::Header: Header<Number = BlockNumberOf<P::SourceChain>>,
CallOf<P::SourceChain>: From<GrandpaCall<R>>,
{
fn build_report_equivocation_call(
equivocation_proof: EquivocationProofOf<P>,
key_owner_proof: KeyOwnerProofOf<P>,
) -> CallOf<P::SourceChain> {
GrandpaCall::<R>::report_equivocation {
equivocation_proof: Box::new(equivocation_proof),
key_owner_proof,
}
.into()
}
}
@@ -21,7 +21,7 @@
//! and authorities set from source to target chain. The finality sync starts
//! with this header.
use crate::{error::Error, finality::engine::Engine};
use crate::{error::Error, finality_base::engine::Engine};
use sp_core::Pair;
use bp_runtime::HeaderIdOf;
@@ -19,26 +19,25 @@
use crate::{
finality::{
engine::Engine,
source::{SubstrateFinalityProof, SubstrateFinalitySource},
target::SubstrateFinalityTarget,
},
TransactionParams,
};
use crate::finality_base::{engine::Engine, SubstrateFinalityPipeline};
use async_trait::async_trait;
use bp_header_chain::justification::GrandpaJustification;
use finality_relay::FinalitySyncPipeline;
use pallet_bridge_grandpa::{Call as BridgeGrandpaCall, Config as BridgeGrandpaConfig};
use relay_substrate_client::{
transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, BlockNumberOf, CallOf, Chain,
ChainWithTransactions, Client, HashOf, HeaderOf, SyncHeader,
transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, BlockNumberOf, CallOf, Chain, Client,
HashOf, HeaderOf, SyncHeader,
};
use relay_utils::metrics::MetricsParams;
use sp_core::Pair;
use std::{fmt::Debug, marker::PhantomData};
pub mod engine;
pub mod initialize;
pub mod source;
pub mod target;
@@ -51,14 +50,7 @@ pub(crate) const RECENT_FINALITY_PROOFS_LIMIT: usize = 4096;
/// Substrate -> Substrate finality proofs synchronization pipeline.
#[async_trait]
pub trait SubstrateFinalitySyncPipeline: 'static + Clone + Debug + Send + Sync {
/// Headers of this chain are submitted to the `TargetChain`.
type SourceChain: Chain;
/// Headers of the `SourceChain` are submitted to this chain.
type TargetChain: ChainWithTransactions;
/// Finality engine.
type FinalityEngine: Engine<Self::SourceChain>;
pub trait SubstrateFinalitySyncPipeline: SubstrateFinalityPipeline {
/// How submit finality proof call is built?
type SubmitFinalityProofCallBuilder: SubmitFinalityProofCallBuilder<Self>;
@@ -144,16 +136,16 @@ macro_rules! generate_submit_finality_proof_call_builder {
fn build_submit_finality_proof_call(
header: relay_substrate_client::SyncHeader<
relay_substrate_client::HeaderOf<
<$pipeline as $crate::finality::SubstrateFinalitySyncPipeline>::SourceChain
<$pipeline as $crate::finality_base::SubstrateFinalityPipeline>::SourceChain
>
>,
proof: bp_header_chain::justification::GrandpaJustification<
relay_substrate_client::HeaderOf<
<$pipeline as $crate::finality::SubstrateFinalitySyncPipeline>::SourceChain
<$pipeline as $crate::finality_base::SubstrateFinalityPipeline>::SourceChain
>
>,
) -> relay_substrate_client::CallOf<
<$pipeline as $crate::finality::SubstrateFinalitySyncPipeline>::TargetChain
<$pipeline as $crate::finality_base::SubstrateFinalityPipeline>::TargetChain
> {
bp_runtime::paste::item! {
$bridge_grandpa($submit_finality_proof {
@@ -16,8 +16,12 @@
//! Default generic implementation of finality source for basic Substrate client.
use crate::finality::{engine::Engine, FinalitySyncPipelineAdapter, SubstrateFinalitySyncPipeline};
use crate::{
finality::{FinalitySyncPipelineAdapter, SubstrateFinalitySyncPipeline},
finality_base::engine::Engine,
};
use crate::finality_base::SubstrateFinalityPipeline;
use async_std::sync::{Arc, Mutex};
use async_trait::async_trait;
use bp_header_chain::FinalityProof;
@@ -42,10 +46,9 @@ pub type SubstrateFinalityProofsStream<P> =
Pin<Box<dyn Stream<Item = SubstrateFinalityProof<P>> + Send>>;
/// Substrate finality proof. Specific to the used `FinalityEngine`.
pub type SubstrateFinalityProof<P> =
<<P as SubstrateFinalitySyncPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalitySyncPipeline>::SourceChain,
>>::FinalityProof;
pub type SubstrateFinalityProof<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain,
>>::FinalityProof;
/// Substrate node as finality source.
pub struct SubstrateFinalitySource<P: SubstrateFinalitySyncPipeline> {
@@ -18,9 +18,10 @@
use crate::{
finality::{
engine::Engine, source::SubstrateFinalityProof, FinalitySyncPipelineAdapter,
source::SubstrateFinalityProof, FinalitySyncPipelineAdapter,
SubmitFinalityProofCallBuilder, SubstrateFinalitySyncPipeline,
},
finality_base::engine::Engine,
TransactionParams,
};
@@ -47,6 +47,10 @@ pub trait Engine<C: Chain>: Send {
type FinalityClient: SubstrateFinalityClient<C>;
/// Type of finality proofs, used by consensus engine.
type FinalityProof: FinalityProof<BlockNumberOf<C>> + Decode + Encode;
/// The type of the equivocation proof used by the consensus engine.
type EquivocationProof;
/// The type of the key owner proof used by the consensus engine.
type KeyOwnerProof;
/// Type of bridge pallet initialization data.
type InitializationData: std::fmt::Debug + Send + Sync + 'static;
/// Type of bridge pallet operating mode.
@@ -138,6 +142,8 @@ impl<C: ChainWithGrandpa> Engine<C> for Grandpa<C> {
type ConsensusLogReader = GrandpaConsensusLogReader<<C::Header as Header>::Number>;
type FinalityClient = SubstrateGrandpaFinalityClient;
type FinalityProof = GrandpaJustification<HeaderOf<C>>;
type EquivocationProof = sp_consensus_grandpa::EquivocationProof<HashOf<C>, BlockNumberOf<C>>;
type KeyOwnerProof = C::KeyOwnerProof;
type InitializationData = bp_header_chain::InitializationData<C::Header>;
type OperatingMode = BasicOperatingMode;
@@ -0,0 +1,35 @@
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Types and functions intended to ease adding of new Substrate -> Substrate
//! finality pipelines.
pub mod engine;
use async_trait::async_trait;
use relay_substrate_client::{Chain, ChainWithTransactions};
use std::fmt::Debug;
/// Substrate -> Substrate finality related pipeline.
#[async_trait]
pub trait SubstrateFinalityPipeline: 'static + Clone + Debug + Send + Sync {
/// Headers of this chain are submitted to the `TargetChain`.
type SourceChain: Chain;
/// Headers of the `SourceChain` are submitted to this chain.
type TargetChain: ChainWithTransactions;
/// Finality engine.
type FinalityEngine: engine::Engine<Self::SourceChain>;
}
@@ -22,8 +22,10 @@ use relay_substrate_client::{Chain, ChainWithUtilityPallet, UtilityPallet};
use std::marker::PhantomData;
pub mod equivocation;
pub mod error;
pub mod finality;
pub mod finality_base;
pub mod messages_lane;
pub mod messages_metrics;
pub mod messages_source;
@@ -38,11 +38,11 @@ use relay_utils::{
use crate::{
finality::{
engine::Engine,
source::{RequiredHeaderNumberRef, SubstrateFinalitySource},
target::SubstrateFinalityTarget,
SubstrateFinalitySyncPipeline, RECENT_FINALITY_PROOFS_LIMIT,
},
finality_base::engine::Engine,
on_demand::OnDemandRelay,
TransactionParams,
};