diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs new file mode 100644 index 0000000000..83a19f88c2 --- /dev/null +++ b/bridges/relays/bin-substrate/src/cli/bridge.rs @@ -0,0 +1,75 @@ +// 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 . + +use structopt::clap::arg_enum; + +arg_enum! { + #[derive(Debug)] + /// Supported full bridges (headers + messages). + pub enum FullBridge { + MillauToRialto, + RialtoToMillau, + } +} + +impl FullBridge { + /// Return instance index of the bridge pallet in source runtime. + pub fn bridge_instance_index(&self) -> u8 { + match self { + Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX, + Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX, + } + } +} + +pub const RIALTO_TO_MILLAU_INDEX: u8 = 0; +pub const MILLAU_TO_RIALTO_INDEX: u8 = 0; + +/// The macro allows executing bridge-specific code without going fully generic. +/// +/// It matches on the [`FullBridge`] enum, sets bridge-specific types or imports and injects +/// the `$generic` code at every variant. +#[macro_export] +macro_rules! select_full_bridge { + ($bridge: expr, $generic: tt) => { + match $bridge { + FullBridge::MillauToRialto => { + type Source = relay_millau_client::Millau; + type Target = relay_rialto_client::Rialto; + + #[allow(unused_imports)] + use bp_millau::derive_account_from_rialto_id as derive_account; + + #[allow(unused_imports)] + use crate::rialto_millau::millau_messages_to_rialto::run as relay_messages; + + $generic + } + FullBridge::RialtoToMillau => { + type Source = relay_rialto_client::Rialto; + type Target = relay_millau_client::Millau; + + #[allow(unused_imports)] + use bp_rialto::derive_account_from_millau_id as derive_account; + + #[allow(unused_imports)] + use crate::rialto_millau::rialto_messages_to_millau::run as relay_messages; + + $generic + } + } + }; +} diff --git a/bridges/relays/bin-substrate/src/cli/derive_account.rs b/bridges/relays/bin-substrate/src/cli/derive_account.rs index cd40fb5891..92b32b0d47 100644 --- a/bridges/relays/bin-substrate/src/cli/derive_account.rs +++ b/bridges/relays/bin-substrate/src/cli/derive_account.rs @@ -14,9 +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::AccountId; +use crate::cli::{bridge::FullBridge, AccountId}; +use crate::select_full_bridge; use relay_substrate_client::Chain; -use structopt::{clap::arg_enum, StructOpt}; +use structopt::StructOpt; /// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain. /// @@ -27,52 +28,18 @@ use structopt::{clap::arg_enum, StructOpt}; #[derive(StructOpt)] pub struct DeriveAccount { /// A bridge instance to initalize. - #[structopt(possible_values = &DeriveAccountBridge::variants(), case_insensitive = true)] - bridge: DeriveAccountBridge, + #[structopt(possible_values = &FullBridge::variants(), case_insensitive = true)] + bridge: FullBridge, /// Source-chain address to derive Target-chain address from. account: AccountId, } -arg_enum! { - #[derive(Debug)] - /// Bridge to derive account for. - pub enum DeriveAccountBridge { - MillauToRialto, - RialtoToMillau, - } -} - -macro_rules! select_bridge { - ($bridge: expr, $generic: tt) => { - match $bridge { - DeriveAccountBridge::MillauToRialto => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_client::Rialto; - - #[allow(unused_imports)] // the import is not used in `run` - use bp_millau::derive_account_from_rialto_id as derive_account; - - $generic - } - DeriveAccountBridge::RialtoToMillau => { - type Source = relay_rialto_client::Rialto; - type Target = relay_millau_client::Millau; - - #[allow(unused_imports)] // the import is not used in `run`. - use bp_rialto::derive_account_from_millau_id as derive_account; - - $generic - } - } - }; -} - impl DeriveAccount { /// Parse CLI arguments and derive account. /// /// Returns both the Source account in correct SS58 format and the derived account. fn derive_account(&self) -> (AccountId, AccountId) { - select_bridge!(self.bridge, { + select_full_bridge!(self.bridge, { let mut account = self.account.clone(); account.enforce_chain::(); let acc = bp_runtime::SourceAccount::Account(account.raw_id()); @@ -84,7 +51,7 @@ impl DeriveAccount { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { - select_bridge!(self.bridge, { + select_full_bridge!(self.bridge, { let (account, derived_account) = self.derive_account(); println!("Source address:\n{} ({})", account, Source::NAME); println!( diff --git a/bridges/relays/bin-substrate/src/cli/encode_call.rs b/bridges/relays/bin-substrate/src/cli/encode_call.rs index 1a2c8ebfb2..1f7861f21a 100644 --- a/bridges/relays/bin-substrate/src/cli/encode_call.rs +++ b/bridges/relays/bin-substrate/src/cli/encode_call.rs @@ -14,17 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::cli::bridge::FullBridge; use crate::cli::{AccountId, Balance, CliChain, ExplicitOrMaximal, HexBytes, HexLaneId}; +use crate::select_full_bridge; use frame_support::dispatch::GetDispatchInfo; use relay_substrate_client::Chain; -use structopt::{clap::arg_enum, StructOpt}; +use structopt::StructOpt; /// Encode source chain runtime call. #[derive(StructOpt, Debug)] pub struct EncodeCall { /// A bridge instance to encode call for. - #[structopt(possible_values = &EncodeCallBridge::variants(), case_insensitive = true)] - bridge: EncodeCallBridge, + #[structopt(possible_values = &FullBridge::variants(), case_insensitive = true)] + bridge: FullBridge, #[structopt(flatten)] call: Call, } @@ -85,49 +87,9 @@ pub trait CliEncodeCall: Chain { fn encode_call(call: &Call) -> anyhow::Result; } -arg_enum! { - #[derive(Debug)] - /// Bridge to encode call for. - pub enum EncodeCallBridge { - MillauToRialto, - RialtoToMillau, - } -} - -impl EncodeCallBridge { - fn bridge_instance_index(&self) -> u8 { - match self { - Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX, - Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX, - } - } -} - -pub const RIALTO_TO_MILLAU_INDEX: u8 = 0; -pub const MILLAU_TO_RIALTO_INDEX: u8 = 0; - -macro_rules! select_bridge { - ($bridge: expr, $generic: tt) => { - match $bridge { - EncodeCallBridge::MillauToRialto => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_client::Rialto; - - $generic - } - EncodeCallBridge::RialtoToMillau => { - type Source = relay_rialto_client::Rialto; - type Target = relay_millau_client::Millau; - - $generic - } - } - }; -} - impl EncodeCall { fn encode(&mut self) -> anyhow::Result { - select_bridge!(self.bridge, { + select_full_bridge!(self.bridge, { preprocess_call::(&mut self.call, self.bridge.bridge_instance_index()); let call = Source::encode_call(&self.call)?; diff --git a/bridges/relays/bin-substrate/src/cli/mod.rs b/bridges/relays/bin-substrate/src/cli/mod.rs index ebceb3a25e..0ddee88aee 100644 --- a/bridges/relays/bin-substrate/src/cli/mod.rs +++ b/bridges/relays/bin-substrate/src/cli/mod.rs @@ -25,6 +25,7 @@ use frame_support::weights::Weight; use sp_runtime::app_crypto::Ss58Codec; use structopt::{clap::arg_enum, StructOpt}; +pub(crate) mod bridge; pub(crate) mod encode_call; mod derive_account; diff --git a/bridges/relays/bin-substrate/src/cli/relay_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_messages.rs index 72a194ef90..feedea66ef 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_messages.rs @@ -14,18 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use crate::cli::bridge::FullBridge; use crate::cli::{ HexLaneId, PrometheusParams, SourceConnectionParams, SourceSigningParams, TargetConnectionParams, TargetSigningParams, }; -use structopt::{clap::arg_enum, StructOpt}; +use crate::select_full_bridge; +use structopt::StructOpt; /// Start messages relayer process. #[derive(StructOpt)] pub struct RelayMessages { /// A bridge instance to relay messages for. - #[structopt(possible_values = &RelayMessagesBridge::variants(), case_insensitive = true)] - bridge: RelayMessagesBridge, + #[structopt(possible_values = &FullBridge::variants(), case_insensitive = true)] + bridge: FullBridge, /// Hex-encoded lane id that should be served by the relay. Defaults to `00000000`. #[structopt(long, default_value = "00000000")] lane: HexLaneId, @@ -41,46 +43,16 @@ pub struct RelayMessages { prometheus_params: PrometheusParams, } -arg_enum! { - #[derive(Debug)] - /// Headers relay bridge. - pub enum RelayMessagesBridge { - MillauToRialto, - RialtoToMillau, - } -} - -macro_rules! select_bridge { - ($bridge: expr, $generic: tt) => { - match $bridge { - RelayMessagesBridge::MillauToRialto => { - type Source = relay_millau_client::Millau; - type Target = relay_rialto_client::Rialto; - use crate::rialto_millau::millau_messages_to_rialto::run; - - $generic - } - RelayMessagesBridge::RialtoToMillau => { - type Source = relay_rialto_client::Rialto; - type Target = relay_millau_client::Millau; - use crate::rialto_millau::rialto_messages_to_millau::run; - - $generic - } - } - }; -} - impl RelayMessages { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { - select_bridge!(self.bridge, { + select_full_bridge!(self.bridge, { let source_client = self.source.into_client::().await?; let source_sign = self.source_sign.into_keypair::()?; let target_client = self.target.into_client::().await?; let target_sign = self.target_sign.into_keypair::()?; - run( + relay_messages( source_client, source_sign, target_client, diff --git a/bridges/relays/bin-substrate/src/rialto_millau/mod.rs b/bridges/relays/bin-substrate/src/rialto_millau/mod.rs index a39053aa4f..13e8bc19c3 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/mod.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/mod.rs @@ -29,7 +29,8 @@ pub type MillauClient = relay_substrate_client::Client; pub type RialtoClient = relay_substrate_client::Client; use crate::cli::{ - encode_call::{self, Call, CliEncodeCall, MILLAU_TO_RIALTO_INDEX, RIALTO_TO_MILLAU_INDEX}, + bridge::{MILLAU_TO_RIALTO_INDEX, RIALTO_TO_MILLAU_INDEX}, + encode_call::{self, Call, CliEncodeCall}, CliChain, ExplicitOrMaximal, HexBytes, Origins, }; use codec::{Decode, Encode}; @@ -426,7 +427,7 @@ impl CliEncodeCall for Millau { fee, bridge_instance_index, } => match *bridge_instance_index { - encode_call::MILLAU_TO_RIALTO_INDEX => { + MILLAU_TO_RIALTO_INDEX => { let payload = Decode::decode(&mut &*payload.0)?; millau_runtime::Call::BridgeRialtoMessages(millau_runtime::MessagesCall::send_message( lane.0, @@ -499,7 +500,7 @@ impl CliEncodeCall for Rialto { fee, bridge_instance_index, } => match *bridge_instance_index { - encode_call::RIALTO_TO_MILLAU_INDEX => { + RIALTO_TO_MILLAU_INDEX => { let payload = Decode::decode(&mut &*payload.0)?; rialto_runtime::Call::BridgeMillauMessages(rialto_runtime::MessagesCall::send_message( lane.0, payload, fee.0,