CLI: Encode Message (#889)

* Encode message.

* Update docs related to `sender`

Co-authored-by: Svyatoslav Nikolsky <svyatonik@gmail.com>
Co-authored-by: Hernando Castano <hernando@hcastano.com>
This commit is contained in:
Tomasz Drwięga
2021-04-13 09:37:26 +02:00
committed by Bastian Köcher
parent b569f201cf
commit 7c639687b6
5 changed files with 123 additions and 94 deletions
@@ -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)]
@@ -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");
}
}
+4 -20
View File
@@ -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<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;
@@ -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,
},
}
@@ -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};
@@ -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<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;
@@ -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;
@@ -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())
}
}