From 46c0400f26e26b53c575ed6bb5bc6d244e2d7d5f Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Tue, 5 Jul 2022 16:28:19 +0300 Subject: [PATCH] [CLI] Remove some macros Refactor the implementations for the following CLI methods in order to avoid using macros: - init_bridge - relay_headers - relay_parachains Signed-off-by: Serban Iorga --- .../bin-substrate/src/chains/westend.rs | 16 +- .../relays/bin-substrate/src/cli/bridge.rs | 137 +++++++ .../bin-substrate/src/cli/init_bridge.rs | 363 +++++++++--------- .../bin-substrate/src/cli/relay_headers.rs | 149 +++---- .../bin-substrate/src/cli/relay_parachains.rs | 120 +++--- 5 files changed, 464 insertions(+), 321 deletions(-) diff --git a/bridges/relays/bin-substrate/src/chains/westend.rs b/bridges/relays/bin-substrate/src/chains/westend.rs index eb578ddb78..ae52944707 100644 --- a/bridges/relays/bin-substrate/src/chains/westend.rs +++ b/bridges/relays/bin-substrate/src/chains/westend.rs @@ -17,7 +17,7 @@ //! Westend chain specification for CLI. use crate::cli::CliChain; -use relay_westend_client::Westend; +use relay_westend_client::{Westend, Westmint}; use sp_version::RuntimeVersion; impl CliChain for Westend { @@ -33,3 +33,17 @@ impl CliChain for Westend { .into() } } + +impl CliChain for Westmint { + const RUNTIME_VERSION: RuntimeVersion = bp_westend::VERSION; + + type KeyPair = sp_core::sr25519::Pair; + type MessagePayload = Vec; + + fn ss58_format() -> u16 { + sp_core::crypto::Ss58AddressFormat::from( + sp_core::crypto::Ss58AddressFormatRegistry::SubstrateAccount, + ) + .into() + } +} diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs index 45d6f960ae..c6b6375b05 100644 --- a/bridges/relays/bin-substrate/src/cli/bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/bridge.rs @@ -14,7 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::cli::CliChain; +use relay_substrate_client::{AccountKeyPairOf, Chain, TransactionSignScheme}; use strum::{EnumString, EnumVariantNames}; +use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline; #[derive(Debug, PartialEq, Eq, EnumString, EnumVariantNames)] #[strum(serialize_all = "kebab_case")] @@ -218,3 +221,137 @@ macro_rules! select_full_bridge { } }; } + +/// Minimal bridge representation that can be used from the CLI. +/// It connects a source chain to a target chain. +pub trait CliBridgeBase: Sized { + /// The source chain. + type Source: Chain + CliChain; + /// The target chain. + type Target: Chain + + TransactionSignScheme + + CliChain>; +} + +/// Bridge representation that can be used from the CLI. +pub trait CliBridge: CliBridgeBase { + /// Finality proofs synchronization pipeline. + type Finality: SubstrateFinalitySyncPipeline< + SourceChain = Self::Source, + TargetChain = Self::Target, + TransactionSignScheme = Self::Target, + >; +} + +//// `Millau` to `Rialto` bridge definition. +pub struct MillauToRialtoCliBridge {} + +impl CliBridgeBase for MillauToRialtoCliBridge { + type Source = relay_millau_client::Millau; + type Target = relay_rialto_client::Rialto; +} + +impl CliBridge for MillauToRialtoCliBridge { + type Finality = crate::chains::millau_headers_to_rialto::MillauFinalityToRialto; +} + +//// `Rialto` to `Millau` bridge definition. +pub struct RialtoToMillauCliBridge {} + +impl CliBridgeBase for RialtoToMillauCliBridge { + type Source = relay_rialto_client::Rialto; + type Target = relay_millau_client::Millau; +} + +impl CliBridge for RialtoToMillauCliBridge { + type Finality = crate::chains::rialto_headers_to_millau::RialtoFinalityToMillau; +} + +//// `Westend` to `Millau` bridge definition. +pub struct WestendToMillauCliBridge {} + +impl CliBridgeBase for WestendToMillauCliBridge { + type Source = relay_westend_client::Westend; + type Target = relay_millau_client::Millau; +} + +impl CliBridge for WestendToMillauCliBridge { + type Finality = crate::chains::westend_headers_to_millau::WestendFinalityToMillau; +} + +//// `Rococo` to `Wococo` bridge definition. +pub struct RococoToWococoCliBridge {} + +impl CliBridgeBase for RococoToWococoCliBridge { + type Source = relay_rococo_client::Rococo; + type Target = relay_wococo_client::Wococo; +} + +impl CliBridge for RococoToWococoCliBridge { + type Finality = crate::chains::rococo_headers_to_wococo::RococoFinalityToWococo; +} + +//// `Wococo` to `Rococo` bridge definition. +pub struct WococoToRococoCliBridge {} + +impl CliBridgeBase for WococoToRococoCliBridge { + type Source = relay_wococo_client::Wococo; + type Target = relay_rococo_client::Rococo; +} + +impl CliBridge for WococoToRococoCliBridge { + type Finality = crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo; +} + +//// `Kusama` to `Polkadot` bridge definition. +pub struct KusamaToPolkadotCliBridge {} + +impl CliBridgeBase for KusamaToPolkadotCliBridge { + type Source = relay_kusama_client::Kusama; + type Target = relay_polkadot_client::Polkadot; +} + +impl CliBridge for KusamaToPolkadotCliBridge { + type Finality = crate::chains::kusama_headers_to_polkadot::KusamaFinalityToPolkadot; +} + +//// `Polkadot` to `Kusama` bridge definition. +pub struct PolkadotToKusamaCliBridge {} + +impl CliBridgeBase for PolkadotToKusamaCliBridge { + type Source = relay_polkadot_client::Polkadot; + type Target = relay_kusama_client::Kusama; +} + +impl CliBridge for PolkadotToKusamaCliBridge { + type Finality = crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama; +} + +//// `Millau` to `RialtoParachain` bridge definition. +pub struct MillauToRialtoParachainCliBridge {} + +impl CliBridgeBase for MillauToRialtoParachainCliBridge { + type Source = relay_millau_client::Millau; + type Target = relay_rialto_parachain_client::RialtoParachain; +} + +impl CliBridge for MillauToRialtoParachainCliBridge { + type Finality = + crate::chains::millau_headers_to_rialto_parachain::MillauFinalityToRialtoParachain; +} + +//// `RialtoParachain` to `Millau` bridge definition. +pub struct RialtoParachainToMillauCliBridge {} + +impl CliBridgeBase for RialtoParachainToMillauCliBridge { + type Source = relay_rialto_parachain_client::RialtoParachain; + type Target = relay_millau_client::Millau; +} + +//// `WestendParachain` to `Millau` bridge definition. +pub struct WestmintToMillauCliBridge {} + +impl CliBridgeBase for WestmintToMillauCliBridge { + type Source = relay_westend_client::Westmint; + type Target = relay_millau_client::Millau; +} diff --git a/bridges/relays/bin-substrate/src/cli/init_bridge.rs b/bridges/relays/bin-substrate/src/cli/init_bridge.rs index 63252382ec..e8efcd503f 100644 --- a/bridges/relays/bin-substrate/src/cli/init_bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/init_bridge.rs @@ -14,15 +14,25 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::cli::{SourceConnectionParams, TargetConnectionParams, TargetSigningParams}; -use bp_header_chain::InitializationData; +use async_trait::async_trait; + +use crate::cli::{ + bridge::{ + CliBridgeBase, KusamaToPolkadotCliBridge, MillauToRialtoCliBridge, + MillauToRialtoParachainCliBridge, PolkadotToKusamaCliBridge, RialtoToMillauCliBridge, + RococoToWococoCliBridge, WestendToMillauCliBridge, WococoToRococoCliBridge, + }, + SourceConnectionParams, TargetConnectionParams, TargetSigningParams, +}; use bp_runtime::Chain as ChainBase; use codec::Encode; -use relay_substrate_client::{Chain, SignParam, TransactionSignScheme, UnsignedTransaction}; +use relay_substrate_client::{ + AccountKeyPairOf, Chain, SignParam, TransactionSignScheme, UnsignedTransaction, +}; use sp_core::{Bytes, Pair}; use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; -use substrate_relay_helper::finality::engine::Grandpa as GrandpaFinalityEngine; +use substrate_relay_helper::finality::engine::{Engine, Grandpa as GrandpaFinalityEngine}; /// Initialize bridge pallet. #[derive(StructOpt)] @@ -52,198 +62,181 @@ pub enum InitBridgeName { MillauToRialtoParachain, } -macro_rules! select_bridge { - ($bridge: expr, $generic: tt) => { - match $bridge { - InitBridgeName::MillauToRialto => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_client::Rialto; - type Engine = GrandpaFinalityEngine; +#[async_trait] +trait BridgeInitializer: CliBridgeBase +where + ::AccountId: From< as Pair>::Public>, +{ + type Engine: Engine; - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - rialto_runtime::SudoCall::sudo { - call: Box::new( - rialto_runtime::BridgeGrandpaMillauCall::initialize { init_data } - .into(), + /// Get the encoded call to init the bridge. + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call; + + /// Initialize the bridge. + async fn init_bridge(data: InitBridge) -> anyhow::Result<()> { + let source_client = data.source.to_client::().await?; + let target_client = data.target.to_client::().await?; + let target_sign = data.target_sign.to_keypair::()?; + + let (spec_version, transaction_version) = target_client.simple_runtime_version().await?; + substrate_relay_helper::finality::initialize::initialize::( + source_client, + target_client.clone(), + target_sign.public().into(), + move |transaction_nonce, initialization_data| { + Ok(Bytes( + Self::Target::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: *target_client.genesis_hash(), + signer: target_sign, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( + Self::encode_init_bridge(initialization_data).into(), + transaction_nonce, ), - } - .into() - } - - $generic + })? + .encode(), + )) }, - InitBridgeName::RialtoToMillau => { - type Source = relay_rialto_client::Rialto; - type Target = relay_millau_client::Millau; - type Engine = GrandpaFinalityEngine; + ) + .await; - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - let initialize_call = millau_runtime::BridgeGrandpaCall::< - millau_runtime::Runtime, - millau_runtime::RialtoGrandpaInstance, - >::initialize { - init_data, - }; - millau_runtime::SudoCall::sudo { call: Box::new(initialize_call.into()) }.into() - } + Ok(()) + } +} - $generic - }, - InitBridgeName::WestendToMillau => { - type Source = relay_westend_client::Westend; - type Target = relay_millau_client::Millau; - type Engine = GrandpaFinalityEngine; +impl BridgeInitializer for MillauToRialtoCliBridge { + type Engine = GrandpaFinalityEngine; - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - // at Westend -> Millau initialization we're not using sudo, because otherwise - // our deployments may fail, because we need to initialize both Rialto -> Millau - // and Westend -> Millau bridge. => since there's single possible sudo account, - // one of transaction may fail with duplicate nonce error - millau_runtime::BridgeGrandpaCall::< - millau_runtime::Runtime, - millau_runtime::WestendGrandpaInstance, - >::initialize { - init_data, - } - .into() - } - - $generic - }, - InitBridgeName::RococoToWococo => { - type Source = relay_rococo_client::Rococo; - type Target = relay_wococo_client::Wococo; - type Engine = GrandpaFinalityEngine; - - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - relay_wococo_client::runtime::Call::BridgeGrandpaRococo( - relay_wococo_client::runtime::BridgeGrandpaRococoCall::initialize( - init_data, - ), - ) - } - - $generic - }, - InitBridgeName::WococoToRococo => { - type Source = relay_wococo_client::Wococo; - type Target = relay_rococo_client::Rococo; - type Engine = GrandpaFinalityEngine; - - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - relay_rococo_client::runtime::Call::BridgeGrandpaWococo( - relay_rococo_client::runtime::BridgeGrandpaWococoCall::initialize( - init_data, - ), - ) - } - - $generic - }, - InitBridgeName::KusamaToPolkadot => { - type Source = relay_kusama_client::Kusama; - type Target = relay_polkadot_client::Polkadot; - type Engine = GrandpaFinalityEngine; - - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - relay_polkadot_client::runtime::Call::BridgeKusamaGrandpa( - relay_polkadot_client::runtime::BridgeKusamaGrandpaCall::initialize( - init_data, - ), - ) - } - - $generic - }, - InitBridgeName::PolkadotToKusama => { - type Source = relay_polkadot_client::Polkadot; - type Target = relay_kusama_client::Kusama; - type Engine = GrandpaFinalityEngine; - - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - relay_kusama_client::runtime::Call::BridgePolkadotGrandpa( - relay_kusama_client::runtime::BridgePolkadotGrandpaCall::initialize( - init_data, - ), - ) - } - - $generic - }, - InitBridgeName::MillauToRialtoParachain => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_parachain_client::RialtoParachain; - type Engine = GrandpaFinalityEngine; - - fn encode_init_bridge( - init_data: InitializationData<::Header>, - ) -> ::Call { - let initialize_call = rialto_parachain_runtime::BridgeGrandpaCall::< - rialto_parachain_runtime::Runtime, - rialto_parachain_runtime::MillauGrandpaInstance, - >::initialize { - init_data, - }; - rialto_parachain_runtime::SudoCall::sudo { - call: Box::new(initialize_call.into()), - } - .into() - } - - $generic - }, + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + rialto_runtime::SudoCall::sudo { + call: Box::new( + rialto_runtime::BridgeGrandpaMillauCall::initialize { init_data }.into(), + ), } - }; + .into() + } +} + +impl BridgeInitializer for MillauToRialtoParachainCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + let initialize_call = rialto_parachain_runtime::BridgeGrandpaCall::< + rialto_parachain_runtime::Runtime, + rialto_parachain_runtime::MillauGrandpaInstance, + >::initialize { + init_data, + }; + rialto_parachain_runtime::SudoCall::sudo { call: Box::new(initialize_call.into()) }.into() + } +} + +impl BridgeInitializer for RialtoToMillauCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + let initialize_call = millau_runtime::BridgeGrandpaCall::< + millau_runtime::Runtime, + millau_runtime::RialtoGrandpaInstance, + >::initialize { + init_data, + }; + millau_runtime::SudoCall::sudo { call: Box::new(initialize_call.into()) }.into() + } +} + +impl BridgeInitializer for WestendToMillauCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + // at Westend -> Millau initialization we're not using sudo, because otherwise + // our deployments may fail, because we need to initialize both Rialto -> Millau + // and Westend -> Millau bridge. => since there's single possible sudo account, + // one of transaction may fail with duplicate nonce error + millau_runtime::BridgeGrandpaCall::< + millau_runtime::Runtime, + millau_runtime::WestendGrandpaInstance, + >::initialize { + init_data, + } + .into() + } +} + +impl BridgeInitializer for RococoToWococoCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + relay_wococo_client::runtime::Call::BridgeGrandpaRococo( + relay_wococo_client::runtime::BridgeGrandpaRococoCall::initialize(init_data), + ) + } +} + +impl BridgeInitializer for WococoToRococoCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + relay_rococo_client::runtime::Call::BridgeGrandpaWococo( + relay_rococo_client::runtime::BridgeGrandpaWococoCall::initialize(init_data), + ) + } +} + +impl BridgeInitializer for KusamaToPolkadotCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + relay_polkadot_client::runtime::Call::BridgeKusamaGrandpa( + relay_polkadot_client::runtime::BridgeKusamaGrandpaCall::initialize(init_data), + ) + } +} + +impl BridgeInitializer for PolkadotToKusamaCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + relay_kusama_client::runtime::Call::BridgePolkadotGrandpa( + relay_kusama_client::runtime::BridgePolkadotGrandpaCall::initialize(init_data), + ) + } } impl InitBridge { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { - select_bridge!(self.bridge, { - let source_client = self.source.to_client::().await?; - let target_client = self.target.to_client::().await?; - let target_sign = self.target_sign.to_keypair::()?; - - let (spec_version, transaction_version) = - target_client.simple_runtime_version().await?; - substrate_relay_helper::finality::initialize::initialize::( - source_client, - target_client.clone(), - target_sign.public().into(), - move |transaction_nonce, initialization_data| { - Ok(Bytes( - Target::sign_transaction(SignParam { - spec_version, - transaction_version, - genesis_hash: *target_client.genesis_hash(), - signer: target_sign, - era: relay_substrate_client::TransactionEra::immortal(), - unsigned: UnsignedTransaction::new( - encode_init_bridge(initialization_data).into(), - transaction_nonce, - ), - })? - .encode(), - )) - }, - ) - .await; - - Ok(()) - }) + match self.bridge { + InitBridgeName::MillauToRialto => MillauToRialtoCliBridge::init_bridge(self), + InitBridgeName::RialtoToMillau => RialtoToMillauCliBridge::init_bridge(self), + InitBridgeName::WestendToMillau => WestendToMillauCliBridge::init_bridge(self), + InitBridgeName::RococoToWococo => RococoToWococoCliBridge::init_bridge(self), + InitBridgeName::WococoToRococo => WococoToRococoCliBridge::init_bridge(self), + InitBridgeName::KusamaToPolkadot => KusamaToPolkadotCliBridge::init_bridge(self), + InitBridgeName::PolkadotToKusama => PolkadotToKusamaCliBridge::init_bridge(self), + InitBridgeName::MillauToRialtoParachain => + MillauToRialtoParachainCliBridge::init_bridge(self), + } + .await } } diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers.rs b/bridges/relays/bin-substrate/src/cli/relay_headers.rs index 59ab3a1a33..4ad43c3c24 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use async_trait::async_trait; +use relay_substrate_client::{AccountKeyPairOf, ChainBase}; +use sp_core::Pair; use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; @@ -21,6 +24,11 @@ use relay_utils::metrics::{GlobalMetrics, StandaloneMetric}; use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline; use crate::cli::{ + bridge::{ + CliBridge, KusamaToPolkadotCliBridge, MillauToRialtoCliBridge, + MillauToRialtoParachainCliBridge, PolkadotToKusamaCliBridge, RialtoToMillauCliBridge, + RococoToWococoCliBridge, WestendToMillauCliBridge, WococoToRococoCliBridge, + }, PrometheusParams, SourceConnectionParams, TargetConnectionParams, TargetSigningParams, }; @@ -58,101 +66,66 @@ pub enum RelayHeadersBridge { MillauToRialtoParachain, } -macro_rules! select_bridge { - ($bridge: expr, $generic: tt) => { - match $bridge { - RelayHeadersBridge::MillauToRialto => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_client::Rialto; - type Finality = crate::chains::millau_headers_to_rialto::MillauFinalityToRialto; +#[async_trait] +trait HeadersRelayer: CliBridge +where + ::AccountId: From< as Pair>::Public>, +{ + /// Relay headers. + async fn relay_headers(data: RelayHeaders) -> anyhow::Result<()> { + let source_client = data.source.to_client::().await?; + let target_client = data.target.to_client::().await?; + let target_transactions_mortality = data.target_sign.target_transactions_mortality; + let target_sign = data.target_sign.to_keypair::()?; - $generic - }, - RelayHeadersBridge::RialtoToMillau => { - type Source = relay_rialto_client::Rialto; - type Target = relay_millau_client::Millau; - type Finality = crate::chains::rialto_headers_to_millau::RialtoFinalityToMillau; + let metrics_params: relay_utils::metrics::MetricsParams = data.prometheus_params.into(); + GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?; - $generic - }, - RelayHeadersBridge::WestendToMillau => { - type Source = relay_westend_client::Westend; - type Target = relay_millau_client::Millau; - type Finality = crate::chains::westend_headers_to_millau::WestendFinalityToMillau; + let target_transactions_params = substrate_relay_helper::TransactionParams { + signer: target_sign, + mortality: target_transactions_mortality, + }; + Self::Finality::start_relay_guards( + &target_client, + &target_transactions_params, + data.target.can_start_version_guard(), + ) + .await?; - $generic - }, - RelayHeadersBridge::RococoToWococo => { - type Source = relay_rococo_client::Rococo; - type Target = relay_wococo_client::Wococo; - type Finality = crate::chains::rococo_headers_to_wococo::RococoFinalityToWococo; - - $generic - }, - RelayHeadersBridge::WococoToRococo => { - type Source = relay_wococo_client::Wococo; - type Target = relay_rococo_client::Rococo; - type Finality = crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo; - - $generic - }, - RelayHeadersBridge::KusamaToPolkadot => { - type Source = relay_kusama_client::Kusama; - type Target = relay_polkadot_client::Polkadot; - type Finality = crate::chains::kusama_headers_to_polkadot::KusamaFinalityToPolkadot; - - $generic - }, - RelayHeadersBridge::PolkadotToKusama => { - type Source = relay_polkadot_client::Polkadot; - type Target = relay_kusama_client::Kusama; - type Finality = crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama; - - $generic - }, - RelayHeadersBridge::MillauToRialtoParachain => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_parachain_client::RialtoParachain; - type Finality = crate::chains::millau_headers_to_rialto_parachain::MillauFinalityToRialtoParachain; - - $generic - - }, - } - }; + substrate_relay_helper::finality::run::( + source_client, + target_client, + data.only_mandatory_headers, + target_transactions_params, + metrics_params, + ) + .await + } } +impl HeadersRelayer for MillauToRialtoCliBridge {} +impl HeadersRelayer for RialtoToMillauCliBridge {} +impl HeadersRelayer for WestendToMillauCliBridge {} +impl HeadersRelayer for RococoToWococoCliBridge {} +impl HeadersRelayer for WococoToRococoCliBridge {} +impl HeadersRelayer for KusamaToPolkadotCliBridge {} +impl HeadersRelayer for PolkadotToKusamaCliBridge {} +impl HeadersRelayer for MillauToRialtoParachainCliBridge {} + impl RelayHeaders { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { - select_bridge!(self.bridge, { - let source_client = self.source.to_client::().await?; - let target_client = self.target.to_client::().await?; - let target_transactions_mortality = self.target_sign.target_transactions_mortality; - let target_sign = self.target_sign.to_keypair::()?; - - let metrics_params: relay_utils::metrics::MetricsParams = self.prometheus_params.into(); - GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?; - - let target_transactions_params = substrate_relay_helper::TransactionParams { - signer: target_sign, - mortality: target_transactions_mortality, - }; - Finality::start_relay_guards( - &target_client, - &target_transactions_params, - self.target.can_start_version_guard(), - ) - .await?; - - substrate_relay_helper::finality::run::( - source_client, - target_client, - self.only_mandatory_headers, - target_transactions_params, - metrics_params, - ) - .await - }) + match self.bridge { + RelayHeadersBridge::MillauToRialto => MillauToRialtoCliBridge::relay_headers(self), + RelayHeadersBridge::RialtoToMillau => RialtoToMillauCliBridge::relay_headers(self), + RelayHeadersBridge::WestendToMillau => WestendToMillauCliBridge::relay_headers(self), + RelayHeadersBridge::RococoToWococo => RococoToWococoCliBridge::relay_headers(self), + RelayHeadersBridge::WococoToRococo => WococoToRococoCliBridge::relay_headers(self), + RelayHeadersBridge::KusamaToPolkadot => KusamaToPolkadotCliBridge::relay_headers(self), + RelayHeadersBridge::PolkadotToKusama => PolkadotToKusamaCliBridge::relay_headers(self), + RelayHeadersBridge::MillauToRialtoParachain => + MillauToRialtoParachainCliBridge::relay_headers(self), + } + .await } } diff --git a/bridges/relays/bin-substrate/src/cli/relay_parachains.rs b/bridges/relays/bin-substrate/src/cli/relay_parachains.rs index 4714f1cc5a..eb46909b3a 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_parachains.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_parachains.rs @@ -14,18 +14,29 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use async_trait::async_trait; use bp_polkadot_core::parachains::ParaId; -use parachains_relay::{parachains_loop::ParachainSyncParams, ParachainsPipeline}; +use pallet_bridge_parachains::RelayBlockNumber; +use parachains_relay::{ + parachains_loop::{ParachainSyncParams, SourceClient, TargetClient}, + ParachainsPipeline, +}; +use relay_substrate_client::{Chain, RelayChain}; use relay_utils::metrics::{GlobalMetrics, StandaloneMetric}; use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; use substrate_relay_helper::{ - parachains::{source::ParachainsSource, target::ParachainsTarget}, + parachains::{ + source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter, + SubstrateParachainsPipeline, + }, TransactionParams, }; use crate::cli::{ - PrometheusParams, SourceConnectionParams, TargetConnectionParams, TargetSigningParams, + bridge::{CliBridgeBase, RialtoParachainToMillauCliBridge, WestmintToMillauCliBridge}, + CliChain, PrometheusParams, SourceConnectionParams, TargetConnectionParams, + TargetSigningParams, }; /// Start parachain heads relayer process. @@ -52,57 +63,72 @@ pub enum RelayParachainsBridge { WestendToMillau, } -macro_rules! select_bridge { - ($bridge: expr, $generic: tt) => { - match $bridge { - RelayParachainsBridge::RialtoToMillau => { - use crate::chains::rialto_parachains_to_millau::RialtoParachainsToMillau as Pipeline; +#[async_trait] +trait ParachainsRelayer: CliBridgeBase +where + ParachainsSource: SourceClient>, + ParachainsTarget: TargetClient>, +{ + type SourceRelay: Chain + CliChain + RelayChain; + type Pipeline: SubstrateParachainsPipeline< + SourceParachain = Self::Source, + TargetChain = Self::Target, + SourceRelayChain = Self::SourceRelay, + TransactionSignScheme = Self::Target, + > + ParachainsPipeline; - $generic - }, - RelayParachainsBridge::WestendToMillau => { - use crate::chains::westend_parachains_to_millau::WestendParachainsToMillau as Pipeline; + async fn relay_headers(data: RelayParachains) -> anyhow::Result<()> { + let source_client = data.source.to_client::().await?; + let source_client = ParachainsSource::::new(source_client, None); - $generic + let target_transaction_params = TransactionParams { + signer: data.target_sign.to_keypair::()?, + mortality: data.target_sign.target_transactions_mortality, + }; + let target_client = data.target.to_client::().await?; + let target_client = ParachainsTarget::::new( + target_client.clone(), + target_transaction_params, + ); + + let metrics_params: relay_utils::metrics::MetricsParams = data.prometheus_params.into(); + GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?; + + parachains_relay::parachains_loop::run( + source_client, + target_client, + ParachainSyncParams { + parachains: vec![ParaId(2000)], + stall_timeout: std::time::Duration::from_secs(60), + strategy: parachains_relay::parachains_loop::ParachainSyncStrategy::Any, }, - } - }; + metrics_params, + futures::future::pending(), + ) + .await + .map_err(|e| anyhow::format_err!("{}", e)) + } +} + +impl ParachainsRelayer for RialtoParachainToMillauCliBridge { + type SourceRelay = relay_rialto_client::Rialto; + type Pipeline = crate::chains::rialto_parachains_to_millau::RialtoParachainsToMillau; +} + +impl ParachainsRelayer for WestmintToMillauCliBridge { + type SourceRelay = relay_westend_client::Westend; + type Pipeline = crate::chains::westend_parachains_to_millau::WestendParachainsToMillau; } impl RelayParachains { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { - select_bridge!(self.bridge, { - type SourceChain = ::SourceChain; - type TargetChain = ::TargetChain; - - let source_client = self.source.to_client::().await?; - let source_client = ParachainsSource::::new(source_client, None); - - let taret_transaction_params = TransactionParams { - signer: self.target_sign.to_keypair::()?, - mortality: self.target_sign.target_transactions_mortality, - }; - let target_client = self.target.to_client::().await?; - let target_client = - ParachainsTarget::::new(target_client.clone(), taret_transaction_params); - - let metrics_params: relay_utils::metrics::MetricsParams = self.prometheus_params.into(); - GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?; - - parachains_relay::parachains_loop::run( - source_client, - target_client, - ParachainSyncParams { - parachains: vec![ParaId(2000)], - stall_timeout: std::time::Duration::from_secs(60), - strategy: parachains_relay::parachains_loop::ParachainSyncStrategy::Any, - }, - metrics_params, - futures::future::pending(), - ) - .await - .map_err(|e| anyhow::format_err!("{}", e)) - }) + match self.bridge { + RelayParachainsBridge::RialtoToMillau => + RialtoParachainToMillauCliBridge::relay_headers(self), + RelayParachainsBridge::WestendToMillau => + WestmintToMillauCliBridge::relay_headers(self), + } + .await } }