Start the equivocation detection loop from the complex relayer (#2507) (#2512)

* Impl SubstrateEquivocationDetectionPipeline for Millau

* Impl SubstrateEquivocationDetectionPipeline for Rialto

* Make BridgeHubSignedExtension more generic

* Define generate_report_equivocation_call_builder!() macro

* Impl SubstrateEquivocationDetectionPipeline for Rococo

* Impl SubstrateEquivocationDetectionPipeline for Wococo

* Impl SubstrateEquivocationDetectionPipeline for Kusama

* Impl SubstrateEquivocationDetectionPipeline for Polkadot

* Complex relayer simplification

- remove `signer` and `transactions_mortality` and add `tx_params`
- change the order of some fields

* Add equivocation detection CLI traits

* Complex relayer: start equivocation detectin loop

* Update runtimes regeneration script

* Equivocation loop: Fix infinite loop

* Revert "Complex relayer: start equivocation detectin loop"

This reverts commit b518ef85679d73654f9f0e2add38cd3839552057.

* Add subcommand for starting the equivocation detection loop

* Fixes

* Initialize empty metrics for the equivocations detector loop
This commit is contained in:
Serban Iorga
2023-08-31 08:50:19 +03:00
committed by Bastian Köcher
parent 588508acd4
commit 1bbc77fee1
48 changed files with 25096 additions and 249 deletions
@@ -19,6 +19,7 @@ scale-info = { version = "2.9.0", default-features = false, features = ["derive"
bp-header-chain = { path = "../../../primitives/header-chain", default-features = false } bp-header-chain = { path = "../../../primitives/header-chain", default-features = false }
bp-messages = { path = "../../../primitives/messages", default-features = false } bp-messages = { path = "../../../primitives/messages", default-features = false }
bp-millau = { path = "../../../primitives/chain-millau", default-features = false } bp-millau = { path = "../../../primitives/chain-millau", default-features = false }
bp-polkadot-core = { path = "../../../primitives/polkadot-core", default-features = false }
bp-relayers = { path = "../../../primitives/relayers", default-features = false } bp-relayers = { path = "../../../primitives/relayers", default-features = false }
bp-runtime = { path = "../../../primitives/runtime", default-features = false } bp-runtime = { path = "../../../primitives/runtime", default-features = false }
bp-rialto-parachain = { path = "../../../primitives/chain-rialto-parachain", default-features = false } bp-rialto-parachain = { path = "../../../primitives/chain-rialto-parachain", default-features = false }
+32 -22
View File
@@ -858,12 +858,10 @@ mod tests {
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
LaneId, MessageKey, LaneId, MessageKey,
}; };
use bridge_runtime_common::{ use bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatchResult;
integrity::check_additional_signed, messages_xcm_extension::XcmBlobMessageDispatchResult,
};
use codec::Encode; use codec::Encode;
use pallet_bridge_messages::OutboundLanes; use pallet_bridge_messages::OutboundLanes;
use sp_runtime::generic::Era; use sp_runtime::{generic::Era, traits::Zero};
use xcm_executor::XcmExecutor; use xcm_executor::XcmExecutor;
fn new_test_ext() -> sp_io::TestExternalities { fn new_test_ext() -> sp_io::TestExternalities {
@@ -941,24 +939,36 @@ mod tests {
#[test] #[test]
fn ensure_signed_extension_definition_is_correct() { fn ensure_signed_extension_definition_is_correct() {
let payload: SignedExtra = ( use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
frame_system::CheckNonZeroSender::new(),
frame_system::CheckSpecVersion::new(),
frame_system::CheckTxVersion::new(),
frame_system::CheckGenesis::new(),
frame_system::CheckEra::from(Era::Immortal),
frame_system::CheckNonce::from(10),
frame_system::CheckWeight::new(),
pallet_transaction_payment::ChargeTransactionPayment::from(10),
BridgeRejectObsoleteHeadersAndMessages,
DummyBridgeRefundMillauMessages,
);
let indirect_payload = bp_rialto_parachain::SignedExtension::new(
((), (), (), (), Era::Immortal, 10.into(), (), 10.into(), (), ()),
None,
);
assert_eq!(payload.encode(), indirect_payload.encode());
check_additional_signed::<SignedExtra, bp_rialto_parachain::SignedExtension>(); sp_io::TestExternalities::default().execute_with(|| {
frame_system::BlockHash::<Runtime>::insert(BlockNumber::zero(), Hash::default());
let payload: SignedExtra = (
frame_system::CheckNonZeroSender::new(),
frame_system::CheckSpecVersion::new(),
frame_system::CheckTxVersion::new(),
frame_system::CheckGenesis::new(),
frame_system::CheckEra::from(Era::Immortal),
frame_system::CheckNonce::from(10),
frame_system::CheckWeight::new(),
pallet_transaction_payment::ChargeTransactionPayment::from(10),
BridgeRejectObsoleteHeadersAndMessages,
DummyBridgeRefundMillauMessages,
);
let indirect_payload = bp_rialto_parachain::SignedExtension::from_params(
VERSION.spec_version,
VERSION.transaction_version,
bp_runtime::TransactionEra::Immortal,
System::block_hash(BlockNumber::zero()),
10,
10,
(((), ()), ((), ())),
);
assert_eq!(payload.encode(), indirect_payload.encode());
assert_eq!(
payload.additional_signed().unwrap().encode(),
indirect_payload.additional_signed().unwrap().encode()
)
});
} }
} }
@@ -27,7 +27,6 @@ use codec::Encode;
use frame_support::{storage::generator::StorageValue, traits::Get, weights::Weight}; use frame_support::{storage::generator::StorageValue, traits::Get, weights::Weight};
use frame_system::limits; use frame_system::limits;
use pallet_bridge_messages::WeightInfoExt as _; use pallet_bridge_messages::WeightInfoExt as _;
use sp_runtime::traits::SignedExtension;
/// Macro that ensures that the runtime configuration and chain primitives crate are sharing /// Macro that ensures that the runtime configuration and chain primitives crate are sharing
/// the same types (nonce, block number, hash, hasher, account id and header). /// the same types (nonce, block number, hash, hasher, account id and header).
@@ -347,15 +346,3 @@ pub fn check_message_lane_weights<
); );
} }
} }
/// Check that the `AdditionalSigned` type of a wrapped runtime is the same as the one of the
/// corresponding actual runtime.
///
/// This method doesn't perform any `assert`. If the condition is not true it will generate a
/// compile-time error.
pub fn check_additional_signed<SignedExt, IndirectSignedExt: SignedExtension>()
where
SignedExt: SignedExtension,
IndirectSignedExt: SignedExtension<AdditionalSigned = SignedExt::AdditionalSigned>,
{
}
@@ -23,10 +23,9 @@ pub use bp_polkadot_core::{
}; };
use bp_messages::*; use bp_messages::*;
use bp_polkadot_core::SuffixedCommonSignedExtension;
use bp_runtime::extensions::{ use bp_runtime::extensions::{
BridgeRejectObsoleteHeadersAndMessages, ChargeTransactionPayment, CheckEra, CheckGenesis, BridgeRejectObsoleteHeadersAndMessages, RefundBridgedParachainMessagesSchema,
CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, CheckWeight,
GenericSignedExtension, RefundBridgedParachainMessagesSchema,
}; };
use frame_support::{ use frame_support::{
dispatch::DispatchClass, dispatch::DispatchClass,
@@ -133,88 +132,8 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024;
/// analysis (like the one above). /// analysis (like the one above).
pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096; pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096;
/// Extra signed extension data that is used by all bridge hubs. /// Signed extension that is used by all bridge hubs.
pub type SignedExtra = ( pub type SignedExtension = SuffixedCommonSignedExtension<(
CheckNonZeroSender,
CheckSpecVersion,
CheckTxVersion,
CheckGenesis<Hash>,
CheckEra<Hash>,
CheckNonce<Nonce>,
CheckWeight,
ChargeTransactionPayment<Balance>,
BridgeRejectObsoleteHeadersAndMessages, BridgeRejectObsoleteHeadersAndMessages,
RefundBridgedParachainMessagesSchema, RefundBridgedParachainMessagesSchema,
); )>;
/// Signed extension that is used by all bridge hubs.
pub type SignedExtension = GenericSignedExtension<SignedExtra>;
/// Helper trait to define some extra methods on bridge hubs signed extension (and
/// overcome Rust limitations).
pub trait BridgeHubSignedExtension {
/// Create signed extension from its components.
fn from_params(
spec_version: u32,
transaction_version: u32,
era: bp_runtime::TransactionEra<BlockNumber, Hash>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
) -> Self;
/// Return transaction nonce.
fn nonce(&self) -> Nonce;
/// Return transaction tip.
fn tip(&self) -> Balance;
}
impl BridgeHubSignedExtension for SignedExtension {
/// Create signed extension from its components.
fn from_params(
spec_version: u32,
transaction_version: u32,
era: bp_runtime::TransactionEra<BlockNumber, Hash>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
) -> Self {
GenericSignedExtension::new(
(
(), // non-zero sender
(), // spec version
(), // tx version
(), // genesis
era.frame_era(), // era
nonce.into(), // nonce (compact encoding)
(), // Check weight
tip.into(), // transaction payment / tip (compact encoding)
(), // bridge reject obsolete headers and msgs
(), // bridge reward to relayer for message passing
),
Some((
(),
spec_version,
transaction_version,
genesis_hash,
era.signed_payload(genesis_hash),
(),
(),
(),
(),
(),
)),
)
}
/// Return transaction nonce.
fn nonce(&self) -> Nonce {
self.payload.5 .0
}
/// Return transaction tip.
fn tip(&self) -> Balance {
self.payload.7 .0
}
}
@@ -57,6 +57,9 @@ impl ChainWithGrandpa for Kusama {
const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = AVERAGE_HEADER_SIZE_IN_JUSTIFICATION; const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = AVERAGE_HEADER_SIZE_IN_JUSTIFICATION;
} }
// The SignedExtension used by Kusama.
pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
/// Name of the parachains pallet in the Kusama runtime. /// Name of the parachains pallet in the Kusama runtime.
pub const PARAS_PALLET_NAME: &str = "Paras"; pub const PARAS_PALLET_NAME: &str = "Paras";
+4 -1
View File
@@ -21,7 +21,7 @@
pub use bp_polkadot_core::*; pub use bp_polkadot_core::*;
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; use bp_runtime::{decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain};
use frame_support::weights::Weight; use frame_support::weights::Weight;
use sp_std::prelude::Vec; use sp_std::prelude::Vec;
@@ -57,6 +57,9 @@ impl ChainWithGrandpa for Polkadot {
const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = AVERAGE_HEADER_SIZE_IN_JUSTIFICATION; const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = AVERAGE_HEADER_SIZE_IN_JUSTIFICATION;
} }
/// The SignedExtension used by Polkadot.
pub type SignedExtension = SuffixedCommonSignedExtension<PrevalidateAttests>;
/// Name of the parachains pallet in the Polkadot runtime. /// Name of the parachains pallet in the Polkadot runtime.
pub const PARAS_PALLET_NAME: &str = "Paras"; pub const PARAS_PALLET_NAME: &str = "Paras";
@@ -61,6 +61,9 @@ parameter_types! {
pub const SS58Prefix: u8 = 42; pub const SS58Prefix: u8 = 42;
} }
// The SignedExtension used by Rococo.
pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
/// Name of the parachains pallet in the Rococo runtime. /// Name of the parachains pallet in the Rococo runtime.
pub const PARAS_PALLET_NAME: &str = "Paras"; pub const PARAS_PALLET_NAME: &str = "Paras";
@@ -60,6 +60,9 @@ impl ChainWithGrandpa for Wococo {
const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = AVERAGE_HEADER_SIZE_IN_JUSTIFICATION; const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = AVERAGE_HEADER_SIZE_IN_JUSTIFICATION;
} }
// The SignedExtension used by Wococo.
pub use bp_rococo::CommonSignedExtension as SignedExtension;
/// Name of the With-Wococo GRANDPA pallet instance that is deployed at bridged chains. /// Name of the With-Wococo GRANDPA pallet instance that is deployed at bridged chains.
pub const WITH_WOCOCO_GRANDPA_PALLET_NAME: &str = "BridgeWococoGrandpa"; pub const WITH_WOCOCO_GRANDPA_PALLET_NAME: &str = "BridgeWococoGrandpa";
+102 -1
View File
@@ -17,7 +17,15 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_runtime::{Chain, EncodedOrDecodedCall, StorageMapKeyProvider}; use bp_runtime::{
self,
extensions::{
ChargeTransactionPayment, CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce,
CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension,
SignedExtensionSchema,
},
Chain, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra,
};
use frame_support::{ use frame_support::{
dispatch::DispatchClass, dispatch::DispatchClass,
parameter_types, parameter_types,
@@ -272,6 +280,99 @@ impl AccountInfoStorageMapKeyProvider {
} }
} }
/// Extra signed extension data that is used by most chains.
pub type CommonSignedExtra = (
CheckNonZeroSender,
CheckSpecVersion,
CheckTxVersion,
CheckGenesis<Hash>,
CheckEra<Hash>,
CheckNonce<Nonce>,
CheckWeight,
ChargeTransactionPayment<Balance>,
);
/// Extra signed extension data that starts with `CommonSignedExtra`.
pub type SuffixedCommonSignedExtension<Suffix> =
GenericSignedExtension<(CommonSignedExtra, Suffix)>;
/// Helper trait to define some extra methods on `SuffixedCommonSignedExtension`.
pub trait SuffixedCommonSignedExtensionExt<Suffix: SignedExtensionSchema> {
/// Create signed extension from its components.
fn from_params(
spec_version: u32,
transaction_version: u32,
era: TransactionEra<BlockNumber, Hash>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
extra: (Suffix::Payload, Suffix::AdditionalSigned),
) -> Self;
/// Return transaction nonce.
fn nonce(&self) -> Nonce;
/// Return transaction tip.
fn tip(&self) -> Balance;
}
impl<Suffix> SuffixedCommonSignedExtensionExt<Suffix> for SuffixedCommonSignedExtension<Suffix>
where
Suffix: SignedExtensionSchema,
{
fn from_params(
spec_version: u32,
transaction_version: u32,
era: TransactionEra<BlockNumber, Hash>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
extra: (Suffix::Payload, Suffix::AdditionalSigned),
) -> Self {
GenericSignedExtension::new(
(
(
(), // non-zero sender
(), // spec version
(), // tx version
(), // genesis
era.frame_era(), // era
nonce.into(), // nonce (compact encoding)
(), // Check weight
tip.into(), // transaction payment / tip (compact encoding)
),
extra.0,
),
Some((
(
(),
spec_version,
transaction_version,
genesis_hash,
era.signed_payload(genesis_hash),
(),
(),
(),
),
extra.1,
)),
)
}
fn nonce(&self) -> Nonce {
let common_payload = self.payload.0;
common_payload.5 .0
}
fn tip(&self) -> Balance {
let common_payload = self.payload.0;
common_payload.7 .0
}
}
/// Signed extension that is used by most chains.
pub type CommonSignedExtension = SuffixedCommonSignedExtension<()>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
+10 -2
View File
@@ -35,7 +35,12 @@ pub trait SignedExtensionSchema: Encode + Decode + Debug + Eq + Clone + StaticTy
type AdditionalSigned: Encode + Debug + Eq + Clone + StaticTypeInfo; type AdditionalSigned: Encode + Debug + Eq + Clone + StaticTypeInfo;
} }
// An implementation of `SignedExtensionSchema` using generic params. impl SignedExtensionSchema for () {
type Payload = ();
type AdditionalSigned = ();
}
/// An implementation of `SignedExtensionSchema` using generic params.
#[derive(Encode, Decode, Clone, Debug, PartialEq, Eq, TypeInfo)] #[derive(Encode, Decode, Clone, Debug, PartialEq, Eq, TypeInfo)]
pub struct GenericSignedExtensionSchema<P, S>(PhantomData<(P, S)>); pub struct GenericSignedExtensionSchema<P, S>(PhantomData<(P, S)>);
@@ -72,6 +77,9 @@ pub type CheckWeight = GenericSignedExtensionSchema<(), ()>;
/// The `SignedExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`. /// The `SignedExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`.
pub type ChargeTransactionPayment<Balance> = GenericSignedExtensionSchema<Compact<Balance>, ()>; pub type ChargeTransactionPayment<Balance> = GenericSignedExtensionSchema<Compact<Balance>, ()>;
/// The `SignedExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`.
pub type PrevalidateAttests = GenericSignedExtensionSchema<(), ()>;
/// The `SignedExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`. /// The `SignedExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`.
pub type BridgeRejectObsoleteHeadersAndMessages = GenericSignedExtensionSchema<(), ()>; pub type BridgeRejectObsoleteHeadersAndMessages = GenericSignedExtensionSchema<(), ()>;
@@ -99,7 +107,7 @@ pub struct GenericSignedExtension<S: SignedExtensionSchema> {
// It may be set to `None` if extensions are decoded. We are never reconstructing transactions // It may be set to `None` if extensions are decoded. We are never reconstructing transactions
// (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to // (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to
// read fields of the `payload`. And when resigning transaction, we're reconstructing // read fields of the `payload`. And when resigning transaction, we're reconstructing
// `SignedExtensions` from the scratch. // `SignedExtensions` from scratch.
additional_signed: Option<S::AdditionalSigned>, additional_signed: Option<S::AdditionalSigned>,
} }
@@ -16,11 +16,14 @@
//! Kusama-to-BridgeHubPolkadot headers sync entrypoint. //! Kusama-to-BridgeHubPolkadot headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait; use async_trait::async_trait;
use relay_substrate_client::{AccountKeyPairOf, Client}; use relay_substrate_client::{AccountKeyPairOf, Client};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline, finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
TransactionParams, TransactionParams,
@@ -32,11 +35,18 @@ pub struct KusamaFinalityToBridgeHubPolkadot;
substrate_relay_helper::generate_submit_finality_proof_call_builder!( substrate_relay_helper::generate_submit_finality_proof_call_builder!(
KusamaFinalityToBridgeHubPolkadot, KusamaFinalityToBridgeHubPolkadot,
KusamaFinalityToBridgeHubPolkadotCallBuilder, SubmitFinalityProofCallBuilder,
relay_bridge_hub_polkadot_client::runtime::Call::BridgeKusamaGrandpa, relay_bridge_hub_polkadot_client::runtime::Call::BridgeKusamaGrandpa,
relay_bridge_hub_polkadot_client::runtime::BridgeKusamaGrandpaCall::submit_finality_proof relay_bridge_hub_polkadot_client::runtime::BridgeKusamaGrandpaCall::submit_finality_proof
); );
substrate_relay_helper::generate_report_equivocation_call_builder!(
KusamaFinalityToBridgeHubPolkadot,
ReportEquivocationCallBuilder,
relay_kusama_client::RuntimeCall::Grandpa,
relay_kusama_client::GrandpaCall::report_equivocation
);
#[async_trait] #[async_trait]
impl SubstrateFinalityPipeline for KusamaFinalityToBridgeHubPolkadot { impl SubstrateFinalityPipeline for KusamaFinalityToBridgeHubPolkadot {
type SourceChain = relay_kusama_client::Kusama; type SourceChain = relay_kusama_client::Kusama;
@@ -47,7 +57,7 @@ impl SubstrateFinalityPipeline for KusamaFinalityToBridgeHubPolkadot {
#[async_trait] #[async_trait]
impl SubstrateFinalitySyncPipeline for KusamaFinalityToBridgeHubPolkadot { impl SubstrateFinalitySyncPipeline for KusamaFinalityToBridgeHubPolkadot {
type SubmitFinalityProofCallBuilder = KusamaFinalityToBridgeHubPolkadotCallBuilder; type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
async fn start_relay_guards( async fn start_relay_guards(
target_client: &Client<Self::TargetChain>, target_client: &Client<Self::TargetChain>,
@@ -64,6 +74,11 @@ impl SubstrateFinalitySyncPipeline for KusamaFinalityToBridgeHubPolkadot {
} }
} }
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for KusamaFinalityToBridgeHubPolkadot {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `Kusama` to BridgeHub `Polkadot` bridge definition. /// `Kusama` to BridgeHub `Polkadot` bridge definition.
pub struct KusamaToBridgeHubPolkadotCliBridge {} pub struct KusamaToBridgeHubPolkadotCliBridge {}
@@ -75,3 +90,7 @@ impl CliBridgeBase for KusamaToBridgeHubPolkadotCliBridge {
impl RelayToRelayHeadersCliBridge for KusamaToBridgeHubPolkadotCliBridge { impl RelayToRelayHeadersCliBridge for KusamaToBridgeHubPolkadotCliBridge {
type Finality = KusamaFinalityToBridgeHubPolkadot; type Finality = KusamaFinalityToBridgeHubPolkadot;
} }
impl RelayToRelayEquivocationDetectionCliBridge for KusamaToBridgeHubPolkadotCliBridge {
type Equivocation = KusamaFinalityToBridgeHubPolkadot;
}
@@ -16,11 +16,14 @@
//! Polkadot-to-KusamaBridgeHub headers sync entrypoint. //! Polkadot-to-KusamaBridgeHub headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait; use async_trait::async_trait;
use relay_substrate_client::{AccountKeyPairOf, Client}; use relay_substrate_client::{AccountKeyPairOf, Client};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline, finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
TransactionParams, TransactionParams,
@@ -32,11 +35,18 @@ pub struct PolkadotFinalityToBridgeHubKusama;
substrate_relay_helper::generate_submit_finality_proof_call_builder!( substrate_relay_helper::generate_submit_finality_proof_call_builder!(
PolkadotFinalityToBridgeHubKusama, PolkadotFinalityToBridgeHubKusama,
PolkadotFinalityToBridgeHubKusamaCallBuilder, SubmitFinalityProofCallBuilder,
relay_bridge_hub_kusama_client::runtime::Call::BridgePolkadotGrandpa, relay_bridge_hub_kusama_client::runtime::Call::BridgePolkadotGrandpa,
relay_bridge_hub_kusama_client::runtime::BridgePolkadotGrandpaCall::submit_finality_proof relay_bridge_hub_kusama_client::runtime::BridgePolkadotGrandpaCall::submit_finality_proof
); );
substrate_relay_helper::generate_report_equivocation_call_builder!(
PolkadotFinalityToBridgeHubKusama,
ReportEquivocationCallBuilder,
relay_polkadot_client::RuntimeCall::Grandpa,
relay_polkadot_client::GrandpaCall::report_equivocation
);
#[async_trait] #[async_trait]
impl SubstrateFinalityPipeline for PolkadotFinalityToBridgeHubKusama { impl SubstrateFinalityPipeline for PolkadotFinalityToBridgeHubKusama {
type SourceChain = relay_polkadot_client::Polkadot; type SourceChain = relay_polkadot_client::Polkadot;
@@ -47,7 +57,7 @@ impl SubstrateFinalityPipeline for PolkadotFinalityToBridgeHubKusama {
#[async_trait] #[async_trait]
impl SubstrateFinalitySyncPipeline for PolkadotFinalityToBridgeHubKusama { impl SubstrateFinalitySyncPipeline for PolkadotFinalityToBridgeHubKusama {
type SubmitFinalityProofCallBuilder = PolkadotFinalityToBridgeHubKusamaCallBuilder; type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
async fn start_relay_guards( async fn start_relay_guards(
target_client: &Client<Self::TargetChain>, target_client: &Client<Self::TargetChain>,
@@ -64,6 +74,11 @@ impl SubstrateFinalitySyncPipeline for PolkadotFinalityToBridgeHubKusama {
} }
} }
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for PolkadotFinalityToBridgeHubKusama {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `Polkadot` to BridgeHub `Kusama` bridge definition. /// `Polkadot` to BridgeHub `Kusama` bridge definition.
pub struct PolkadotToBridgeHubKusamaCliBridge {} pub struct PolkadotToBridgeHubKusamaCliBridge {}
@@ -75,3 +90,7 @@ impl CliBridgeBase for PolkadotToBridgeHubKusamaCliBridge {
impl RelayToRelayHeadersCliBridge for PolkadotToBridgeHubKusamaCliBridge { impl RelayToRelayHeadersCliBridge for PolkadotToBridgeHubKusamaCliBridge {
type Finality = PolkadotFinalityToBridgeHubKusama; type Finality = PolkadotFinalityToBridgeHubKusama;
} }
impl RelayToRelayEquivocationDetectionCliBridge for PolkadotToBridgeHubKusamaCliBridge {
type Equivocation = PolkadotFinalityToBridgeHubKusama;
}
@@ -16,8 +16,14 @@
//! Millau-to-Rialto headers sync entrypoint. //! Millau-to-Rialto headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::{
DirectReportGrandpaEquivocationCallBuilder, SubstrateEquivocationDetectionPipeline,
},
finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline}, finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline},
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
}; };
@@ -41,6 +47,11 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
>; >;
} }
impl SubstrateEquivocationDetectionPipeline for MillauFinalityToRialto {
type ReportEquivocationCallBuilder =
DirectReportGrandpaEquivocationCallBuilder<Self, millau_runtime::Runtime>;
}
/// `Millau` to `Rialto` bridge definition. /// `Millau` to `Rialto` bridge definition.
pub struct MillauToRialtoCliBridge {} pub struct MillauToRialtoCliBridge {}
@@ -53,6 +64,10 @@ impl RelayToRelayHeadersCliBridge for MillauToRialtoCliBridge {
type Finality = MillauFinalityToRialto; type Finality = MillauFinalityToRialto;
} }
impl RelayToRelayEquivocationDetectionCliBridge for MillauToRialtoCliBridge {
type Equivocation = MillauFinalityToRialto;
}
impl MessagesCliBridge for MillauToRialtoCliBridge { impl MessagesCliBridge for MillauToRialtoCliBridge {
type MessagesLane = type MessagesLane =
crate::bridges::rialto_millau::millau_messages_to_rialto::MillauMessagesToRialto; crate::bridges::rialto_millau::millau_messages_to_rialto::MillauMessagesToRialto;
@@ -16,8 +16,14 @@
//! Rialto-to-Millau headers sync entrypoint. //! Rialto-to-Millau headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::{
DirectReportGrandpaEquivocationCallBuilder, SubstrateEquivocationDetectionPipeline,
},
finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline}, finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline},
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
}; };
@@ -41,6 +47,11 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
>; >;
} }
impl SubstrateEquivocationDetectionPipeline for RialtoFinalityToMillau {
type ReportEquivocationCallBuilder =
DirectReportGrandpaEquivocationCallBuilder<Self, rialto_runtime::Runtime>;
}
/// `Rialto` to `Millau` bridge definition. /// `Rialto` to `Millau` bridge definition.
pub struct RialtoToMillauCliBridge {} pub struct RialtoToMillauCliBridge {}
@@ -53,6 +64,10 @@ impl RelayToRelayHeadersCliBridge for RialtoToMillauCliBridge {
type Finality = RialtoFinalityToMillau; type Finality = RialtoFinalityToMillau;
} }
impl RelayToRelayEquivocationDetectionCliBridge for RialtoToMillauCliBridge {
type Equivocation = RialtoFinalityToMillau;
}
impl MessagesCliBridge for RialtoToMillauCliBridge { impl MessagesCliBridge for RialtoToMillauCliBridge {
type MessagesLane = type MessagesLane =
crate::bridges::rialto_millau::rialto_messages_to_millau::RialtoMessagesToMillau; crate::bridges::rialto_millau::rialto_messages_to_millau::RialtoMessagesToMillau;
@@ -34,8 +34,14 @@
//! Millau-to-RialtoParachain headers sync entrypoint. //! Millau-to-RialtoParachain headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::{
DirectReportGrandpaEquivocationCallBuilder, SubstrateEquivocationDetectionPipeline,
},
finality::SubstrateFinalitySyncPipeline, finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
}; };
@@ -62,6 +68,11 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialtoParachain {
type SubmitFinalityProofCallBuilder = MillauFinalityToRialtoParachainCallBuilder; type SubmitFinalityProofCallBuilder = MillauFinalityToRialtoParachainCallBuilder;
} }
impl SubstrateEquivocationDetectionPipeline for MillauFinalityToRialtoParachain {
type ReportEquivocationCallBuilder =
DirectReportGrandpaEquivocationCallBuilder<Self, millau_runtime::Runtime>;
}
/// `Millau` to `RialtoParachain` bridge definition. /// `Millau` to `RialtoParachain` bridge definition.
pub struct MillauToRialtoParachainCliBridge {} pub struct MillauToRialtoParachainCliBridge {}
@@ -74,6 +85,10 @@ impl RelayToRelayHeadersCliBridge for MillauToRialtoParachainCliBridge {
type Finality = MillauFinalityToRialtoParachain; type Finality = MillauFinalityToRialtoParachain;
} }
impl RelayToRelayEquivocationDetectionCliBridge for MillauToRialtoParachainCliBridge {
type Equivocation = MillauFinalityToRialtoParachain;
}
impl MessagesCliBridge for MillauToRialtoParachainCliBridge { impl MessagesCliBridge for MillauToRialtoParachainCliBridge {
type MessagesLane = type MessagesLane =
crate::bridges::rialto_parachain_millau::millau_messages_to_rialto_parachain::MillauMessagesToRialtoParachain; crate::bridges::rialto_parachain_millau::millau_messages_to_rialto_parachain::MillauMessagesToRialtoParachain;
@@ -16,11 +16,14 @@
//! Rococo-to-Wococo bridge hubs headers sync entrypoint. //! Rococo-to-Wococo bridge hubs headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait; use async_trait::async_trait;
use relay_substrate_client::{AccountKeyPairOf, Client}; use relay_substrate_client::{AccountKeyPairOf, Client};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline, finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
TransactionParams, TransactionParams,
@@ -32,11 +35,18 @@ pub struct RococoFinalityToBridgeHubWococo;
substrate_relay_helper::generate_submit_finality_proof_call_builder!( substrate_relay_helper::generate_submit_finality_proof_call_builder!(
RococoFinalityToBridgeHubWococo, RococoFinalityToBridgeHubWococo,
RococoFinalityToBridgeHubWococoCallBuilder, SubmitFinalityProofCallBuilder,
relay_bridge_hub_wococo_client::RuntimeCall::BridgeRococoGrandpa, relay_bridge_hub_wococo_client::RuntimeCall::BridgeRococoGrandpa,
relay_bridge_hub_wococo_client::BridgeGrandpaCall::submit_finality_proof relay_bridge_hub_wococo_client::BridgeGrandpaCall::submit_finality_proof
); );
substrate_relay_helper::generate_report_equivocation_call_builder!(
RococoFinalityToBridgeHubWococo,
ReportEquivocationCallBuilder,
relay_rococo_client::RuntimeCall::Grandpa,
relay_rococo_client::GrandpaCall::report_equivocation
);
#[async_trait] #[async_trait]
impl SubstrateFinalityPipeline for RococoFinalityToBridgeHubWococo { impl SubstrateFinalityPipeline for RococoFinalityToBridgeHubWococo {
type SourceChain = relay_rococo_client::Rococo; type SourceChain = relay_rococo_client::Rococo;
@@ -47,7 +57,7 @@ impl SubstrateFinalityPipeline for RococoFinalityToBridgeHubWococo {
#[async_trait] #[async_trait]
impl SubstrateFinalitySyncPipeline for RococoFinalityToBridgeHubWococo { impl SubstrateFinalitySyncPipeline for RococoFinalityToBridgeHubWococo {
type SubmitFinalityProofCallBuilder = RococoFinalityToBridgeHubWococoCallBuilder; type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
async fn start_relay_guards( async fn start_relay_guards(
target_client: &Client<Self::TargetChain>, target_client: &Client<Self::TargetChain>,
@@ -64,6 +74,11 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToBridgeHubWococo {
} }
} }
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for RococoFinalityToBridgeHubWococo {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `Rococo` to BridgeHub `Wococo` bridge definition. /// `Rococo` to BridgeHub `Wococo` bridge definition.
pub struct RococoToBridgeHubWococoCliBridge {} pub struct RococoToBridgeHubWococoCliBridge {}
@@ -75,3 +90,7 @@ impl CliBridgeBase for RococoToBridgeHubWococoCliBridge {
impl RelayToRelayHeadersCliBridge for RococoToBridgeHubWococoCliBridge { impl RelayToRelayHeadersCliBridge for RococoToBridgeHubWococoCliBridge {
type Finality = RococoFinalityToBridgeHubWococo; type Finality = RococoFinalityToBridgeHubWococo;
} }
impl RelayToRelayEquivocationDetectionCliBridge for RococoToBridgeHubWococoCliBridge {
type Equivocation = RococoFinalityToBridgeHubWococo;
}
@@ -16,11 +16,14 @@
//! Wococo-to-Rococo bridge hubs headers sync entrypoint. //! Wococo-to-Rococo bridge hubs headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge}; use crate::cli::bridge::{
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait; use async_trait::async_trait;
use relay_substrate_client::{AccountKeyPairOf, Client}; use relay_substrate_client::{AccountKeyPairOf, Client};
use substrate_relay_helper::{ use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline, finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline}, finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
TransactionParams, TransactionParams,
@@ -32,11 +35,18 @@ pub struct WococoFinalityToBridgeHubRococo;
substrate_relay_helper::generate_submit_finality_proof_call_builder!( substrate_relay_helper::generate_submit_finality_proof_call_builder!(
WococoFinalityToBridgeHubRococo, WococoFinalityToBridgeHubRococo,
WococoFinalityToBridgeHubRococoCallBuilder, SubmitFinalityProofCallBuilder,
relay_bridge_hub_rococo_client::RuntimeCall::BridgeWococoGrandpa, relay_bridge_hub_rococo_client::RuntimeCall::BridgeWococoGrandpa,
relay_bridge_hub_rococo_client::BridgeGrandpaCall::submit_finality_proof relay_bridge_hub_rococo_client::BridgeGrandpaCall::submit_finality_proof
); );
substrate_relay_helper::generate_report_equivocation_call_builder!(
WococoFinalityToBridgeHubRococo,
ReportEquivocationCallBuilder,
relay_wococo_client::RuntimeCall::Grandpa,
relay_wococo_client::GrandpaCall::report_equivocation
);
#[async_trait] #[async_trait]
impl SubstrateFinalityPipeline for WococoFinalityToBridgeHubRococo { impl SubstrateFinalityPipeline for WococoFinalityToBridgeHubRococo {
type SourceChain = relay_wococo_client::Wococo; type SourceChain = relay_wococo_client::Wococo;
@@ -47,7 +57,7 @@ impl SubstrateFinalityPipeline for WococoFinalityToBridgeHubRococo {
#[async_trait] #[async_trait]
impl SubstrateFinalitySyncPipeline for WococoFinalityToBridgeHubRococo { impl SubstrateFinalitySyncPipeline for WococoFinalityToBridgeHubRococo {
type SubmitFinalityProofCallBuilder = WococoFinalityToBridgeHubRococoCallBuilder; type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
async fn start_relay_guards( async fn start_relay_guards(
target_client: &Client<Self::TargetChain>, target_client: &Client<Self::TargetChain>,
@@ -64,6 +74,11 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToBridgeHubRococo {
} }
} }
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for WococoFinalityToBridgeHubRococo {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `Wococo` to BridgeHub `Rococo` bridge definition. /// `Wococo` to BridgeHub `Rococo` bridge definition.
pub struct WococoToBridgeHubRococoCliBridge {} pub struct WococoToBridgeHubRococoCliBridge {}
@@ -75,3 +90,7 @@ impl CliBridgeBase for WococoToBridgeHubRococoCliBridge {
impl RelayToRelayHeadersCliBridge for WococoToBridgeHubRococoCliBridge { impl RelayToRelayHeadersCliBridge for WococoToBridgeHubRococoCliBridge {
type Finality = WococoFinalityToBridgeHubRococo; type Finality = WococoFinalityToBridgeHubRococo;
} }
impl RelayToRelayEquivocationDetectionCliBridge for WococoToBridgeHubRococoCliBridge {
type Equivocation = WococoFinalityToBridgeHubRococo;
}
+27 -2
View File
@@ -19,8 +19,8 @@ use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumbe
use relay_substrate_client::{Chain, ChainWithTransactions, Parachain, RelayChain}; use relay_substrate_client::{Chain, ChainWithTransactions, Parachain, RelayChain};
use strum::{EnumString, EnumVariantNames}; use strum::{EnumString, EnumVariantNames};
use substrate_relay_helper::{ use substrate_relay_helper::{
finality::SubstrateFinalitySyncPipeline, messages_lane::SubstrateMessageLane, equivocation::SubstrateEquivocationDetectionPipeline, finality::SubstrateFinalitySyncPipeline,
parachains::SubstrateParachainsPipeline, messages_lane::SubstrateMessageLane, parachains::SubstrateParachainsPipeline,
}; };
#[derive(Debug, PartialEq, Eq, EnumString, EnumVariantNames)] #[derive(Debug, PartialEq, Eq, EnumString, EnumVariantNames)]
@@ -56,6 +56,31 @@ pub trait RelayToRelayHeadersCliBridge: CliBridgeBase {
>; >;
} }
/// Convenience trait that adds bounds to `CliBridgeBase`.
pub trait RelayToRelayEquivocationDetectionCliBridgeBase: CliBridgeBase {
type BoundedSource: ChainWithTransactions;
}
impl<T> RelayToRelayEquivocationDetectionCliBridgeBase for T
where
T: CliBridgeBase,
T::Source: ChainWithTransactions,
{
type BoundedSource = T::Source;
}
/// Bridge representation that can be used from the CLI for detecting equivocations
/// in the headers synchronized from a relay chain to a relay chain.
pub trait RelayToRelayEquivocationDetectionCliBridge:
RelayToRelayEquivocationDetectionCliBridgeBase
{
/// Equivocation detection pipeline.
type Equivocation: SubstrateEquivocationDetectionPipeline<
SourceChain = Self::Source,
TargetChain = Self::Target,
>;
}
/// Bridge representation that can be used from the CLI for relaying headers /// Bridge representation that can be used from the CLI for relaying headers
/// from a parachain to a relay chain. /// from a parachain to a relay chain.
pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase
@@ -0,0 +1,113 @@
// 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/>.
use crate::{
bridges::{
kusama_polkadot::{
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
},
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rococo_wococo::{
rococo_headers_to_bridge_hub_wococo::RococoToBridgeHubWococoCliBridge,
wococo_headers_to_bridge_hub_rococo::WococoToBridgeHubRococoCliBridge,
},
},
cli::{bridge::*, chain_schema::*, PrometheusParams},
};
use async_trait::async_trait;
use relay_substrate_client::ChainWithTransactions;
use structopt::StructOpt;
use strum::{EnumString, EnumVariantNames, VariantNames};
use substrate_relay_helper::equivocation;
/// Start equivocation detection loop.
#[derive(StructOpt)]
pub struct DetectEquivocations {
#[structopt(possible_values = DetectEquivocationsBridge::VARIANTS, case_insensitive = true)]
bridge: DetectEquivocationsBridge,
#[structopt(flatten)]
source: SourceConnectionParams,
#[structopt(flatten)]
source_sign: SourceSigningParams,
#[structopt(flatten)]
target: TargetConnectionParams,
#[structopt(flatten)]
prometheus_params: PrometheusParams,
}
#[derive(Debug, EnumString, EnumVariantNames)]
#[strum(serialize_all = "kebab_case")]
/// Equivocations detection bridge.
pub enum DetectEquivocationsBridge {
MillauToRialto,
RialtoToMillau,
MillauToRialtoParachain,
RococoToBridgeHubWococo,
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
PolkadotToBridgeHubKusama,
}
#[async_trait]
trait EquivocationsDetector: RelayToRelayEquivocationDetectionCliBridge
where
Self::Source: ChainWithTransactions,
{
async fn start(data: DetectEquivocations) -> anyhow::Result<()> {
equivocation::run::<Self::Equivocation>(
data.source.into_client::<Self::Source>().await?,
data.target.into_client::<Self::Target>().await?,
data.source_sign.transaction_params::<Self::Source>()?,
data.prometheus_params.into_metrics_params()?,
)
.await
}
}
impl EquivocationsDetector for MillauToRialtoCliBridge {}
impl EquivocationsDetector for RialtoToMillauCliBridge {}
impl EquivocationsDetector for MillauToRialtoParachainCliBridge {}
impl EquivocationsDetector for RococoToBridgeHubWococoCliBridge {}
impl EquivocationsDetector for WococoToBridgeHubRococoCliBridge {}
impl EquivocationsDetector for KusamaToBridgeHubPolkadotCliBridge {}
impl EquivocationsDetector for PolkadotToBridgeHubKusamaCliBridge {}
impl DetectEquivocations {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
DetectEquivocationsBridge::MillauToRialto => MillauToRialtoCliBridge::start(self),
DetectEquivocationsBridge::RialtoToMillau => RialtoToMillauCliBridge::start(self),
DetectEquivocationsBridge::MillauToRialtoParachain =>
MillauToRialtoParachainCliBridge::start(self),
DetectEquivocationsBridge::RococoToBridgeHubWococo =>
RococoToBridgeHubWococoCliBridge::start(self),
DetectEquivocationsBridge::WococoToBridgeHubRococo =>
WococoToBridgeHubRococoCliBridge::start(self),
DetectEquivocationsBridge::KusamaToBridgeHubPolkadot =>
KusamaToBridgeHubPolkadotCliBridge::start(self),
DetectEquivocationsBridge::PolkadotToBridgeHubKusama =>
PolkadotToBridgeHubKusamaCliBridge::start(self),
}
.await
}
}
+8 -1
View File
@@ -35,6 +35,7 @@ pub(crate) mod encode_message;
pub(crate) mod send_message; pub(crate) mod send_message;
mod chain_schema; mod chain_schema;
mod detect_equivocations;
mod init_bridge; mod init_bridge;
mod register_parachain; mod register_parachain;
mod relay_headers; mod relay_headers;
@@ -86,8 +87,13 @@ pub enum Command {
ResubmitTransactions(resubmit_transactions::ResubmitTransactions), ResubmitTransactions(resubmit_transactions::ResubmitTransactions),
/// Register parachain. /// Register parachain.
RegisterParachain(register_parachain::RegisterParachain), RegisterParachain(register_parachain::RegisterParachain),
/// /// Relay parachain heads.
RelayParachains(relay_parachains::RelayParachains), RelayParachains(relay_parachains::RelayParachains),
/// Detect and report equivocations.
///
/// Parses the source chain headers that were synchronized with the target chain looking for
/// equivocations. If any equivocation is found, it is reported to the source chain.
DetectEquivocations(detect_equivocations::DetectEquivocations),
} }
impl Command { impl Command {
@@ -119,6 +125,7 @@ impl Command {
Self::ResubmitTransactions(arg) => arg.run().await?, Self::ResubmitTransactions(arg) => arg.run().await?,
Self::RegisterParachain(arg) => arg.run().await?, Self::RegisterParachain(arg) => arg.run().await?,
Self::RelayParachains(arg) => arg.run().await?, Self::RelayParachains(arg) => arg.run().await?,
Self::DetectEquivocations(arg) => arg.run().await?,
} }
Ok(()) Ok(())
} }
@@ -131,10 +131,8 @@ impl<Left: ChainWithTransactions + CliChain, Right: ChainWithTransactions + CliC
pub struct BridgeEndCommonParams<Chain: ChainWithTransactions + CliChain> { pub struct BridgeEndCommonParams<Chain: ChainWithTransactions + CliChain> {
/// Chain client. /// Chain client.
pub client: Client<Chain>, pub client: Client<Chain>,
/// Transactions signer. /// Params used for sending transactions to the chain.
pub sign: AccountKeyPairOf<Chain>, pub tx_params: TransactionParams<AccountKeyPairOf<Chain>>,
/// Transactions mortality.
pub transactions_mortality: Option<u32>,
/// Accounts, which balances are exposed as metrics by the relay process. /// Accounts, which balances are exposed as metrics by the relay process.
pub accounts: Vec<TaggedAccount<AccountIdOf<Chain>>>, pub accounts: Vec<TaggedAccount<AccountIdOf<Chain>>>,
} }
@@ -181,15 +179,9 @@ where
) -> MessagesRelayParams<Bridge::MessagesLane> { ) -> MessagesRelayParams<Bridge::MessagesLane> {
MessagesRelayParams { MessagesRelayParams {
source_client: self.source.client.clone(), source_client: self.source.client.clone(),
source_transaction_params: TransactionParams { source_transaction_params: self.source.tx_params.clone(),
signer: self.source.sign.clone(),
mortality: self.source.transactions_mortality,
},
target_client: self.target.client.clone(), target_client: self.target.client.clone(),
target_transaction_params: TransactionParams { target_transaction_params: self.target.tx_params.clone(),
signer: self.target.sign.clone(),
mortality: self.target.transactions_mortality,
},
source_to_target_headers_relay: Some(source_to_target_headers_relay), source_to_target_headers_relay: Some(source_to_target_headers_relay),
target_to_source_headers_relay: Some(target_to_source_headers_relay), target_to_source_headers_relay: Some(target_to_source_headers_relay),
lane_id, lane_id,
@@ -328,11 +320,11 @@ where
{ {
let common = self.mut_base().mut_common(); let common = self.mut_base().mut_common();
common.left.accounts.push(TaggedAccount::Messages { common.left.accounts.push(TaggedAccount::Messages {
id: common.left.sign.public().into(), id: common.left.tx_params.signer.public().into(),
bridged_chain: Self::Right::NAME.to_string(), bridged_chain: Self::Right::NAME.to_string(),
}); });
common.right.accounts.push(TaggedAccount::Messages { common.right.accounts.push(TaggedAccount::Messages {
id: common.right.sign.public().into(), id: common.right.tx_params.signer.public().into(),
bridged_chain: Self::Left::NAME.to_string(), bridged_chain: Self::Left::NAME.to_string(),
}); });
} }
@@ -58,13 +58,13 @@ pub struct ParachainToParachainBridge<
/// Override for right_relay->left headers signer. /// Override for right_relay->left headers signer.
pub right_headers_to_left_transaction_params: pub right_headers_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>, TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for left_relay->right headers signer.
pub left_headers_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
/// Override for right->left parachains signer. /// Override for right->left parachains signer.
pub right_parachains_to_left_transaction_params: pub right_parachains_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>, TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for left_relay->right headers signer.
pub left_headers_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
/// Override for left->right parachains signer. /// Override for left->right parachains signer.
pub left_parachains_to_right_transaction_params: pub left_parachains_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>, TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
@@ -83,35 +83,33 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
#[structopt(flatten)] #[structopt(flatten)]
left: [<$left_parachain ConnectionParams>], left: [<$left_parachain ConnectionParams>],
#[structopt(flatten)]
left_relay: [<$left_chain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the left chain // default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)] #[structopt(flatten)]
left_sign: [<$left_parachain SigningParams>], left_sign: [<$left_parachain SigningParams>],
#[structopt(flatten)]
right: [<$right_parachain ConnectionParams>],
#[structopt(flatten)]
right_relay: [<$right_chain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)]
right_sign: [<$right_parachain SigningParams>],
// override for right_relay->left-parachain headers signer // override for right_relay->left-parachain headers signer
#[structopt(flatten)] #[structopt(flatten)]
right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_parachain SigningParams>], right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_parachain SigningParams>],
// override for left_relay->right-parachain headers signer
#[structopt(flatten)]
left_relay_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>],
// override for right->left parachains signer // override for right->left parachains signer
#[structopt(flatten)] #[structopt(flatten)]
right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_parachain SigningParams>], right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_parachain SigningParams>],
#[structopt(flatten)]
left_relay: [<$left_chain ConnectionParams>],
#[structopt(flatten)]
right: [<$right_parachain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)]
right_sign: [<$right_parachain SigningParams>],
// override for left_relay->right-parachain headers signer
#[structopt(flatten)]
left_relay_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>],
// override for left->right parachains signer // override for left->right parachains signer
#[structopt(flatten)] #[structopt(flatten)]
left_parachains_to_right_sign_override: [<$left_chain ParachainsTo $right_parachain SigningParams>], left_parachains_to_right_sign_override: [<$left_chain ParachainsTo $right_parachain SigningParams>],
#[structopt(flatten)]
right_relay: [<$right_chain ConnectionParams>],
} }
impl [<$left_parachain $right_parachain HeadersAndMessages>] { impl [<$left_parachain $right_parachain HeadersAndMessages>] {
@@ -134,14 +132,12 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
self.shared, self.shared,
BridgeEndCommonParams { BridgeEndCommonParams {
client: self.left.into_client::<Left>().await?, client: self.left.into_client::<Left>().await?,
sign: self.left_sign.to_keypair::<Left>()?, tx_params: self.left_sign.transaction_params::<Left>()?,
transactions_mortality: self.left_sign.transactions_mortality()?,
accounts: vec![], accounts: vec![],
}, },
BridgeEndCommonParams { BridgeEndCommonParams {
client: self.right.into_client::<Right>().await?, client: self.right.into_client::<Right>().await?,
sign: self.right_sign.to_keypair::<Right>()?, tx_params: self.right_sign.transaction_params::<Right>()?,
transactions_mortality: self.right_sign.transactions_mortality()?,
accounts: vec![], accounts: vec![],
}, },
)?, )?,
@@ -61,6 +61,7 @@ pub struct RelayToParachainBridge<
/// Override for right->left parachains signer. /// Override for right->left parachains signer.
pub right_parachains_to_left_transaction_params: pub right_parachains_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>, TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for left->right headers signer. /// Override for left->right headers signer.
pub left_headers_to_right_transaction_params: pub left_headers_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>, TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
@@ -79,30 +80,27 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
#[structopt(flatten)] #[structopt(flatten)]
left: [<$left_chain ConnectionParams>], left: [<$left_chain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the left chain // default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)] #[structopt(flatten)]
left_sign: [<$left_chain SigningParams>], left_sign: [<$left_chain SigningParams>],
#[structopt(flatten)]
right: [<$right_parachain ConnectionParams>],
#[structopt(flatten)]
right_relay: [<$right_chain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)]
right_sign: [<$right_parachain SigningParams>],
// override for right_relay->left headers signer // override for right_relay->left headers signer
#[structopt(flatten)] #[structopt(flatten)]
right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>], right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>],
// override for right->left parachains signer
#[structopt(flatten)]
right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_chain SigningParams>],
#[structopt(flatten)]
right: [<$right_parachain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)]
right_sign: [<$right_parachain SigningParams>],
// override for left->right headers signer // override for left->right headers signer
#[structopt(flatten)] #[structopt(flatten)]
left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>], left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>],
// override for right->left parachains signer
#[structopt(flatten)] #[structopt(flatten)]
right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_chain SigningParams>], right_relay: [<$right_chain ConnectionParams>],
} }
impl [<$left_chain $right_parachain HeadersAndMessages>] { impl [<$left_chain $right_parachain HeadersAndMessages>] {
@@ -122,14 +120,12 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
self.shared, self.shared,
BridgeEndCommonParams { BridgeEndCommonParams {
client: self.left.into_client::<Left>().await?, client: self.left.into_client::<Left>().await?,
sign: self.left_sign.to_keypair::<Left>()?, tx_params: self.left_sign.transaction_params::<Left>()?,
transactions_mortality: self.left_sign.transactions_mortality()?,
accounts: vec![], accounts: vec![],
}, },
BridgeEndCommonParams { BridgeEndCommonParams {
client: self.right.into_client::<Right>().await?, client: self.right.into_client::<Right>().await?,
sign: self.right_sign.to_keypair::<Right>()?, tx_params: self.right_sign.transaction_params::<Right>()?,
transactions_mortality: self.right_sign.transactions_mortality()?,
accounts: vec![], accounts: vec![],
}, },
)?, )?,
@@ -56,22 +56,24 @@ macro_rules! declare_relay_to_relay_bridge_schema {
pub struct [<$left_chain $right_chain HeadersAndMessages>] { pub struct [<$left_chain $right_chain HeadersAndMessages>] {
#[structopt(flatten)] #[structopt(flatten)]
shared: HeadersAndMessagesSharedParams, shared: HeadersAndMessagesSharedParams,
// default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)] #[structopt(flatten)]
left: [<$left_chain ConnectionParams>], left: [<$left_chain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)]
left_sign: [<$left_chain SigningParams>],
// override for right->left headers signer // override for right->left headers signer
#[structopt(flatten)] #[structopt(flatten)]
right_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>], right_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>],
#[structopt(flatten)]
left_sign: [<$left_chain SigningParams>],
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)] #[structopt(flatten)]
right: [<$right_chain ConnectionParams>], right: [<$right_chain ConnectionParams>],
#[structopt(flatten)]
// default signer, which is always used to sign messages relay transactions on the right chain
right_sign: [<$right_chain SigningParams>],
// override for left->right headers signer // override for left->right headers signer
#[structopt(flatten)] #[structopt(flatten)]
left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_chain SigningParams>], left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_chain SigningParams>],
#[structopt(flatten)]
right_sign: [<$right_chain SigningParams>],
} }
impl [<$left_chain $right_chain HeadersAndMessages>] { impl [<$left_chain $right_chain HeadersAndMessages>] {
@@ -88,14 +90,12 @@ macro_rules! declare_relay_to_relay_bridge_schema {
self.shared, self.shared,
BridgeEndCommonParams { BridgeEndCommonParams {
client: self.left.into_client::<Left>().await?, client: self.left.into_client::<Left>().await?,
sign: self.left_sign.to_keypair::<Left>()?, tx_params: self.left_sign.transaction_params::<Left>()?,
transactions_mortality: self.left_sign.transactions_mortality()?,
accounts: vec![], accounts: vec![],
}, },
BridgeEndCommonParams { BridgeEndCommonParams {
client: self.right.into_client::<Right>().await?, client: self.right.into_client::<Right>().await?,
sign: self.right_sign.to_keypair::<Right>()?, tx_params: self.right_sign.transaction_params::<Right>()?,
transactions_mortality: self.right_sign.transactions_mortality()?,
accounts: vec![], accounts: vec![],
}, },
)?, )?,
@@ -16,8 +16,9 @@
//! Types used to connect to the BridgeHub-Kusama-Substrate parachain. //! Types used to connect to the BridgeHub-Kusama-Substrate parachain.
use bp_bridge_hub_kusama::{BridgeHubSignedExtension, AVERAGE_BLOCK_INTERVAL}; use bp_bridge_hub_kusama::AVERAGE_BLOCK_INTERVAL;
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_polkadot::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode; use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
@@ -79,6 +80,7 @@ impl ChainWithTransactions for BridgeHubKusama {
param.genesis_hash, param.genesis_hash,
unsigned.nonce, unsigned.nonce,
unsigned.tip, unsigned.tip,
(((), ()), ((), ())),
), ),
)?; )?;
@@ -17,6 +17,7 @@ bp-bridge-hub-polkadot = { path = "../../primitives/chain-bridge-hub-polkadot" }
bp-header-chain = { path = "../../primitives/header-chain" } bp-header-chain = { path = "../../primitives/header-chain" }
bp-messages = { path = "../../primitives/messages" } bp-messages = { path = "../../primitives/messages" }
bp-parachains = { path = "../../primitives/parachains" } bp-parachains = { path = "../../primitives/parachains" }
bp-polkadot-core= { path = "../../primitives/polkadot-core" }
bp-kusama = { path = "../../primitives/chain-kusama" } bp-kusama = { path = "../../primitives/chain-kusama" }
bp-runtime = { path = "../../primitives/runtime" } bp-runtime = { path = "../../primitives/runtime" }
@@ -16,8 +16,9 @@
//! Types used to connect to the BridgeHub-Polkadot-Substrate parachain. //! Types used to connect to the BridgeHub-Polkadot-Substrate parachain.
use bp_bridge_hub_polkadot::{BridgeHubSignedExtension, AVERAGE_BLOCK_INTERVAL}; use bp_bridge_hub_polkadot::AVERAGE_BLOCK_INTERVAL;
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode; use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
@@ -79,6 +80,7 @@ impl ChainWithTransactions for BridgeHubPolkadot {
param.genesis_hash, param.genesis_hash,
unsigned.nonce, unsigned.nonce,
unsigned.tip, unsigned.tip,
(((), ()), ((), ())),
), ),
)?; )?;
@@ -18,8 +18,9 @@
pub mod codegen_runtime; pub mod codegen_runtime;
use bp_bridge_hub_rococo::{BridgeHubSignedExtension, SignedExtension, AVERAGE_BLOCK_INTERVAL}; use bp_bridge_hub_rococo::{SignedExtension, AVERAGE_BLOCK_INTERVAL};
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode; use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
@@ -95,6 +96,7 @@ impl ChainWithTransactions for BridgeHubRococo {
param.genesis_hash, param.genesis_hash,
unsigned.nonce, unsigned.nonce,
unsigned.tip, unsigned.tip,
(((), ()), ((), ())),
), ),
)?; )?;
@@ -16,8 +16,9 @@
//! Types used to connect to the BridgeHub-Wococo-Substrate parachain. //! Types used to connect to the BridgeHub-Wococo-Substrate parachain.
use bp_bridge_hub_wococo::{BridgeHubSignedExtension, SignedExtension, AVERAGE_BLOCK_INTERVAL}; use bp_bridge_hub_wococo::{SignedExtension, AVERAGE_BLOCK_INTERVAL};
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode; use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
@@ -84,6 +85,7 @@ impl ChainWithTransactions for BridgeHubWococo {
param.genesis_hash, param.genesis_hash,
unsigned.nonce, unsigned.nonce,
unsigned.tip, unsigned.tip,
(((), ()), ((), ())),
), ),
)?; )?;
+10 -2
View File
@@ -6,15 +6,23 @@ edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0" license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies] [dependencies]
relay-substrate-client = { path = "../client-substrate" } codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] }
relay-utils = { path = "../utils" } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] }
subxt = { version = "0.31.0", default-features = false, features = ["native"] }
# Bridge dependencies # Bridge dependencies
bp-kusama = { path = "../../primitives/chain-kusama" } bp-kusama = { path = "../../primitives/chain-kusama" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-runtime = { path = "../../primitives/runtime" } bp-runtime = { path = "../../primitives/runtime" }
relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
# Substrate Dependencies # Substrate Dependencies
sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { 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" } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master" }
File diff suppressed because it is too large Load Diff
+69 -3
View File
@@ -16,21 +16,36 @@
//! Types used to connect to the Kusama chain. //! Types used to connect to the Kusama chain.
pub mod codegen_runtime;
use bp_kusama::{AccountInfoStorageMapKeyProvider, KUSAMA_SYNCED_HEADERS_GRANDPA_INFO_METHOD}; use bp_kusama::{AccountInfoStorageMapKeyProvider, KUSAMA_SYNCED_HEADERS_GRANDPA_INFO_METHOD};
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
}; };
use sp_core::storage::StorageKey; use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
use sp_session::MembershipProof; use sp_session::MembershipProof;
use std::time::Duration; use std::time::Duration;
pub use codegen_runtime::api::runtime_types;
pub type RuntimeCall = runtime_types::kusama_runtime::RuntimeCall;
pub type GrandpaCall = runtime_types::pallet_grandpa::pallet::Call;
/// Kusama header id. /// Kusama header id.
pub type HeaderId = relay_utils::HeaderId<bp_kusama::Hash, bp_kusama::BlockNumber>; pub type HeaderId = relay_utils::HeaderId<bp_kusama::Hash, bp_kusama::BlockNumber>;
/// Kusama header type used in headers sync. /// Kusama header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_kusama::Header>; pub type SyncHeader = relay_substrate_client::SyncHeader<bp_kusama::Header>;
/// The address format for describing accounts.
pub type Address = MultiAddress<bp_kusama::AccountId, ()>;
/// Kusama chain definition /// Kusama chain definition
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Kusama; pub struct Kusama;
@@ -47,7 +62,7 @@ impl Chain for Kusama {
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_kusama::SignedBlock; type SignedBlock = bp_kusama::SignedBlock;
type Call = (); type Call = RuntimeCall;
} }
impl ChainWithGrandpa for Kusama { impl ChainWithGrandpa for Kusama {
@@ -67,3 +82,54 @@ impl RelayChain for Kusama {
const PARAS_PALLET_NAME: &'static str = bp_kusama::PARAS_PALLET_NAME; const PARAS_PALLET_NAME: &'static str = bp_kusama::PARAS_PALLET_NAME;
const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgeKusamaParachain"; const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgeKusamaParachain";
} }
impl ChainWithTransactions for Kusama {
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction =
bp_polkadot_core::UncheckedExtrinsic<Self::Call, bp_kusama::SignedExtension>;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
let raw_payload = SignedPayload::new(
unsigned.call,
bp_kusama::SignedExtension::from_params(
param.spec_version,
param.transaction_version,
unsigned.era,
param.genesis_hash,
unsigned.nonce,
unsigned.tip,
((), ()),
),
)?;
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
let signer: sp_runtime::MultiSigner = param.signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
Ok(Self::SignedTransaction::new_signed(
call,
signer.into_account().into(),
signature.into(),
extra,
))
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
tx.signature.is_some()
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
.map(|(address, _, _)| *address == Address::Id(signer.public().into()))
.unwrap_or(false)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
let extra = &tx.signature.as_ref()?.2;
Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip()))
}
}
+2 -3
View File
@@ -25,9 +25,8 @@ use relay_substrate_client::{
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError, ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
FullRuntimeUtilityPallet, NonceOf, SignParam, UnderlyingChainProvider, UnsignedTransaction, FullRuntimeUtilityPallet, NonceOf, SignParam, UnderlyingChainProvider, UnsignedTransaction,
}; };
use sp_core::{storage::StorageKey, Pair}; use sp_core::{storage::StorageKey, Pair, Void};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
use sp_session::MembershipProof;
use std::time::Duration; use std::time::Duration;
/// Millau header id. /// Millau header id.
@@ -71,7 +70,7 @@ impl ChainWithGrandpa for Millau {
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
MILLAU_SYNCED_HEADERS_GRANDPA_INFO_METHOD; MILLAU_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
type KeyOwnerProof = MembershipProof; type KeyOwnerProof = Void;
} }
impl ChainWithBalances for Millau { impl ChainWithBalances for Millau {
+10 -2
View File
@@ -6,15 +6,23 @@ edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0" license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies] [dependencies]
relay-substrate-client = { path = "../client-substrate" } codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] }
relay-utils = { path = "../utils" } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] }
subxt = { version = "0.31.0", default-features = false, features = ["native"] }
# Bridge dependencies # Bridge dependencies
bp-polkadot = { path = "../../primitives/chain-polkadot" } bp-polkadot = { path = "../../primitives/chain-polkadot" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-runtime = { path = "../../primitives/runtime" } bp-runtime = { path = "../../primitives/runtime" }
relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
# Substrate Dependencies # Substrate Dependencies
sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { 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" } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master" }
File diff suppressed because it is too large Load Diff
+69 -3
View File
@@ -16,21 +16,36 @@
//! Types used to connect to the Polkadot chain. //! Types used to connect to the Polkadot chain.
mod codegen_runtime;
use bp_polkadot::{AccountInfoStorageMapKeyProvider, POLKADOT_SYNCED_HEADERS_GRANDPA_INFO_METHOD}; use bp_polkadot::{AccountInfoStorageMapKeyProvider, POLKADOT_SYNCED_HEADERS_GRANDPA_INFO_METHOD};
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
}; };
use sp_core::storage::StorageKey; use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
use sp_session::MembershipProof; use sp_session::MembershipProof;
use std::time::Duration; use std::time::Duration;
pub use codegen_runtime::api::runtime_types;
pub type RuntimeCall = runtime_types::polkadot_runtime::RuntimeCall;
pub type GrandpaCall = runtime_types::pallet_grandpa::pallet::Call;
/// Polkadot header id. /// Polkadot header id.
pub type HeaderId = relay_utils::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockNumber>; pub type HeaderId = relay_utils::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockNumber>;
/// Polkadot header type used in headers sync. /// Polkadot header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_polkadot::Header>; pub type SyncHeader = relay_substrate_client::SyncHeader<bp_polkadot::Header>;
/// The address format for describing accounts.
pub type Address = MultiAddress<bp_polkadot::AccountId, ()>;
/// Polkadot chain definition /// Polkadot chain definition
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Polkadot; pub struct Polkadot;
@@ -47,7 +62,7 @@ impl Chain for Polkadot {
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_polkadot::SignedBlock; type SignedBlock = bp_polkadot::SignedBlock;
type Call = (); type Call = RuntimeCall;
} }
impl ChainWithGrandpa for Polkadot { impl ChainWithGrandpa for Polkadot {
@@ -67,3 +82,54 @@ impl RelayChain for Polkadot {
const PARAS_PALLET_NAME: &'static str = bp_polkadot::PARAS_PALLET_NAME; const PARAS_PALLET_NAME: &'static str = bp_polkadot::PARAS_PALLET_NAME;
const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgePolkadotParachain"; const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgePolkadotParachain";
} }
impl ChainWithTransactions for Polkadot {
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction =
bp_polkadot_core::UncheckedExtrinsic<Self::Call, bp_polkadot::SignedExtension>;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
let raw_payload = SignedPayload::new(
unsigned.call,
bp_polkadot::SignedExtension::from_params(
param.spec_version,
param.transaction_version,
unsigned.era,
param.genesis_hash,
unsigned.nonce,
unsigned.tip,
((), ()),
),
)?;
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
let signer: sp_runtime::MultiSigner = param.signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
Ok(Self::SignedTransaction::new_signed(
call,
signer.into_account().into(),
signature.into(),
extra,
))
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
tx.signature.is_some()
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
.map(|(address, _, _)| *address == Address::Id(signer.public().into()))
.unwrap_or(false)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
let extra = &tx.signature.as_ref()?.2;
Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip()))
}
}
@@ -18,8 +18,8 @@
pub mod codegen_runtime; pub mod codegen_runtime;
use bp_bridge_hub_cumulus::BridgeHubSignedExtension;
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode; use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
@@ -98,6 +98,7 @@ impl ChainWithTransactions for RialtoParachain {
param.genesis_hash, param.genesis_hash,
unsigned.nonce, unsigned.nonce,
unsigned.tip, unsigned.tip,
(((), ()), ((), ())),
), ),
)?; )?;
+2 -3
View File
@@ -25,9 +25,8 @@ use relay_substrate_client::{
ChainWithTransactions, Error as SubstrateError, NonceOf, RelayChain, SignParam, ChainWithTransactions, Error as SubstrateError, NonceOf, RelayChain, SignParam,
UnderlyingChainProvider, UnsignedTransaction, UnderlyingChainProvider, UnsignedTransaction,
}; };
use sp_core::{storage::StorageKey, Pair}; use sp_core::{storage::StorageKey, Pair, Void};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
use sp_session::MembershipProof;
use std::time::Duration; use std::time::Duration;
/// Rialto header id. /// Rialto header id.
@@ -56,7 +55,7 @@ impl ChainWithGrandpa for Rialto {
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str = const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
RIALTO_SYNCED_HEADERS_GRANDPA_INFO_METHOD; RIALTO_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
type KeyOwnerProof = MembershipProof; type KeyOwnerProof = Void;
} }
impl RelayChain for Rialto { impl RelayChain for Rialto {
+10 -2
View File
@@ -6,15 +6,23 @@ edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0" license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies] [dependencies]
relay-substrate-client = { path = "../client-substrate" } codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] }
relay-utils = { path = "../utils" } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] }
subxt = { version = "0.31.0", default-features = false, features = ["native"] }
# Bridge dependencies # Bridge dependencies
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-rococo = { path = "../../primitives/chain-rococo" } bp-rococo = { path = "../../primitives/chain-rococo" }
bp-runtime = { path = "../../primitives/runtime" } bp-runtime = { path = "../../primitives/runtime" }
relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
# Substrate Dependencies # Substrate Dependencies
sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { 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" } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master" }
File diff suppressed because it is too large Load Diff
+69 -3
View File
@@ -16,21 +16,36 @@
//! Types used to connect to the Rococo-Substrate chain. //! Types used to connect to the Rococo-Substrate chain.
pub mod codegen_runtime;
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_rococo::ROCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD; use bp_rococo::ROCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
}; };
use sp_core::storage::StorageKey; use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
use sp_session::MembershipProof; use sp_session::MembershipProof;
use std::time::Duration; use std::time::Duration;
pub use codegen_runtime::api::runtime_types;
pub type RuntimeCall = runtime_types::rococo_runtime::RuntimeCall;
pub type GrandpaCall = runtime_types::pallet_grandpa::pallet::Call;
/// Rococo header id. /// Rococo header id.
pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>; pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>;
/// Rococo header type used in headers sync. /// Rococo header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_rococo::Header>; pub type SyncHeader = relay_substrate_client::SyncHeader<bp_rococo::Header>;
/// The address format for describing accounts.
pub type Address = MultiAddress<bp_rococo::AccountId, ()>;
/// Rococo chain definition /// Rococo chain definition
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Rococo; pub struct Rococo;
@@ -47,7 +62,7 @@ impl Chain for Rococo {
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_rococo::SignedBlock; type SignedBlock = bp_rococo::SignedBlock;
type Call = (); type Call = RuntimeCall;
} }
impl ChainWithGrandpa for Rococo { impl ChainWithGrandpa for Rococo {
@@ -67,3 +82,54 @@ impl RelayChain for Rococo {
const PARAS_PALLET_NAME: &'static str = bp_rococo::PARAS_PALLET_NAME; const PARAS_PALLET_NAME: &'static str = bp_rococo::PARAS_PALLET_NAME;
const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgeRococoParachain"; const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgeRococoParachain";
} }
impl ChainWithTransactions for Rococo {
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction =
bp_polkadot_core::UncheckedExtrinsic<Self::Call, bp_rococo::SignedExtension>;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
let raw_payload = SignedPayload::new(
unsigned.call,
bp_rococo::SignedExtension::from_params(
param.spec_version,
param.transaction_version,
unsigned.era,
param.genesis_hash,
unsigned.nonce,
unsigned.tip,
((), ()),
),
)?;
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
let signer: sp_runtime::MultiSigner = param.signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
Ok(Self::SignedTransaction::new_signed(
call,
signer.into_account().into(),
signature.into(),
extra,
))
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
tx.signature.is_some()
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
.map(|(address, _, _)| *address == Address::Id(signer.public().into()))
.unwrap_or(false)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
let extra = &tx.signature.as_ref()?.2;
Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip()))
}
}
+7 -2
View File
@@ -6,14 +6,19 @@ edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0" license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies] [dependencies]
relay-substrate-client = { path = "../client-substrate" } codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] }
relay-utils = { path = "../utils" }
# Bridge dependencies # Bridge dependencies
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-runtime = { path = "../../primitives/runtime" } bp-runtime = { path = "../../primitives/runtime" }
bp-wococo = { path = "../../primitives/chain-wococo" } bp-wococo = { path = "../../primitives/chain-wococo" }
relay-rococo-client = { path = "../client-rococo" }
relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
# Substrate Dependencies # Substrate Dependencies
sp-core = { 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" } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
+68 -3
View File
@@ -16,21 +16,35 @@
//! Types used to connect to the Wococo-Substrate chain. //! Types used to connect to the Wococo-Substrate chain.
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId; use bp_runtime::ChainId;
use bp_wococo::WOCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD; use bp_wococo::WOCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
use codec::Encode;
use relay_substrate_client::{ use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
}; };
use sp_core::storage::StorageKey; use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
use sp_session::MembershipProof; use sp_session::MembershipProof;
use std::time::Duration; use std::time::Duration;
pub use codegen_runtime::api::runtime_types;
use relay_rococo_client::codegen_runtime;
pub type RuntimeCall = runtime_types::rococo_runtime::RuntimeCall;
pub type GrandpaCall = runtime_types::pallet_grandpa::pallet::Call;
/// Wococo header id. /// Wococo header id.
pub type HeaderId = relay_utils::HeaderId<bp_wococo::Hash, bp_wococo::BlockNumber>; pub type HeaderId = relay_utils::HeaderId<bp_wococo::Hash, bp_wococo::BlockNumber>;
/// Wococo header type used in headers sync. /// Wococo header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_wococo::Header>; pub type SyncHeader = relay_substrate_client::SyncHeader<bp_wococo::Header>;
/// The address format for describing accounts.
pub type Address = MultiAddress<bp_wococo::AccountId, ()>;
/// Wococo chain definition /// Wococo chain definition
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Wococo; pub struct Wococo;
@@ -47,7 +61,7 @@ impl Chain for Wococo {
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_wococo::SignedBlock; type SignedBlock = bp_wococo::SignedBlock;
type Call = (); type Call = RuntimeCall;
} }
impl ChainWithGrandpa for Wococo { impl ChainWithGrandpa for Wococo {
@@ -67,3 +81,54 @@ impl RelayChain for Wococo {
const PARAS_PALLET_NAME: &'static str = bp_wococo::PARAS_PALLET_NAME; const PARAS_PALLET_NAME: &'static str = bp_wococo::PARAS_PALLET_NAME;
const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgeWococoParachain"; const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "BridgeWococoParachain";
} }
impl ChainWithTransactions for Wococo {
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction =
bp_polkadot_core::UncheckedExtrinsic<Self::Call, bp_wococo::SignedExtension>;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
let raw_payload = SignedPayload::new(
unsigned.call,
bp_wococo::SignedExtension::from_params(
param.spec_version,
param.transaction_version,
unsigned.era,
param.genesis_hash,
unsigned.nonce,
unsigned.tip,
((), ()),
),
)?;
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
let signer: sp_runtime::MultiSigner = param.signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
Ok(Self::SignedTransaction::new_signed(
call,
signer.into_account().into(),
signature.into(),
extra,
))
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
tx.signature.is_some()
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
.map(|(address, _, _)| *address == Address::Id(signer.public().into()))
.unwrap_or(false)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
let extra = &tx.signature.as_ref()?.2;
Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip()))
}
}
@@ -24,6 +24,7 @@ use finality_relay::{FinalityProofsBuf, FinalityProofsStream};
use futures::{select, FutureExt}; use futures::{select, FutureExt};
use num_traits::Saturating; use num_traits::Saturating;
use relay_utils::{ use relay_utils::{
metrics::MetricsParams,
relay_loop::{reconnect_failed_client, RECONNECT_DELAY}, relay_loop::{reconnect_failed_client, RECONNECT_DELAY},
FailedClient, MaybeConnectionError, FailedClient, MaybeConnectionError,
}; };
@@ -275,7 +276,10 @@ impl<P: EquivocationDetectionPipeline, SC: SourceClient<P>, TC: TargetClient<P>>
let mut context = let mut context =
match self.build_equivocation_reporting_context(current_block_number).await { match self.build_equivocation_reporting_context(current_block_number).await {
Some(context) => context, Some(context) => context,
None => continue, None => {
current_block_number = current_block_number.saturating_add(1.into());
continue
},
}; };
self.check_block(current_block_number, &mut context).await; self.check_block(current_block_number, &mut context).await;
current_block_number = current_block_number.saturating_add(1.into()); current_block_number = current_block_number.saturating_add(1.into());
@@ -311,16 +315,18 @@ impl<P: EquivocationDetectionPipeline, SC: SourceClient<P>, TC: TargetClient<P>>
} }
/// Spawn the equivocations detection loop. /// Spawn the equivocations detection loop.
/// TODO: remove `#[allow(dead_code)]`
#[allow(dead_code)]
pub async fn run<P: EquivocationDetectionPipeline>( pub async fn run<P: EquivocationDetectionPipeline>(
source_client: impl SourceClient<P>, source_client: impl SourceClient<P>,
target_client: impl TargetClient<P>, target_client: impl TargetClient<P>,
tick: Duration, tick: Duration,
metrics_params: MetricsParams,
exit_signal: impl Future<Output = ()> + 'static + Send, exit_signal: impl Future<Output = ()> + 'static + Send,
) -> Result<(), relay_utils::Error> { ) -> Result<(), relay_utils::Error> {
let exit_signal = exit_signal.shared(); let exit_signal = exit_signal.shared();
relay_utils::relay_loop(source_client, target_client) relay_utils::relay_loop(source_client, target_client)
.with_metrics(metrics_params)
.expose()
.await?
.run( .run(
format!("{}_to_{}_EquivocationDetection", P::SOURCE_NAME, P::TARGET_NAME), format!("{}_to_{}_EquivocationDetection", P::SOURCE_NAME, P::TARGET_NAME),
move |source_client, target_client, _metrics| { move |source_client, target_client, _metrics| {
+2
View File
@@ -23,6 +23,8 @@ use finality_relay::{FinalityPipeline, SourceClientBase};
use relay_utils::{relay_loop::Client as RelayClient, TransactionTracker}; use relay_utils::{relay_loop::Client as RelayClient, TransactionTracker};
use std::fmt::Debug; use std::fmt::Debug;
pub use equivocation_loop::run;
pub trait EquivocationDetectionPipeline: FinalityPipeline { pub trait EquivocationDetectionPipeline: FinalityPipeline {
/// Block number of the target chain. /// Block number of the target chain.
type TargetNumber: relay_utils::BlockNumberBase; type TargetNumber: relay_utils::BlockNumberBase;
@@ -20,14 +20,19 @@
mod source; mod source;
mod target; mod target;
use crate::finality_base::{engine::Engine, SubstrateFinalityPipeline, SubstrateFinalityProof}; use crate::{
equivocation::{source::SubstrateEquivocationSource, target::SubstrateEquivocationTarget},
finality_base::{engine::Engine, SubstrateFinalityPipeline, SubstrateFinalityProof},
TransactionParams,
};
use async_trait::async_trait; use async_trait::async_trait;
use bp_runtime::{AccountIdOf, BlockNumberOf, HashOf}; use bp_runtime::{AccountIdOf, BlockNumberOf, HashOf};
use equivocation_detector::EquivocationDetectionPipeline; use equivocation_detector::EquivocationDetectionPipeline;
use finality_relay::FinalityPipeline; use finality_relay::FinalityPipeline;
use pallet_grandpa::{Call as GrandpaCall, Config as GrandpaConfig}; use pallet_grandpa::{Call as GrandpaCall, Config as GrandpaConfig};
use relay_substrate_client::{AccountKeyPairOf, CallOf, Chain, ChainWithTransactions}; use relay_substrate_client::{AccountKeyPairOf, CallOf, Chain, ChainWithTransactions, Client};
use relay_utils::metrics::MetricsParams;
use sp_core::Pair; use sp_core::Pair;
use sp_runtime::traits::{Block, Header}; use sp_runtime::traits::{Block, Header};
use std::marker::PhantomData; use std::marker::PhantomData;
@@ -70,13 +75,15 @@ type FinalityVerificationContextfOf<P> =
<<P as SubstrateFinalityPipeline>::FinalityEngine as Engine< <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain, <P as SubstrateFinalityPipeline>::SourceChain,
>>::FinalityVerificationContext; >>::FinalityVerificationContext;
type EquivocationProofOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine< /// The type of the equivocation proof used by the `SubstrateEquivocationDetectionPipeline`
pub type EquivocationProofOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain, <P as SubstrateFinalityPipeline>::SourceChain,
>>::EquivocationProof; >>::EquivocationProof;
type EquivocationsFinderOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine< type EquivocationsFinderOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain, <P as SubstrateFinalityPipeline>::SourceChain,
>>::EquivocationsFinder; >>::EquivocationsFinder;
type KeyOwnerProofOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine< /// The type of the key owner proof used by the `SubstrateEquivocationDetectionPipeline`
pub type KeyOwnerProofOf<P> = <<P as SubstrateFinalityPipeline>::FinalityEngine as Engine<
<P as SubstrateFinalityPipeline>::SourceChain, <P as SubstrateFinalityPipeline>::SourceChain,
>>::KeyOwnerProof; >>::KeyOwnerProof;
@@ -147,3 +154,56 @@ where
.into() .into()
} }
} }
/// Macro that generates `ReportEquivocationCallBuilder` implementation for the case where
/// we only have access to the mocked version of the source chain runtime.
#[rustfmt::skip]
#[macro_export]
macro_rules! generate_report_equivocation_call_builder {
($pipeline:ident, $mocked_builder:ident, $grandpa:path, $report_equivocation:path) => {
pub struct $mocked_builder;
impl $crate::equivocation::ReportEquivocationCallBuilder<$pipeline>
for $mocked_builder
{
fn build_report_equivocation_call(
equivocation_proof: $crate::equivocation::EquivocationProofOf<$pipeline>,
key_owner_proof: $crate::equivocation::KeyOwnerProofOf<$pipeline>,
) -> relay_substrate_client::CallOf<
<$pipeline as $crate::finality_base::SubstrateFinalityPipeline>::SourceChain
> {
bp_runtime::paste::item! {
$grandpa($report_equivocation {
equivocation_proof: Box::new(equivocation_proof),
key_owner_proof: key_owner_proof
})
}
}
}
};
}
/// Run Substrate-to-Substrate equivocations detection loop.
pub async fn run<P: SubstrateEquivocationDetectionPipeline>(
source_client: Client<P::SourceChain>,
target_client: Client<P::TargetChain>,
source_transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
metrics_params: MetricsParams,
) -> anyhow::Result<()> {
log::info!(
target: "bridge",
"Starting {} -> {} equivocations detection loop",
P::SourceChain::NAME,
P::TargetChain::NAME,
);
equivocation_detector::run(
SubstrateEquivocationSource::<P>::new(source_client, source_transaction_params),
SubstrateEquivocationTarget::<P>::new(target_client),
P::TargetChain::AVERAGE_BLOCK_INTERVAL,
metrics_params,
futures::future::pending(),
)
.await
.map_err(|e| anyhow::format_err!("{}", e))
}
@@ -40,7 +40,15 @@ pub struct SubstrateEquivocationSource<P: SubstrateEquivocationDetectionPipeline
transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>, transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
} }
impl<P: SubstrateEquivocationDetectionPipeline> SubstrateEquivocationSource<P> {} impl<P: SubstrateEquivocationDetectionPipeline> SubstrateEquivocationSource<P> {
/// Create new instance of `SubstrateEquivocationSource`.
pub fn new(
client: Client<P::SourceChain>,
transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
) -> Self {
Self { client, transaction_params }
}
}
impl<P: SubstrateEquivocationDetectionPipeline> Clone for SubstrateEquivocationSource<P> { impl<P: SubstrateEquivocationDetectionPipeline> Clone for SubstrateEquivocationSource<P> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@@ -40,7 +40,12 @@ pub struct SubstrateEquivocationTarget<P: SubstrateEquivocationDetectionPipeline
_phantom: PhantomData<P>, _phantom: PhantomData<P>,
} }
impl<P: SubstrateEquivocationDetectionPipeline> SubstrateEquivocationTarget<P> {} impl<P: SubstrateEquivocationDetectionPipeline> SubstrateEquivocationTarget<P> {
/// Create new instance of `SubstrateEquivocationTarget`.
pub fn new(client: Client<P::TargetChain>) -> Self {
Self { client, _phantom: Default::default() }
}
}
impl<P: SubstrateEquivocationDetectionPipeline> Clone for SubstrateEquivocationTarget<P> { impl<P: SubstrateEquivocationDetectionPipeline> Clone for SubstrateEquivocationTarget<P> {
fn clone(&self) -> Self { fn clone(&self) -> Self {