Send messages using xcm pallet (#1518)

* send messages using xcm pallet

* XcmBridge && XcmBridgeAdapter + (untested) config in RialtoParachain

* impl encode_send_xcm for the rest

* remove duplicate code

* some fixes

* cleanup

* some more tests

* cleanup

* cleanup

* send Rialto -> Millau messages using bridge-messages pallet

* fmt

* some clippy fixes

* more clippy
This commit is contained in:
Svyatoslav Nikolsky
2022-07-27 15:15:07 +03:00
committed by Bastian Köcher
parent b21790b769
commit c131a5e3c8
17 changed files with 480 additions and 158 deletions
@@ -22,12 +22,49 @@ use crate::cli::{
CliChain,
};
use bp_messages::LaneId;
use bp_rialto_parachain::RIALTO_PARACHAIN_ID;
use bp_runtime::EncodedOrDecodedCall;
use relay_millau_client::Millau;
use relay_substrate_client::BalanceOf;
use sp_version::RuntimeVersion;
use xcm::latest::prelude::*;
impl CliEncodeMessage for Millau {
fn encode_send_xcm(
message: xcm::VersionedXcm<()>,
bridge_instance_index: u8,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
Ok(match bridge_instance_index {
bridge::MILLAU_TO_RIALTO_INDEX => {
let dest =
(Parent, X1(GlobalConsensus(millau_runtime::xcm_config::RialtoNetwork::get())));
millau_runtime::Call::XcmPallet(millau_runtime::XcmCall::send {
dest: Box::new(dest.into()),
message: Box::new(message),
})
.into()
},
bridge::MILLAU_TO_RIALTO_PARACHAIN_INDEX => {
let dest = (
Parent,
X2(
GlobalConsensus(millau_runtime::xcm_config::RialtoNetwork::get()),
Parachain(RIALTO_PARACHAIN_ID),
),
);
millau_runtime::Call::XcmPallet(millau_runtime::XcmCall::send {
dest: Box::new(dest.into()),
message: Box::new(message),
})
.into()
},
_ => anyhow::bail!(
"Unsupported target bridge pallet with instance index: {}",
bridge_instance_index
),
})
}
fn encode_send_message_call(
lane: LaneId,
payload: RawMessage,
@@ -26,8 +26,30 @@ use bp_runtime::EncodedOrDecodedCall;
use relay_rialto_client::Rialto;
use relay_substrate_client::BalanceOf;
use sp_version::RuntimeVersion;
use xcm::latest::prelude::*;
impl CliEncodeMessage for Rialto {
fn encode_send_xcm(
message: xcm::VersionedXcm<()>,
bridge_instance_index: u8,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
Ok(match bridge_instance_index {
bridge::RIALTO_TO_MILLAU_INDEX => {
let dest =
(Parent, X1(GlobalConsensus(rialto_runtime::xcm_config::MillauNetwork::get())));
rialto_runtime::Call::XcmPallet(rialto_runtime::XcmCall::send {
dest: Box::new(dest.into()),
message: Box::new(message),
})
.into()
},
_ => anyhow::bail!(
"Unsupported target bridge pallet with instance index: {}",
bridge_instance_index
),
})
}
fn encode_send_message_call(
lane: LaneId,
payload: RawMessage,
@@ -26,8 +26,32 @@ use bp_runtime::EncodedOrDecodedCall;
use relay_rialto_parachain_client::RialtoParachain;
use relay_substrate_client::BalanceOf;
use sp_version::RuntimeVersion;
use xcm::latest::prelude::*;
impl CliEncodeMessage for RialtoParachain {
fn encode_send_xcm(
message: xcm::VersionedXcm<()>,
bridge_instance_index: u8,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
Ok(match bridge_instance_index {
bridge::RIALTO_PARACHAIN_TO_MILLAU_INDEX => {
let dest =
(Parent, X1(GlobalConsensus(rialto_parachain_runtime::MillauNetwork::get())));
rialto_parachain_runtime::Call::PolkadotXcm(
rialto_parachain_runtime::XcmCall::send {
dest: Box::new(dest.into()),
message: Box::new(message),
},
)
.into()
},
_ => anyhow::bail!(
"Unsupported target bridge pallet with instance index: {}",
bridge_instance_index
),
})
}
fn encode_send_message_call(
lane: LaneId,
payload: RawMessage,
@@ -42,7 +42,13 @@ pub enum Message {
pub type RawMessage = Vec<u8>;
pub trait CliEncodeMessage: Chain {
/// Encode a send message call.
/// Encode a send XCM call of the XCM pallet.
fn encode_send_xcm(
message: xcm::VersionedXcm<()>,
bridge_instance_index: u8,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>>;
/// Encode a send message call of the bridge-messages pallet.
fn encode_send_message_call(
lane: LaneId,
message: RawMessage,
@@ -24,13 +24,13 @@ use crate::{
cli::{
bridge::{FullBridge, MessagesCliBridge},
chain_schema::*,
encode_message::{self, CliEncodeMessage},
encode_message::{self, CliEncodeMessage, RawMessage},
estimate_fee::{estimate_message_delivery_and_dispatch_fee, ConversionRateOverride},
Balance, CliChain, HexBytes, HexLaneId,
},
};
use async_trait::async_trait;
use codec::Encode;
use codec::{Decode, Encode};
use relay_substrate_client::{
AccountIdOf, AccountKeyPairOf, Chain, ChainBase, SignParam, TransactionSignScheme,
UnsignedTransaction,
@@ -70,6 +70,10 @@ pub struct SendMessage {
source: SourceConnectionParams,
#[structopt(flatten)]
source_sign: SourceSigningParams,
/// Send message using XCM pallet instead. By default message is sent using
/// bridge messages pallet.
#[structopt(long)]
use_xcm_pallet: bool,
/// Hex-encoded lane id. Defaults to `00000000`.
#[structopt(long, default_value = "00000000")]
lane: HexLaneId,
@@ -124,12 +128,19 @@ where
),
};
let payload_len = payload.encode().len();
let send_message_call = Self::Source::encode_send_message_call(
data.lane.0,
payload,
fee.cast().into(),
data.bridge.bridge_instance_index(),
)?;
let send_message_call = if data.use_xcm_pallet {
Self::Source::encode_send_xcm(
decode_xcm(payload)?,
data.bridge.bridge_instance_index(),
)?
} else {
Self::Source::encode_send_message_call(
data.lane.0,
payload,
fee.cast().into(),
data.bridge.bridge_instance_index(),
)?
};
let source_genesis_hash = *source_client.genesis_hash();
let (spec_version, transaction_version) = source_client.simple_runtime_version().await?;
@@ -210,6 +221,12 @@ impl SendMessage {
}
}
/// Decode SCALE encoded raw XCM message.
fn decode_xcm(message: RawMessage) -> anyhow::Result<xcm::VersionedXcm<()>> {
Decode::decode(&mut &message[..])
.map_err(|e| anyhow::format_err!("Failed to decode XCM program: {:?}", e))
}
#[cfg(test)]
mod tests {
use super::*;