Added Rococo BH <> Rococo Bulletin bridge (#2724)

* added Rococo BH <> Rococo Bulletin bridge

* init-bridge support

* allow customising finality-related runtime APIs

* revert me

* use Rococo/BridgeHubRococo pretending to be a Polkadot/BridgeHubPolkadot in Rococo <> RococoBulletin bridge

* Revert "revert me"

This reverts commit 90c598d9d50a25e7182c97eee7818bf8d4bc404c.

* Revert "allow customising finality-related runtime APIs"

This reverts commit b39c32c34acddfd0b919042122e0e667470bd0a4.

* fmt

* WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX

* regenerate bulletin chain runtime (pallet indices have changed)

* fx WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX constant because of latest changes

* also change indices in runtime

* fmt

* clippy
This commit is contained in:
Svyatoslav Nikolsky
2023-12-14 17:03:35 +03:00
committed by Bastian Köcher
parent e711c9a5d5
commit 59882a7343
24 changed files with 2037 additions and 455 deletions
@@ -18,4 +18,5 @@
pub mod kusama_polkadot;
pub mod polkadot_bulletin;
pub mod rococo_bulletin;
pub mod rococo_westend;
@@ -36,8 +36,8 @@ impl MessagesCliBridge for BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge
substrate_relay_helper::generate_receive_message_proof_call_builder!(
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane,
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLaneReceiveMessagesProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotBridgeHubMessages,
relay_polkadot_bulletin_client::BridgePolkadotBridgeHubMessagesCall::receive_messages_proof
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotMessages,
relay_polkadot_bulletin_client::BridgePolkadotMessagesCall::receive_messages_proof
);
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
@@ -43,8 +43,8 @@ substrate_relay_helper::generate_receive_message_proof_call_builder!(
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane,
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLaneReceiveMessagesDeliveryProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotBridgeHubMessages,
relay_polkadot_bulletin_client::BridgePolkadotBridgeHubMessagesCall::receive_messages_delivery_proof
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotMessages,
relay_polkadot_bulletin_client::BridgePolkadotMessagesCall::receive_messages_delivery_proof
);
/// PolkadotBulletin-to-BridgeHubPolkadot messages lane.
@@ -0,0 +1,65 @@
// Copyright 2022 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/>.
//! BridgeHubRococo-to-RococoBulletin messages sync entrypoint.
use super::BridgeHubRococoAsBridgeHubPolkadot;
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
use relay_polkadot_bulletin_client::PolkadotBulletin as RococoBulletin;
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
/// BridgeHubRococo-to-RococoBulletin messages bridge.
pub struct BridgeHubRococoToRococoBulletinMessagesCliBridge {}
impl CliBridgeBase for BridgeHubRococoToRococoBulletinMessagesCliBridge {
type Source = BridgeHubRococoAsBridgeHubPolkadot;
type Target = RococoBulletin;
}
impl MessagesCliBridge for BridgeHubRococoToRococoBulletinMessagesCliBridge {
type MessagesLane = BridgeHubRococoMessagesToRococoBulletinMessageLane;
}
substrate_relay_helper::generate_receive_message_proof_call_builder!(
BridgeHubRococoMessagesToRococoBulletinMessageLane,
BridgeHubRococoMessagesToRococoBulletinMessageLaneReceiveMessagesProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotMessages,
relay_polkadot_bulletin_client::BridgePolkadotMessagesCall::receive_messages_proof
);
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
BridgeHubRococoMessagesToRococoBulletinMessageLane,
BridgeHubRococoMessagesToRococoBulletinMessageLaneReceiveMessagesDeliveryProofCallBuilder,
relay_bridge_hub_rococo_client::RuntimeCall::BridgePolkadotBulletinMessages,
relay_bridge_hub_rococo_client::BridgeBulletinMessagesCall::receive_messages_delivery_proof
);
/// BridgeHubRococo-to-RococoBulletin messages lane.
#[derive(Clone, Debug)]
pub struct BridgeHubRococoMessagesToRococoBulletinMessageLane;
impl SubstrateMessageLane for BridgeHubRococoMessagesToRococoBulletinMessageLane {
type SourceChain = BridgeHubRococoAsBridgeHubPolkadot;
type TargetChain = RococoBulletin;
type ReceiveMessagesProofCallBuilder =
BridgeHubRococoMessagesToRococoBulletinMessageLaneReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder =
BridgeHubRococoMessagesToRococoBulletinMessageLaneReceiveMessagesDeliveryProofCallBuilder;
type SourceBatchCallBuilder = UtilityPalletBatchCallBuilder<BridgeHubRococoAsBridgeHubPolkadot>;
type TargetBatchCallBuilder = ();
}
@@ -0,0 +1,259 @@
// Copyright 2019-2021 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/>.
//! Declaration of all bridges between Rococo Bulletin Chain and Rococo Bridge Hub.
use crate::cli::CliChain;
use bp_messages::MessageNonce;
use bp_runtime::{
AccountIdOf, BalanceOf, BlockNumberOf, ChainId, HashOf, HasherOf, HeaderOf, NonceOf,
SignatureOf,
};
use frame_support::pallet_prelude::Weight;
use relay_substrate_client::{
Error as SubstrateError, SignParam, SimpleRuntimeVersion, UnsignedTransaction,
};
use sp_core::storage::StorageKey;
use std::time::Duration;
pub mod bridge_hub_rococo_messages_to_rococo_bulletin;
pub mod rococo_bulletin_headers_to_bridge_hub_rococo;
pub mod rococo_bulletin_messages_to_bridge_hub_rococo;
pub mod rococo_headers_to_rococo_bulletin;
pub mod rococo_parachains_to_rococo_bulletin;
/// Base `Chain` implementation of Rococo, pretending to be Polkadot.
pub struct RococoBaseAsPolkadot;
impl bp_runtime::Chain for RococoBaseAsPolkadot {
type BlockNumber = BlockNumberOf<bp_rococo::Rococo>;
type Hash = HashOf<bp_rococo::Rococo>;
type Hasher = HasherOf<bp_rococo::Rococo>;
type Header = HeaderOf<bp_rococo::Rococo>;
type AccountId = AccountIdOf<bp_rococo::Rococo>;
type Balance = BalanceOf<bp_rococo::Rococo>;
type Nonce = NonceOf<bp_rococo::Rococo>;
type Signature = SignatureOf<bp_rococo::Rococo>;
fn max_extrinsic_size() -> u32 {
bp_rococo::Rococo::max_extrinsic_size()
}
fn max_extrinsic_weight() -> Weight {
bp_rococo::Rococo::max_extrinsic_weight()
}
}
impl bp_header_chain::ChainWithGrandpa for RococoBaseAsPolkadot {
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str =
bp_polkadot::Polkadot::WITH_CHAIN_GRANDPA_PALLET_NAME;
const MAX_AUTHORITIES_COUNT: u32 = bp_rococo::Rococo::MAX_AUTHORITIES_COUNT;
const REASONABLE_HEADERS_IN_JUSTIFICATON_ANCESTRY: u32 =
bp_rococo::Rococo::REASONABLE_HEADERS_IN_JUSTIFICATON_ANCESTRY;
const MAX_HEADER_SIZE: u32 = bp_rococo::Rococo::MAX_HEADER_SIZE;
const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 =
bp_rococo::Rococo::AVERAGE_HEADER_SIZE_IN_JUSTIFICATION;
}
/// Relay `Chain` implementation of Rococo, pretending to be Polkadot.
#[derive(Debug, Clone, Copy)]
pub struct RococoAsPolkadot;
impl bp_runtime::UnderlyingChainProvider for RococoAsPolkadot {
type Chain = RococoBaseAsPolkadot;
}
impl relay_substrate_client::Chain for RococoAsPolkadot {
const ID: ChainId = relay_rococo_client::Rococo::ID;
const NAME: &'static str = relay_rococo_client::Rococo::NAME;
const BEST_FINALIZED_HEADER_ID_METHOD: &'static str =
relay_polkadot_client::Polkadot::BEST_FINALIZED_HEADER_ID_METHOD;
const AVERAGE_BLOCK_INTERVAL: Duration = relay_rococo_client::Rococo::AVERAGE_BLOCK_INTERVAL;
type SignedBlock = <relay_rococo_client::Rococo as relay_substrate_client::Chain>::SignedBlock;
type Call = <relay_rococo_client::Rococo as relay_substrate_client::Chain>::Call;
}
impl relay_substrate_client::ChainWithGrandpa for RococoAsPolkadot {
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
relay_polkadot_client::Polkadot::SYNCED_HEADERS_GRANDPA_INFO_METHOD;
type KeyOwnerProof =
<relay_rococo_client::Rococo as relay_substrate_client::ChainWithGrandpa>::KeyOwnerProof;
}
impl relay_substrate_client::ChainWithBalances for RococoAsPolkadot {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
relay_rococo_client::Rococo::account_info_storage_key(account_id)
}
}
impl relay_substrate_client::RelayChain for RococoAsPolkadot {
const PARAS_PALLET_NAME: &'static str = relay_rococo_client::Rococo::PARAS_PALLET_NAME;
}
impl relay_substrate_client::ChainWithTransactions for RococoAsPolkadot {
type AccountKeyPair = <relay_rococo_client::Rococo as relay_substrate_client::ChainWithTransactions>::AccountKeyPair;
type SignedTransaction = <relay_rococo_client::Rococo as relay_substrate_client::ChainWithTransactions>::SignedTransaction;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
relay_rococo_client::Rococo::sign_transaction(
SignParam {
spec_version: param.spec_version,
transaction_version: param.transaction_version,
genesis_hash: param.genesis_hash,
signer: param.signer,
},
unsigned.switch_chain(),
)
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
relay_rococo_client::Rococo::is_signed(tx)
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
relay_rococo_client::Rococo::is_signed_by(signer, tx)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
relay_rococo_client::Rococo::parse_transaction(tx).map(|tx| tx.switch_chain())
}
}
impl CliChain for RococoAsPolkadot {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> = None;
}
/// Base `Chain` implementation of Rococo Bridge Hub, pretending to be a Polkadot Bridge Hub.
pub struct BaseBridgeHubRococoAsBridgeHubPolkadot;
impl bp_runtime::Chain for BaseBridgeHubRococoAsBridgeHubPolkadot {
type BlockNumber = BlockNumberOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type Hash = HashOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type Hasher = HasherOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type Header = HeaderOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type AccountId = AccountIdOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type Balance = BalanceOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type Nonce = NonceOf<bp_bridge_hub_rococo::BridgeHubRococo>;
type Signature = SignatureOf<bp_bridge_hub_rococo::BridgeHubRococo>;
fn max_extrinsic_size() -> u32 {
bp_bridge_hub_rococo::BridgeHubRococo::max_extrinsic_size()
}
fn max_extrinsic_weight() -> Weight {
bp_bridge_hub_rococo::BridgeHubRococo::max_extrinsic_weight()
}
}
impl bp_runtime::Parachain for BaseBridgeHubRococoAsBridgeHubPolkadot {
const PARACHAIN_ID: u32 = bp_bridge_hub_rococo::BridgeHubRococo::PARACHAIN_ID;
}
/// Relay `Chain` implementation of Rococo Bridge Hub, pretending to be a Polkadot Bridge Hub.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BridgeHubRococoAsBridgeHubPolkadot;
impl bp_runtime::UnderlyingChainProvider for BridgeHubRococoAsBridgeHubPolkadot {
type Chain = BaseBridgeHubRococoAsBridgeHubPolkadot;
}
impl relay_substrate_client::Chain for BridgeHubRococoAsBridgeHubPolkadot {
const ID: ChainId = relay_bridge_hub_rococo_client::BridgeHubRococo::ID;
const NAME: &'static str = relay_bridge_hub_rococo_client::BridgeHubRococo::NAME;
const BEST_FINALIZED_HEADER_ID_METHOD: &'static str =
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::BEST_FINALIZED_HEADER_ID_METHOD;
const AVERAGE_BLOCK_INTERVAL: Duration =
relay_bridge_hub_rococo_client::BridgeHubRococo::AVERAGE_BLOCK_INTERVAL;
type SignedBlock = <relay_bridge_hub_rococo_client::BridgeHubRococo as relay_substrate_client::Chain>::SignedBlock;
type Call =
<relay_bridge_hub_rococo_client::BridgeHubRococo as relay_substrate_client::Chain>::Call;
}
impl relay_substrate_client::ChainWithBalances for BridgeHubRococoAsBridgeHubPolkadot {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
relay_bridge_hub_rococo_client::BridgeHubRococo::account_info_storage_key(account_id)
}
}
impl relay_substrate_client::ChainWithUtilityPallet for BridgeHubRococoAsBridgeHubPolkadot {
type UtilityPallet = relay_substrate_client::MockedRuntimeUtilityPallet<
relay_bridge_hub_rococo_client::RuntimeCall,
>;
}
impl relay_substrate_client::ChainWithTransactions for BridgeHubRococoAsBridgeHubPolkadot {
type AccountKeyPair = <relay_bridge_hub_rococo_client::BridgeHubRococo as relay_substrate_client::ChainWithTransactions>::AccountKeyPair;
type SignedTransaction = <relay_bridge_hub_rococo_client::BridgeHubRococo as relay_substrate_client::ChainWithTransactions>::SignedTransaction;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
relay_bridge_hub_rococo_client::BridgeHubRococo::sign_transaction(
SignParam {
spec_version: param.spec_version,
transaction_version: param.transaction_version,
genesis_hash: param.genesis_hash,
signer: param.signer,
},
unsigned.switch_chain(),
)
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
relay_bridge_hub_rococo_client::BridgeHubRococo::is_signed(tx)
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
relay_bridge_hub_rococo_client::BridgeHubRococo::is_signed_by(signer, tx)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
relay_bridge_hub_rococo_client::BridgeHubRococo::parse_transaction(tx)
.map(|tx| tx.switch_chain())
}
}
impl relay_substrate_client::ChainWithMessages for BridgeHubRococoAsBridgeHubPolkadot {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::WITH_CHAIN_MESSAGES_PALLET_NAME;
const WITH_CHAIN_RELAYERS_PALLET_NAME: Option<&'static str> =
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::WITH_CHAIN_RELAYERS_PALLET_NAME;
const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::TO_CHAIN_MESSAGE_DETAILS_METHOD;
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::FROM_CHAIN_MESSAGE_DETAILS_METHOD;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
relay_bridge_hub_rococo_client::BridgeHubRococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
relay_bridge_hub_rococo_client::BridgeHubRococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
impl CliChain for BridgeHubRococoAsBridgeHubPolkadot {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
Some(SimpleRuntimeVersion { spec_version: 1_003_000, transaction_version: 3 });
}
@@ -0,0 +1,86 @@
// Copyright 2022 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/>.
//! RococoBulletin-to-BridgeHubRococo headers sync entrypoint.
use super::BridgeHubRococoAsBridgeHubPolkadot;
use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait;
use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
};
/// Description of `RococoBulletin` -> `RococoBridgeHub` finalized headers bridge.
#[derive(Clone, Debug)]
pub struct RococoBulletinFinalityToBridgeHubRococo;
substrate_relay_helper::generate_submit_finality_proof_call_builder!(
RococoBulletinFinalityToBridgeHubRococo,
SubmitFinalityProofCallBuilder,
relay_bridge_hub_rococo_client::RuntimeCall::BridgePolkadotBulletinGrandpa,
relay_bridge_hub_rococo_client::BridgeBulletinGrandpaCall::submit_finality_proof
);
substrate_relay_helper::generate_report_equivocation_call_builder!(
RococoBulletinFinalityToBridgeHubRococo,
ReportEquivocationCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::Grandpa,
relay_polkadot_bulletin_client::GrandpaCall::report_equivocation
);
#[async_trait]
impl SubstrateFinalityPipeline for RococoBulletinFinalityToBridgeHubRococo {
type SourceChain = relay_polkadot_bulletin_client::PolkadotBulletin;
type TargetChain = BridgeHubRococoAsBridgeHubPolkadot;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
#[async_trait]
impl SubstrateFinalitySyncPipeline for RococoBulletinFinalityToBridgeHubRococo {
type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
}
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for RococoBulletinFinalityToBridgeHubRococo {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `RococoBulletin` to BridgeHub `Rococo` bridge definition.
pub struct RococoBulletinToBridgeHubRococoCliBridge {}
impl CliBridgeBase for RococoBulletinToBridgeHubRococoCliBridge {
type Source = relay_polkadot_bulletin_client::PolkadotBulletin;
type Target = BridgeHubRococoAsBridgeHubPolkadot;
}
impl RelayToRelayHeadersCliBridge for RococoBulletinToBridgeHubRococoCliBridge {
type Finality = RococoBulletinFinalityToBridgeHubRococo;
}
impl RelayToRelayEquivocationDetectionCliBridge for RococoBulletinToBridgeHubRococoCliBridge {
type Equivocation = RococoBulletinFinalityToBridgeHubRococo;
}
impl MessagesCliBridge for RococoBulletinToBridgeHubRococoCliBridge {
type MessagesLane = crate::bridges::rococo_bulletin::rococo_bulletin_messages_to_bridge_hub_rococo::RococoBulletinMessagesToBridgeHubRococoMessageLane;
}
@@ -0,0 +1,65 @@
// Copyright 2022 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/>.
//! RococoBulletin-to-BridgeHubRococo messages sync entrypoint.
use super::BridgeHubRococoAsBridgeHubPolkadot;
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
use relay_polkadot_bulletin_client::PolkadotBulletin as RococoBulletin;
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
/// RococoBulletin-to-BridgeHubRococo messages bridge.
pub struct RococoBulletinToBridgeHubRococoMessagesCliBridge {}
impl CliBridgeBase for RococoBulletinToBridgeHubRococoMessagesCliBridge {
type Source = RococoBulletin;
type Target = BridgeHubRococoAsBridgeHubPolkadot;
}
impl MessagesCliBridge for RococoBulletinToBridgeHubRococoMessagesCliBridge {
type MessagesLane = RococoBulletinMessagesToBridgeHubRococoMessageLane;
}
substrate_relay_helper::generate_receive_message_proof_call_builder!(
RococoBulletinMessagesToBridgeHubRococoMessageLane,
RococoBulletinMessagesToBridgeHubRococoMessageLaneReceiveMessagesProofCallBuilder,
relay_bridge_hub_rococo_client::RuntimeCall::BridgePolkadotBulletinMessages,
relay_bridge_hub_rococo_client::BridgeBulletinMessagesCall::receive_messages_proof
);
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
RococoBulletinMessagesToBridgeHubRococoMessageLane,
RococoBulletinMessagesToBridgeHubRococoMessageLaneReceiveMessagesDeliveryProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotMessages,
relay_polkadot_bulletin_client::BridgePolkadotMessagesCall::receive_messages_delivery_proof
);
/// RococoBulletin-to-BridgeHubRococo messages lane.
#[derive(Clone, Debug)]
pub struct RococoBulletinMessagesToBridgeHubRococoMessageLane;
impl SubstrateMessageLane for RococoBulletinMessagesToBridgeHubRococoMessageLane {
type SourceChain = RococoBulletin;
type TargetChain = BridgeHubRococoAsBridgeHubPolkadot;
type ReceiveMessagesProofCallBuilder =
RococoBulletinMessagesToBridgeHubRococoMessageLaneReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder =
RococoBulletinMessagesToBridgeHubRococoMessageLaneReceiveMessagesDeliveryProofCallBuilder;
type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = UtilityPalletBatchCallBuilder<BridgeHubRococoAsBridgeHubPolkadot>;
}
@@ -0,0 +1,81 @@
// Copyright 2022 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/>.
//! Rococo-to-RococoBulletin headers sync entrypoint.
use super::RococoAsPolkadot;
use crate::cli::bridge::{
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait;
use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
};
/// Description of Rococo -> `RococoBulletin` finalized headers bridge.
#[derive(Clone, Debug)]
pub struct RococoFinalityToRococoBulletin;
substrate_relay_helper::generate_submit_finality_proof_call_builder!(
RococoFinalityToRococoBulletin,
SubmitFinalityProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotGrandpa,
relay_polkadot_bulletin_client::BridgePolkadotGrandpaCall::submit_finality_proof
);
substrate_relay_helper::generate_report_equivocation_call_builder!(
RococoFinalityToRococoBulletin,
ReportEquivocationCallBuilder,
relay_rococo_client::RuntimeCall::Grandpa,
relay_rococo_client::GrandpaCall::report_equivocation
);
#[async_trait]
impl SubstrateFinalityPipeline for RococoFinalityToRococoBulletin {
type SourceChain = RococoAsPolkadot;
type TargetChain = relay_polkadot_bulletin_client::PolkadotBulletin;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
#[async_trait]
impl SubstrateFinalitySyncPipeline for RococoFinalityToRococoBulletin {
type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
}
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for RococoFinalityToRococoBulletin {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `Rococo` to BridgeHub `RococoBulletin` bridge definition.
pub struct RococoToRococoBulletinCliBridge {}
impl CliBridgeBase for RococoToRococoBulletinCliBridge {
type Source = RococoAsPolkadot;
type Target = relay_polkadot_bulletin_client::PolkadotBulletin;
}
impl RelayToRelayHeadersCliBridge for RococoToRococoBulletinCliBridge {
type Finality = RococoFinalityToRococoBulletin;
}
impl RelayToRelayEquivocationDetectionCliBridge for RococoToRococoBulletinCliBridge {
type Equivocation = RococoFinalityToRococoBulletin;
}
@@ -0,0 +1,91 @@
// Copyright 2019-2021 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/>.
//! Rococo-to-RococoBulletin parachains sync entrypoint.
use super::{BridgeHubRococoAsBridgeHubPolkadot, RococoAsPolkadot};
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
use bp_runtime::Chain;
use relay_substrate_client::{CallOf, HeaderIdOf};
use substrate_relay_helper::{
messages_lane::MessagesRelayLimits,
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
};
/// Rococo-to-RococoBulletin parachain sync description.
#[derive(Clone, Debug)]
pub struct RococoToRococoBulletin;
impl SubstrateParachainsPipeline for RococoToRococoBulletin {
type SourceParachain = BridgeHubRococoAsBridgeHubPolkadot;
type SourceRelayChain = RococoAsPolkadot;
type TargetChain = relay_polkadot_bulletin_client::PolkadotBulletin;
type SubmitParachainHeadsCallBuilder = RococoToRococoBulletinCallBuilder;
}
pub struct RococoToRococoBulletinCallBuilder;
impl SubmitParachainHeadsCallBuilder<RococoToRococoBulletin> for RococoToRococoBulletinCallBuilder {
fn build_submit_parachain_heads_call(
at_relay_block: HeaderIdOf<relay_rococo_client::Rococo>,
parachains: Vec<(ParaId, ParaHash)>,
parachain_heads_proof: ParaHeadsProof,
) -> CallOf<relay_polkadot_bulletin_client::PolkadotBulletin> {
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotParachains(
relay_polkadot_bulletin_client::BridgePolkadotParachainsCall::submit_parachain_heads {
at_relay_block: (at_relay_block.0, at_relay_block.1),
parachains,
parachain_heads_proof,
},
)
}
}
/// Rococo-to-RococoBulletin parachain sync description for the CLI.
pub struct RococoToRococoBulletinCliBridge {}
impl ParachainToRelayHeadersCliBridge for RococoToRococoBulletinCliBridge {
type SourceRelay = RococoAsPolkadot;
type ParachainFinality = RococoToRococoBulletin;
type RelayFinality =
crate::bridges::rococo_bulletin::rococo_headers_to_rococo_bulletin::RococoFinalityToRococoBulletin;
}
impl CliBridgeBase for RococoToRococoBulletinCliBridge {
type Source = BridgeHubRococoAsBridgeHubPolkadot;
type Target = relay_polkadot_bulletin_client::PolkadotBulletin;
}
impl MessagesCliBridge for RococoToRococoBulletinCliBridge {
type MessagesLane =
crate::bridges::rococo_bulletin::bridge_hub_rococo_messages_to_rococo_bulletin::BridgeHubRococoMessagesToRococoBulletinMessageLane;
fn maybe_messages_limits() -> Option<MessagesRelayLimits> {
// Rococo Bulletin chain is missing the `TransactionPayment` runtime API (as well as the
// transaction payment pallet itself), so we can't estimate limits using runtime calls.
// Let's do it here.
//
// Folloiung constants are just safe **underestimations**. Normally, we are able to deliver
// and dispatch thousands of messages in the same transaction.
Some(MessagesRelayLimits {
max_messages_in_single_batch: 128,
max_messages_weight_in_single_batch:
bp_polkadot_bulletin::PolkadotBulletin::max_extrinsic_weight() / 20,
})
}
}
@@ -35,6 +35,8 @@ pub enum FullBridge {
BridgeHubPolkadotToBridgeHubKusama,
PolkadotBulletinToBridgeHubPolkadot,
BridgeHubPolkadotToPolkadotBulletin,
RococoBulletinToBridgeHubRococo,
BridgeHubRococoToRococoBulletin,
}
/// Minimal bridge representation that can be used from the CLI.
@@ -27,6 +27,10 @@ use crate::{
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
},
rococo_bulletin::{
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
},
rococo_westend::{
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
@@ -66,6 +70,8 @@ pub enum InitBridgeName {
PolkadotToBridgeHubKusama,
PolkadotToPolkadotBulletin,
PolkadotBulletinToBridgeHubPolkadot,
RococoToRococoBulletin,
RococoBulletinToBridgeHubRococo,
RococoToBridgeHubWestend,
WestendToBridgeHubRococo,
}
@@ -195,6 +201,35 @@ impl BridgeInitializer for PolkadotBulletinToBridgeHubPolkadotCliBridge {
}
}
impl BridgeInitializer for RococoToRococoBulletinCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
type RuntimeCall = relay_polkadot_bulletin_client::RuntimeCall;
type BridgePolkadotGrandpaCall = relay_polkadot_bulletin_client::BridgePolkadotGrandpaCall;
type SudoCall = relay_polkadot_bulletin_client::SudoCall;
let initialize_call =
RuntimeCall::BridgePolkadotGrandpa(BridgePolkadotGrandpaCall::initialize { init_data });
RuntimeCall::Sudo(SudoCall::sudo { call: Box::new(initialize_call) })
}
}
impl BridgeInitializer for RococoBulletinToBridgeHubRococoCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
relay_bridge_hub_rococo_client::RuntimeCall::BridgePolkadotBulletinGrandpa(
relay_bridge_hub_rococo_client::BridgeBulletinGrandpaCall::initialize { init_data },
)
}
}
impl InitBridge {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
@@ -207,6 +242,10 @@ impl InitBridge {
PolkadotToPolkadotBulletinCliBridge::init_bridge(self),
InitBridgeName::PolkadotBulletinToBridgeHubPolkadot =>
PolkadotBulletinToBridgeHubPolkadotCliBridge::init_bridge(self),
InitBridgeName::RococoToRococoBulletin =>
RococoToRococoBulletinCliBridge::init_bridge(self),
InitBridgeName::RococoBulletinToBridgeHubRococo =>
RococoBulletinToBridgeHubRococoCliBridge::init_bridge(self),
InitBridgeName::RococoToBridgeHubWestend =>
RococoToBridgeHubWestendCliBridge::init_bridge(self),
InitBridgeName::WestendToBridgeHubRococo =>
@@ -27,6 +27,10 @@ use crate::bridges::{
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
},
rococo_bulletin::{
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
},
};
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline;
@@ -61,6 +65,8 @@ pub enum RelayHeadersBridge {
PolkadotToBridgeHubKusama,
PolkadotToPolkadotBulletin,
PolkadotBulletinToBridgeHubPolkadot,
RococoToRococoBulletin,
RococoBulletinToBridgeHubRococo,
}
#[async_trait]
@@ -98,6 +104,8 @@ impl HeadersRelayer for KusamaToBridgeHubPolkadotCliBridge {}
impl HeadersRelayer for PolkadotToBridgeHubKusamaCliBridge {}
impl HeadersRelayer for PolkadotToPolkadotBulletinCliBridge {}
impl HeadersRelayer for PolkadotBulletinToBridgeHubPolkadotCliBridge {}
impl HeadersRelayer for RococoToRococoBulletinCliBridge {}
impl HeadersRelayer for RococoBulletinToBridgeHubRococoCliBridge {}
impl RelayHeaders {
/// Run the command.
@@ -111,6 +119,10 @@ impl RelayHeaders {
PolkadotToPolkadotBulletinCliBridge::relay_headers(self),
RelayHeadersBridge::PolkadotBulletinToBridgeHubPolkadot =>
PolkadotBulletinToBridgeHubPolkadotCliBridge::relay_headers(self),
RelayHeadersBridge::RococoToRococoBulletin =>
RococoToRococoBulletinCliBridge::relay_headers(self),
RelayHeadersBridge::RococoBulletinToBridgeHubRococo =>
RococoBulletinToBridgeHubRococoCliBridge::relay_headers(self),
}
.await
}
@@ -47,6 +47,11 @@ use crate::{
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
},
rococo_bulletin::{
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
rococo_parachains_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
BridgeHubRococoAsBridgeHubPolkadot,
},
rococo_westend::{
rococo_parachains_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendCliBridge,
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
@@ -199,6 +204,7 @@ declare_chain_cli_schema!(BridgeHubKusama, bridge_hub_kusama);
declare_chain_cli_schema!(Polkadot, polkadot);
declare_chain_cli_schema!(BridgeHubPolkadot, bridge_hub_polkadot);
declare_chain_cli_schema!(PolkadotBulletin, polkadot_bulletin);
declare_chain_cli_schema!(RococoBulletin, rococo_bulletin);
// Means to override signers of different layer transactions.
declare_chain_cli_schema!(RococoHeadersToBridgeHubWestend, rococo_headers_to_bridge_hub_westend);
declare_chain_cli_schema!(
@@ -224,15 +230,22 @@ declare_chain_cli_schema!(
PolkadotBulletinHeadersToBridgeHubPolkadot,
polkadot_bulletin_headers_to_bridge_hub_polkadot
);
declare_chain_cli_schema!(
RococoBulletinHeadersToBridgeHubRococo,
rococo_bulletin_headers_to_bridge_hub_rococo
);
declare_chain_cli_schema!(PolkadotHeadersToPolkadotBulletin, polkadot_headers_to_polkadot_bulletin);
declare_chain_cli_schema!(RococoHeadersToRococoBulletin, rococo_headers_to_rococo_bulletin);
declare_chain_cli_schema!(
PolkadotParachainsToPolkadotBulletin,
polkadot_parachains_to_polkadot_bulletin
);
declare_chain_cli_schema!(RococoParachainsToRococoBulletin, rococo_parachains_to_rococo_bulletin);
// All supported bridges.
declare_parachain_to_parachain_bridge_schema!(BridgeHubRococo, Rococo, BridgeHubWestend, Westend);
declare_parachain_to_parachain_bridge_schema!(BridgeHubKusama, Kusama, BridgeHubPolkadot, Polkadot);
declare_relay_to_parachain_bridge_schema!(PolkadotBulletin, BridgeHubPolkadot, Polkadot);
declare_relay_to_parachain_bridge_schema!(RococoBulletin, BridgeHubRococo, Rococo);
/// Base portion of the bidirectional complex relay.
///
@@ -477,6 +490,32 @@ impl Full2WayBridge for PolkadotBulletinBridgeHubPolkadotFull2WayBridge {
}
}
/// `RococoBulletin` <> `BridgeHubRococo` complex relay.
pub struct RococoBulletinBridgeHubRococoFull2WayBridge {
base: <Self as Full2WayBridge>::Base,
}
#[async_trait]
impl Full2WayBridge for RococoBulletinBridgeHubRococoFull2WayBridge {
type Base = RelayToParachainBridge<Self::L2R, Self::R2L>;
type Left = relay_polkadot_bulletin_client::PolkadotBulletin;
type Right = BridgeHubRococoAsBridgeHubPolkadot;
type L2R = RococoBulletinToBridgeHubRococoCliBridge;
type R2L = RococoToRococoBulletinCliBridge;
fn new(base: Self::Base) -> anyhow::Result<Self> {
Ok(Self { base })
}
fn base(&self) -> &Self::Base {
&self.base
}
fn mut_base(&mut self) -> &mut Self::Base {
&mut self.base
}
}
/// Complex headers+messages relay.
#[derive(Debug, PartialEq, StructOpt)]
pub enum RelayHeadersAndMessages {
@@ -484,6 +523,8 @@ pub enum RelayHeadersAndMessages {
BridgeHubKusamaBridgeHubPolkadot(BridgeHubKusamaBridgeHubPolkadotHeadersAndMessages),
/// `PolkadotBulletin` <> `BridgeHubPolkadot` relay.
PolkadotBulletinBridgeHubPolkadot(PolkadotBulletinBridgeHubPolkadotHeadersAndMessages),
/// `RococoBulletin` <> `BridgeHubRococo` relay.
RococoBulletinBridgeHubRococo(RococoBulletinBridgeHubRococoHeadersAndMessages),
/// BridgeHubRococo <> BridgeHubWestend relay.
BridgeHubRococoBridgeHubWestend(BridgeHubRococoBridgeHubWestendHeadersAndMessages),
}
@@ -504,6 +545,10 @@ impl RelayHeadersAndMessages {
PolkadotBulletinBridgeHubPolkadotFull2WayBridge::new(params.into_bridge().await?)?
.run()
.await,
RelayHeadersAndMessages::RococoBulletinBridgeHubRococo(params) =>
RococoBulletinBridgeHubRococoFull2WayBridge::new(params.into_bridge().await?)?
.run()
.await,
}
}
}
@@ -28,6 +28,10 @@ use crate::bridges::{
bridge_hub_polkadot_messages_to_polkadot_bulletin::BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge,
polkadot_bulletin_messages_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge,
},
rococo_bulletin::{
bridge_hub_rococo_messages_to_rococo_bulletin::BridgeHubRococoToRococoBulletinMessagesCliBridge,
rococo_bulletin_messages_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoMessagesCliBridge,
},
rococo_westend::{
bridge_hub_rococo_messages_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendMessagesCliBridge,
bridge_hub_westend_messages_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoMessagesCliBridge,
@@ -103,6 +107,8 @@ impl MessagesRelayer for BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge {}
impl MessagesRelayer for BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge {}
impl MessagesRelayer for PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {}
impl MessagesRelayer for BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {}
impl MessagesRelayer for RococoBulletinToBridgeHubRococoMessagesCliBridge {}
impl MessagesRelayer for BridgeHubRococoToRococoBulletinMessagesCliBridge {}
impl RelayMessages {
/// Run the command.
@@ -120,6 +126,10 @@ impl RelayMessages {
PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
FullBridge::BridgeHubPolkadotToPolkadotBulletin =>
BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge::relay_messages(self),
FullBridge::RococoBulletinToBridgeHubRococo =>
RococoBulletinToBridgeHubRococoMessagesCliBridge::relay_messages(self),
FullBridge::BridgeHubRococoToRococoBulletin =>
BridgeHubRococoToRococoBulletinMessagesCliBridge::relay_messages(self),
}
.await
}
@@ -20,6 +20,7 @@ use crate::bridges::{
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
},
polkadot_bulletin::polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
rococo_bulletin::rococo_parachains_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
rococo_westend::{
rococo_parachains_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendCliBridge,
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
@@ -67,6 +68,7 @@ pub enum RelayParachainsBridge {
KusamaToBridgeHubPolkadot,
PolkadotToBridgeHubKusama,
PolkadotToPolkadotBulletin,
RococoToRococoBulletin,
RococoToBridgeHubWestend,
WestendToBridgeHubRococo,
}
@@ -117,6 +119,7 @@ impl ParachainsRelayer for BridgeHubWestendToBridgeHubRococoCliBridge {}
impl ParachainsRelayer for BridgeHubKusamaToBridgeHubPolkadotCliBridge {}
impl ParachainsRelayer for BridgeHubPolkadotToBridgeHubKusamaCliBridge {}
impl ParachainsRelayer for PolkadotToPolkadotBulletinCliBridge {}
impl ParachainsRelayer for RococoToRococoBulletinCliBridge {}
impl RelayParachains {
/// Run the command.
@@ -132,6 +135,8 @@ impl RelayParachains {
BridgeHubPolkadotToBridgeHubKusamaCliBridge::relay_parachains(self),
RelayParachainsBridge::PolkadotToPolkadotBulletin =>
PolkadotToPolkadotBulletinCliBridge::relay_parachains(self),
RelayParachainsBridge::RococoToRococoBulletin =>
RococoToRococoBulletinCliBridge::relay_parachains(self),
}
.await
}