Skip to content

Commit

Permalink
CLI: Encode Message (paritytech#889)
Browse files Browse the repository at this point in the history
* Encode message.

* Update docs related to `sender`

Co-authored-by: Svyatoslav Nikolsky <svyatonik@gmail.com>
Co-authored-by: Hernando Castano <hernando@hcastano.com>
  • Loading branch information
3 people authored and serban300 committed Apr 9, 2024
1 parent 9c81bb6 commit 70e5784
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 94 deletions.
2 changes: 2 additions & 0 deletions bridges/relays/bin-substrate/src/cli/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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)]
Expand Down
106 changes: 106 additions & 0 deletions bridges/relays/bin-substrate/src/cli/encode_message.rs
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

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<HexBytes> {
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");
}
}
24 changes: 4 additions & 20 deletions bridges/relays/bin-substrate/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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?,
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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<Self::MessagePayload, String>;
fn encode_message(message: crate::cli::encode_message::MessagePayload) -> Result<Self::MessagePayload, String>;

/// Maximal extrinsic weight (from the runtime).
fn max_extrinsic_weight() -> Weight;
Expand Down
51 changes: 3 additions & 48 deletions bridges/relays/bin-substrate/src/rialto_millau/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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 {
Expand All @@ -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,
},
}

Expand All @@ -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,
},
}
34 changes: 8 additions & 26 deletions bridges/relays/bin-substrate/src/rialto_millau/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub type RialtoClient = relay_substrate_client::Client<Rialto>;
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};
Expand Down Expand Up @@ -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 } => {
Expand Down Expand Up @@ -459,11 +441,11 @@ impl CliChain for Millau {
}

// TODO [#854|#843] support multiple bridges?
fn encode_message(message: cli::MessagePayload) -> Result<Self::MessagePayload, String> {
fn encode_message(message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> {
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;

Expand Down Expand Up @@ -529,11 +511,11 @@ impl CliChain for Rialto {
bp_rialto::max_extrinsic_weight()
}

fn encode_message(message: cli::MessagePayload) -> Result<Self::MessagePayload, String> {
fn encode_message(message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> {
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;

Expand Down Expand Up @@ -564,7 +546,7 @@ impl CliChain for Westend {
0
}

fn encode_message(_message: cli::MessagePayload) -> Result<Self::MessagePayload, String> {
fn encode_message(_message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> {
Err("Sending messages from Westend is not yet supported.".into())
}
}
Expand Down

0 comments on commit 70e5784

Please sign in to comment.