diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs index 83a19f88c2788..a962aa674c7a6 100644 --- a/bridges/relays/bin-substrate/src/cli/bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/bridge.rs @@ -48,6 +48,7 @@ macro_rules! select_full_bridge { match $bridge { FullBridge::MillauToRialto => { type Source = relay_millau_client::Millau; + #[allow(dead_code)] type Target = relay_rialto_client::Rialto; #[allow(unused_imports)] @@ -60,6 +61,7 @@ macro_rules! select_full_bridge { } FullBridge::RialtoToMillau => { type Source = relay_rialto_client::Rialto; + #[allow(dead_code)] type Target = relay_millau_client::Millau; #[allow(unused_imports)] diff --git a/bridges/relays/bin-substrate/src/cli/encode_message.rs b/bridges/relays/bin-substrate/src/cli/encode_message.rs new file mode 100644 index 0000000000000..5ef668864ea56 --- /dev/null +++ b/bridges/relays/bin-substrate/src/cli/encode_message.rs @@ -0,0 +1,106 @@ +// 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 crate::cli::{bridge::FullBridge, AccountId, CliChain, HexBytes}; +use crate::select_full_bridge; +use structopt::StructOpt; + +/// Generic message payload. +#[derive(StructOpt, Debug)] +pub enum MessagePayload { + /// Raw, SCALE-encoded `MessagePayload`. + Raw { + /// Hex-encoded SCALE data. + data: HexBytes, + }, + /// Construct message to send over the bridge. + Call { + /// Message details. + #[structopt(flatten)] + call: crate::cli::encode_call::Call, + /// SS58 encoded Source account that will send the payload. + #[structopt(long)] + sender: AccountId, + }, +} + +/// A `MessagePayload` to encode. +#[derive(StructOpt)] +pub struct EncodeMessage { + /// A bridge instance to initalize. + #[structopt(possible_values = &FullBridge::variants(), case_insensitive = true)] + bridge: FullBridge, + #[structopt(flatten)] + payload: MessagePayload, +} + +impl EncodeMessage { + /// Run the command. + pub fn encode(self) -> anyhow::Result { + select_full_bridge!(self.bridge, { + let payload = Source::encode_message(self.payload).map_err(|e| anyhow::format_err!("{}", e))?; + Ok(HexBytes::encode(&payload)) + }) + } + + /// Run the command. + pub async fn run(self) -> anyhow::Result<()> { + let payload = self.encode()?; + println!("{:?}", payload); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::crypto::Ss58Codec; + + #[test] + fn should_encode_raw_message() { + // given + let msg = "01000000e88514000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d3c040130000000000000000000000000"; + let encode_message = EncodeMessage::from_iter(vec!["encode-message", "MillauToRialto", "raw", msg]); + + // when + let hex = encode_message.encode().unwrap(); + + // then + assert_eq!(format!("{:?}", hex), format!("0x{}", msg)); + } + + #[test] + fn should_encode_remark_with_size() { + // given + let sender = sp_keyring::AccountKeyring::Alice.to_account_id().to_ss58check(); + let encode_message = EncodeMessage::from_iter(vec![ + "encode-message", + "RialtoToMillau", + "call", + "--sender", + &sender, + "remark", + "--remark-size", + "12", + ]); + + // when + let hex = encode_message.encode().unwrap(); + + // then + assert_eq!(format!("{:?}", hex), "0x01000000e88514000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d3c040130000000000000000000000000"); + } +} diff --git a/bridges/relays/bin-substrate/src/cli/mod.rs b/bridges/relays/bin-substrate/src/cli/mod.rs index 0ddee88aeef0a..e291f7247020a 100644 --- a/bridges/relays/bin-substrate/src/cli/mod.rs +++ b/bridges/relays/bin-substrate/src/cli/mod.rs @@ -27,6 +27,7 @@ use structopt::{clap::arg_enum, StructOpt}; pub(crate) mod bridge; pub(crate) mod encode_call; +pub(crate) mod encode_message; mod derive_account; mod init_bridge; @@ -71,7 +72,7 @@ pub enum Command { /// /// The `MessagePayload` can be then fed to `Messages::send_message` function and sent over /// the bridge. - EncodeMessagePayload(EncodeMessagePayload), + EncodeMessage(encode_message::EncodeMessage), /// Estimate Delivery and Dispatch Fee required for message submission to messages pallet. EstimateFee(EstimateFee), /// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain. @@ -87,7 +88,7 @@ impl Command { Self::InitBridge(arg) => arg.run().await?, Self::SendMessage(arg) => arg.run().await?, Self::EncodeCall(arg) => arg.run().await?, - Self::EncodeMessagePayload(arg) => arg.run().await?, + Self::EncodeMessage(arg) => arg.run().await?, Self::EstimateFee(arg) => arg.run().await?, Self::DeriveAccount(arg) => arg.run().await?, } @@ -112,23 +113,6 @@ impl SendMessage { } } -/// A `MessagePayload` to encode. -#[derive(StructOpt)] -pub enum EncodeMessagePayload { - #[structopt(flatten)] - RialtoMillau(rialto_millau::EncodeMessagePayload), -} - -impl EncodeMessagePayload { - /// Run the command. - pub async fn run(self) -> anyhow::Result<()> { - match self { - Self::RialtoMillau(arg) => arg.run().await?, - } - Ok(()) - } -} - /// Estimate Delivery & Dispatch Fee command. #[derive(StructOpt)] pub enum EstimateFee { @@ -260,7 +244,7 @@ pub trait CliChain: relay_substrate_client::Chain { fn ss58_format() -> u16; /// Construct message payload to be sent over the bridge. - fn encode_message(message: crate::rialto_millau::cli::MessagePayload) -> Result; + fn encode_message(message: crate::cli::encode_message::MessagePayload) -> Result; /// Maximal extrinsic weight (from the runtime). fn max_extrinsic_weight() -> Weight; diff --git a/bridges/relays/bin-substrate/src/rialto_millau/cli.rs b/bridges/relays/bin-substrate/src/rialto_millau/cli.rs index 9e5788b1cb69d..4c92ec1773841 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/cli.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/cli.rs @@ -20,8 +20,7 @@ use frame_support::weights::Weight; use structopt::StructOpt; use crate::cli::{ - AccountId, Balance, ExplicitOrMaximal, HexBytes, HexLaneId, Origins, SourceConnectionParams, SourceSigningParams, - TargetSigningParams, + Balance, ExplicitOrMaximal, HexLaneId, Origins, SourceConnectionParams, SourceSigningParams, TargetSigningParams, }; /// Send bridge message. @@ -89,31 +88,6 @@ impl SendMessage { } } -/// A `MessagePayload` to encode. -/// -/// TODO [#855] Move to separate module. -#[derive(StructOpt)] -pub enum EncodeMessagePayload { - /// Message Payload of Rialto to Millau call. - RialtoToMillau { - #[structopt(flatten)] - payload: MessagePayload, - }, - /// Message Payload of Millau to Rialto call. - MillauToRialto { - #[structopt(flatten)] - payload: MessagePayload, - }, -} - -impl EncodeMessagePayload { - /// Run the command. - pub async fn run(self) -> anyhow::Result<()> { - super::run_encode_message_payload(self).await.map_err(format_err)?; - Ok(()) - } -} - /// Estimate Delivery & Dispatch Fee command. /// /// TODO [#855] Move to separate module. @@ -128,7 +102,7 @@ pub enum EstimateFee { lane: HexLaneId, /// Payload to send over the bridge. #[structopt(flatten)] - payload: MessagePayload, + payload: crate::cli::encode_message::MessagePayload, }, /// Estimate fee of Rialto to Millau message. MillauToRialto { @@ -139,7 +113,7 @@ pub enum EstimateFee { lane: HexLaneId, /// Payload to send over the bridge. #[structopt(flatten)] - payload: MessagePayload, + payload: crate::cli::encode_message::MessagePayload, }, } @@ -154,22 +128,3 @@ impl EstimateFee { fn format_err(err: String) -> anyhow::Error { anyhow::anyhow!(err) } - -/// Generic message payload. -#[derive(StructOpt, Debug)] -pub enum MessagePayload { - /// Raw, SCALE-encoded `MessagePayload`. - Raw { - /// Hex-encoded SCALE data. - data: HexBytes, - }, - /// Construct message to send over the bridge. - Call { - /// Message details. - #[structopt(flatten)] - call: crate::cli::encode_call::Call, - /// SS58 encoded account that will send the payload (must have SS58Prefix = 42) - #[structopt(long)] - sender: AccountId, - }, -} diff --git a/bridges/relays/bin-substrate/src/rialto_millau/mod.rs b/bridges/relays/bin-substrate/src/rialto_millau/mod.rs index 13e8bc19c3717..d6e49ccf2cc2e 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/mod.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/mod.rs @@ -31,7 +31,7 @@ pub type RialtoClient = relay_substrate_client::Client; use crate::cli::{ bridge::{MILLAU_TO_RIALTO_INDEX, RIALTO_TO_MILLAU_INDEX}, encode_call::{self, Call, CliEncodeCall}, - CliChain, ExplicitOrMaximal, HexBytes, Origins, + encode_message, CliChain, ExplicitOrMaximal, HexBytes, Origins, }; use codec::{Decode, Encode}; use frame_support::weights::{GetDispatchInfo, Weight}; @@ -267,24 +267,6 @@ async fn run_send_message(command: cli::SendMessage) -> Result<(), String> { Ok(()) } -async fn run_encode_message_payload(call: cli::EncodeMessagePayload) -> Result<(), String> { - match call { - cli::EncodeMessagePayload::RialtoToMillau { payload } => { - type Source = Rialto; - - let payload = Source::encode_message(payload)?; - println!("{:?}", HexBytes::encode(&payload)); - } - cli::EncodeMessagePayload::MillauToRialto { payload } => { - type Source = Millau; - - let payload = Source::encode_message(payload)?; - println!("{:?}", HexBytes::encode(&payload)); - } - } - Ok(()) -} - async fn run_estimate_fee(cmd: cli::EstimateFee) -> Result<(), String> { match cmd { cli::EstimateFee::RialtoToMillau { source, lane, payload } => { @@ -459,11 +441,11 @@ impl CliChain for Millau { } // TODO [#854|#843] support multiple bridges? - fn encode_message(message: cli::MessagePayload) -> Result { + fn encode_message(message: encode_message::MessagePayload) -> Result { match message { - cli::MessagePayload::Raw { data } => MessagePayload::decode(&mut &*data.0) + encode_message::MessagePayload::Raw { data } => MessagePayload::decode(&mut &*data.0) .map_err(|e| format!("Failed to decode Millau's MessagePayload: {:?}", e)), - cli::MessagePayload::Call { mut call, mut sender } => { + encode_message::MessagePayload::Call { mut call, mut sender } => { type Source = Millau; type Target = Rialto; @@ -529,11 +511,11 @@ impl CliChain for Rialto { bp_rialto::max_extrinsic_weight() } - fn encode_message(message: cli::MessagePayload) -> Result { + fn encode_message(message: encode_message::MessagePayload) -> Result { match message { - cli::MessagePayload::Raw { data } => MessagePayload::decode(&mut &*data.0) + encode_message::MessagePayload::Raw { data } => MessagePayload::decode(&mut &*data.0) .map_err(|e| format!("Failed to decode Rialto's MessagePayload: {:?}", e)), - cli::MessagePayload::Call { mut call, mut sender } => { + encode_message::MessagePayload::Call { mut call, mut sender } => { type Source = Rialto; type Target = Millau; @@ -564,7 +546,7 @@ impl CliChain for Westend { 0 } - fn encode_message(_message: cli::MessagePayload) -> Result { + fn encode_message(_message: encode_message::MessagePayload) -> Result { Err("Sending messages from Westend is not yet supported.".into()) } }