From f09f758d180d5f9821575e7fac1fb19ad8ab4b2b Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Wed, 9 Aug 2023 17:08:02 +0300 Subject: [PATCH] Add equivocation detection pipeline --- Cargo.lock | 8 ++ relays/client-kusama/Cargo.toml | 1 + relays/client-kusama/src/lib.rs | 3 + relays/client-millau/Cargo.toml | 1 + relays/client-millau/src/lib.rs | 3 + relays/client-polkadot/Cargo.toml | 1 + relays/client-polkadot/src/lib.rs | 3 + relays/client-rialto/Cargo.toml | 1 + relays/client-rialto/src/lib.rs | 3 + relays/client-rococo/Cargo.toml | 1 + relays/client-rococo/src/lib.rs | 3 + relays/client-substrate/src/chain.rs | 3 + relays/client-westend/Cargo.toml | 1 + relays/client-westend/src/lib.rs | 3 + relays/client-wococo/Cargo.toml | 1 + relays/client-wococo/src/lib.rs | 3 + relays/lib-substrate-relay/Cargo.toml | 1 + .../src/equivocation/mod.rs | 83 +++++++++++++++++++ .../lib-substrate-relay/src/finality/mod.rs | 4 +- .../src/finality_base/engine.rs | 6 ++ relays/lib-substrate-relay/src/lib.rs | 1 + 21 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 relays/lib-substrate-relay/src/equivocation/mod.rs diff --git a/Cargo.lock b/Cargo.lock index c5a22cf9899..c512280b6e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10261,6 +10261,7 @@ dependencies = [ "relay-substrate-client", "relay-utils", "sp-core", + "sp-session", ] [[package]] @@ -10277,6 +10278,7 @@ dependencies = [ "relay-utils", "sp-core", "sp-runtime", + "sp-session", ] [[package]] @@ -10287,6 +10289,7 @@ dependencies = [ "relay-substrate-client", "relay-utils", "sp-core", + "sp-session", ] [[package]] @@ -10303,6 +10306,7 @@ dependencies = [ "rialto-runtime", "sp-core", "sp-runtime", + "sp-session", ] [[package]] @@ -10333,6 +10337,7 @@ dependencies = [ "relay-substrate-client", "relay-utils", "sp-core", + "sp-session", ] [[package]] @@ -10410,6 +10415,7 @@ dependencies = [ "relay-substrate-client", "relay-utils", "sp-core", + "sp-session", ] [[package]] @@ -10420,6 +10426,7 @@ dependencies = [ "relay-substrate-client", "relay-utils", "sp-core", + "sp-session", ] [[package]] @@ -13980,6 +13987,7 @@ dependencies = [ "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", + "pallet-grandpa", "pallet-transaction-payment", "parachains-relay", "parity-scale-codec", diff --git a/relays/client-kusama/Cargo.toml b/relays/client-kusama/Cargo.toml index e4d83d88ceb..4f8813c51a5 100644 --- a/relays/client-kusama/Cargo.toml +++ b/relays/client-kusama/Cargo.toml @@ -16,3 +16,4 @@ bp-kusama = { path = "../../primitives/chain-kusama" } # Substrate Dependencies sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-kusama/src/lib.rs b/relays/client-kusama/src/lib.rs index 7291a21b620..15b8abd2670 100644 --- a/relays/client-kusama/src/lib.rs +++ b/relays/client-kusama/src/lib.rs @@ -21,6 +21,7 @@ use relay_substrate_client::{ Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, }; use sp_core::storage::StorageKey; +use sp_session::MembershipProof; use std::time::Duration; /// Kusama header id. @@ -50,6 +51,8 @@ impl Chain for Kusama { impl ChainWithGrandpa for Kusama { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = KUSAMA_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl ChainWithBalances for Kusama { diff --git a/relays/client-millau/Cargo.toml b/relays/client-millau/Cargo.toml index e01c37eb52b..86ce0429d54 100644 --- a/relays/client-millau/Cargo.toml +++ b/relays/client-millau/Cargo.toml @@ -22,3 +22,4 @@ frame-system = { git = "https://github.com/paritytech/substrate", branch = "mast pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-millau/src/lib.rs b/relays/client-millau/src/lib.rs index d470b9ee1f4..68d71e7bdb7 100644 --- a/relays/client-millau/src/lib.rs +++ b/relays/client-millau/src/lib.rs @@ -25,6 +25,7 @@ use relay_substrate_client::{ }; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; +use sp_session::MembershipProof; use std::time::Duration; /// Millau header id. @@ -60,6 +61,8 @@ impl Chain for Millau { impl ChainWithGrandpa for Millau { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = MILLAU_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl ChainWithBalances for Millau { diff --git a/relays/client-polkadot/Cargo.toml b/relays/client-polkadot/Cargo.toml index cc16ec1f5c3..7c9fa957001 100644 --- a/relays/client-polkadot/Cargo.toml +++ b/relays/client-polkadot/Cargo.toml @@ -16,3 +16,4 @@ bp-polkadot = { path = "../../primitives/chain-polkadot" } # Substrate Dependencies sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-polkadot/src/lib.rs b/relays/client-polkadot/src/lib.rs index 07386281c04..345b45506d3 100644 --- a/relays/client-polkadot/src/lib.rs +++ b/relays/client-polkadot/src/lib.rs @@ -21,6 +21,7 @@ use relay_substrate_client::{ Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, }; use sp_core::storage::StorageKey; +use sp_session::MembershipProof; use std::time::Duration; /// Polkadot header id. @@ -50,6 +51,8 @@ impl Chain for Polkadot { impl ChainWithGrandpa for Polkadot { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = POLKADOT_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl ChainWithBalances for Polkadot { diff --git a/relays/client-rialto/Cargo.toml b/relays/client-rialto/Cargo.toml index 85607b07db9..4279c6ecc12 100644 --- a/relays/client-rialto/Cargo.toml +++ b/relays/client-rialto/Cargo.toml @@ -22,3 +22,4 @@ frame-support = { git = "https://github.com/paritytech/substrate", branch = "mas pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-rialto/src/lib.rs b/relays/client-rialto/src/lib.rs index a73c3cb9753..213be5eda65 100644 --- a/relays/client-rialto/src/lib.rs +++ b/relays/client-rialto/src/lib.rs @@ -25,6 +25,7 @@ use relay_substrate_client::{ }; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; +use sp_session::MembershipProof; use std::time::Duration; /// Rialto header id. @@ -51,6 +52,8 @@ impl Chain for Rialto { impl ChainWithGrandpa for Rialto { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = RIALTO_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl RelayChain for Rialto { diff --git a/relays/client-rococo/Cargo.toml b/relays/client-rococo/Cargo.toml index cc197ba8562..9ced6e2b939 100644 --- a/relays/client-rococo/Cargo.toml +++ b/relays/client-rococo/Cargo.toml @@ -16,3 +16,4 @@ bp-rococo = { path = "../../primitives/chain-rococo" } # Substrate Dependencies sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-rococo/src/lib.rs b/relays/client-rococo/src/lib.rs index 5e4124a5d33..04fe11c741c 100644 --- a/relays/client-rococo/src/lib.rs +++ b/relays/client-rococo/src/lib.rs @@ -21,6 +21,7 @@ use relay_substrate_client::{ Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, }; use sp_core::storage::StorageKey; +use sp_session::MembershipProof; use std::time::Duration; /// Rococo header id. @@ -50,6 +51,8 @@ impl Chain for Rococo { impl ChainWithGrandpa for Rococo { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = ROCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl ChainWithBalances for Rococo { diff --git a/relays/client-substrate/src/chain.rs b/relays/client-substrate/src/chain.rs index 86526790b5b..6fc54944e75 100644 --- a/relays/client-substrate/src/chain.rs +++ b/relays/client-substrate/src/chain.rs @@ -86,6 +86,9 @@ pub trait ChainWithGrandpa: Chain + UnderlyingChainWithGrandpaProvider { /// Keep in mind that this method is normally provided by the other chain, which is /// bridged with this chain. const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str; + + /// The type of the key owner proof used by the grandpa engine. + type KeyOwnerProof; } /// Substrate-based parachain from minimal relay-client point of view. diff --git a/relays/client-westend/Cargo.toml b/relays/client-westend/Cargo.toml index c60305868ad..744b2d29e75 100644 --- a/relays/client-westend/Cargo.toml +++ b/relays/client-westend/Cargo.toml @@ -16,3 +16,4 @@ bp-westend = { path = "../../primitives/chain-westend" } # Substrate Dependencies sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-westend/src/lib.rs b/relays/client-westend/src/lib.rs index c304b7e2f37..523accbfdbf 100644 --- a/relays/client-westend/src/lib.rs +++ b/relays/client-westend/src/lib.rs @@ -21,6 +21,7 @@ use relay_substrate_client::{ Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, }; use sp_core::storage::StorageKey; +use sp_session::MembershipProof; use std::time::Duration; /// Westend header id. @@ -50,6 +51,8 @@ impl Chain for Westend { impl ChainWithGrandpa for Westend { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = WESTEND_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl RelayChain for Westend { diff --git a/relays/client-wococo/Cargo.toml b/relays/client-wococo/Cargo.toml index 19483ab22fd..385cede88bc 100644 --- a/relays/client-wococo/Cargo.toml +++ b/relays/client-wococo/Cargo.toml @@ -15,3 +15,4 @@ bp-wococo = { path = "../../primitives/chain-wococo" } # Substrate Dependencies sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/client-wococo/src/lib.rs b/relays/client-wococo/src/lib.rs index c080a217a77..e9d52280822 100644 --- a/relays/client-wococo/src/lib.rs +++ b/relays/client-wococo/src/lib.rs @@ -21,6 +21,7 @@ use relay_substrate_client::{ Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, }; use sp_core::storage::StorageKey; +use sp_session::MembershipProof; use std::time::Duration; /// Wococo header id. @@ -50,6 +51,8 @@ impl Chain for Wococo { impl ChainWithGrandpa for Wococo { const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = WOCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD; + + type KeyOwnerProof = MembershipProof; } impl ChainWithBalances for Wococo { diff --git a/relays/lib-substrate-relay/Cargo.toml b/relays/lib-substrate-relay/Cargo.toml index 26762a50a77..6db30996a8a 100644 --- a/relays/lib-substrate-relay/Cargo.toml +++ b/relays/lib-substrate-relay/Cargo.toml @@ -43,6 +43,7 @@ bp-messages = { path = "../../primitives/messages" } frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/relays/lib-substrate-relay/src/equivocation/mod.rs b/relays/lib-substrate-relay/src/equivocation/mod.rs new file mode 100644 index 00000000000..31668490f90 --- /dev/null +++ b/relays/lib-substrate-relay/src/equivocation/mod.rs @@ -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 . + +//! 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; +} + +type EquivocationProofOf

= <

::FinalityEngine as Engine< +

::SourceChain, +>>::EquivocationProof; +type KeyOwnerProofOf

= <

::FinalityEngine as Engine< +

::SourceChain, +>>::KeyOwnerProof; + +/// Different ways of building `report_equivocation` calls. +pub trait ReportEquivocationCallBuilder { + /// Build a `report_equivocation` call to be executed on the source chain. + fn build_report_equivocation_call( + equivocation_proof: EquivocationProofOf

, + key_owner_proof: KeyOwnerProofOf

, + ) -> CallOf; +} + +/// Building the `report_equivocation` call when having direct access to the target chain runtime. +pub struct DirectReportGrandpaEquivocationCallBuilder { + _phantom: PhantomData<(P, R)>, +} + +impl ReportEquivocationCallBuilder

for DirectReportGrandpaEquivocationCallBuilder +where + P: SubstrateEquivocationDetectionPipeline, + P::FinalityEngine: Engine< + P::SourceChain, + EquivocationProof = sp_consensus_grandpa::EquivocationProof< + HashOf, + BlockNumberOf, + >, + >, + R: frame_system::Config> + + GrandpaConfig>, + ::Header: Header>, + CallOf: From>, +{ + fn build_report_equivocation_call( + equivocation_proof: EquivocationProofOf

, + key_owner_proof: KeyOwnerProofOf

, + ) -> CallOf { + GrandpaCall::::report_equivocation { + equivocation_proof: Box::new(equivocation_proof), + key_owner_proof, + } + .into() + } +} diff --git a/relays/lib-substrate-relay/src/finality/mod.rs b/relays/lib-substrate-relay/src/finality/mod.rs index 0bec4338a6a..db021db8352 100644 --- a/relays/lib-substrate-relay/src/finality/mod.rs +++ b/relays/lib-substrate-relay/src/finality/mod.rs @@ -50,9 +50,7 @@ pub(crate) const RECENT_FINALITY_PROOFS_LIMIT: usize = 4096; /// Substrate -> Substrate finality proofs synchronization pipeline. #[async_trait] -pub trait SubstrateFinalitySyncPipeline: - 'static + SubstrateFinalityPipeline + Clone + Debug + Send + Sync -{ +pub trait SubstrateFinalitySyncPipeline: SubstrateFinalityPipeline { /// How submit finality proof call is built? type SubmitFinalityProofCallBuilder: SubmitFinalityProofCallBuilder; diff --git a/relays/lib-substrate-relay/src/finality_base/engine.rs b/relays/lib-substrate-relay/src/finality_base/engine.rs index e650ebf54f3..272c20c2606 100644 --- a/relays/lib-substrate-relay/src/finality_base/engine.rs +++ b/relays/lib-substrate-relay/src/finality_base/engine.rs @@ -46,6 +46,10 @@ pub trait Engine: Send { type ConsensusLogReader: ConsensusLogReader; /// Type of finality proofs, used by consensus engine. type FinalityProof: FinalityProof> + 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. @@ -137,6 +141,8 @@ impl Engine for Grandpa { const ID: ConsensusEngineId = GRANDPA_ENGINE_ID; type ConsensusLogReader = GrandpaConsensusLogReader<::Number>; type FinalityProof = GrandpaJustification>; + type EquivocationProof = sp_consensus_grandpa::EquivocationProof, BlockNumberOf>; + type KeyOwnerProof = C::KeyOwnerProof; type InitializationData = bp_header_chain::InitializationData; type OperatingMode = BasicOperatingMode; diff --git a/relays/lib-substrate-relay/src/lib.rs b/relays/lib-substrate-relay/src/lib.rs index 08a7ce785ba..068c5ceccf3 100644 --- a/relays/lib-substrate-relay/src/lib.rs +++ b/relays/lib-substrate-relay/src/lib.rs @@ -22,6 +22,7 @@ use relay_substrate_client::{Chain, ChainWithUtilityPallet, UtilityPallet}; use std::marker::PhantomData; +pub mod equivocation; pub mod error; pub mod finality; pub mod finality_base;