mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 04:41:03 +00:00
9b57f2181c
* moved bridge declarations to dedicated folder * Kusama <> Polkadot bridges declaration * support for Kusama <> Polkadot bridge in CLI * update dictionary
191 lines
6.0 KiB
Rust
191 lines
6.0 KiB
Rust
// 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::{
|
|
bridges::{
|
|
rialto_millau::{
|
|
millau_headers_to_rialto::MillauToRialtoCliBridge,
|
|
rialto_headers_to_millau::RialtoToMillauCliBridge,
|
|
},
|
|
rialto_parachain_millau::{
|
|
millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
|
|
rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
|
|
},
|
|
},
|
|
cli::{
|
|
bridge::{FullBridge, MessagesCliBridge},
|
|
chain_schema::*,
|
|
encode_message::{self, CliEncodeMessage, RawMessage},
|
|
CliChain,
|
|
},
|
|
};
|
|
use async_trait::async_trait;
|
|
use codec::{Decode, Encode};
|
|
use relay_substrate_client::{
|
|
AccountIdOf, AccountKeyPairOf, Chain, ChainBase, ChainWithTransactions, UnsignedTransaction,
|
|
};
|
|
use sp_core::Pair;
|
|
use sp_runtime::AccountId32;
|
|
use std::fmt::Display;
|
|
use structopt::StructOpt;
|
|
use strum::VariantNames;
|
|
|
|
/// Send bridge message.
|
|
#[derive(StructOpt)]
|
|
pub struct SendMessage {
|
|
/// A bridge instance to encode call for.
|
|
#[structopt(possible_values = FullBridge::VARIANTS, case_insensitive = true)]
|
|
bridge: FullBridge,
|
|
#[structopt(flatten)]
|
|
source: SourceConnectionParams,
|
|
#[structopt(flatten)]
|
|
source_sign: SourceSigningParams,
|
|
/// Message type.
|
|
#[structopt(subcommand)]
|
|
message: crate::cli::encode_message::Message,
|
|
}
|
|
|
|
#[async_trait]
|
|
trait MessageSender: MessagesCliBridge
|
|
where
|
|
Self::Source: ChainBase<Index = u32> + ChainWithTransactions + CliChain + CliEncodeMessage,
|
|
<Self::Source as ChainBase>::Balance: Display + From<u64> + Into<u128>,
|
|
<Self::Source as Chain>::Call: Sync,
|
|
<Self::Source as ChainWithTransactions>::SignedTransaction: Sync,
|
|
AccountIdOf<Self::Source>: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
|
|
AccountId32: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
|
|
{
|
|
async fn send_message(data: SendMessage) -> anyhow::Result<()> {
|
|
let payload = encode_message::encode_message::<Self::Source, Self::Target>(&data.message)?;
|
|
|
|
let source_client = data.source.into_client::<Self::Source>().await?;
|
|
let source_sign = data.source_sign.to_keypair::<Self::Source>()?;
|
|
|
|
let payload_len = payload.encoded_size();
|
|
let send_message_call = Self::Source::encode_send_xcm(
|
|
decode_xcm(payload)?,
|
|
data.bridge.bridge_instance_index(),
|
|
)?;
|
|
|
|
source_client
|
|
.submit_signed_extrinsic(&source_sign, move |_, transaction_nonce| {
|
|
let unsigned = UnsignedTransaction::new(send_message_call, transaction_nonce);
|
|
log::info!(
|
|
target: "bridge",
|
|
"Sending message to {}. Size: {}",
|
|
Self::Target::NAME,
|
|
payload_len,
|
|
);
|
|
Ok(unsigned)
|
|
})
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl MessageSender for MillauToRialtoCliBridge {}
|
|
impl MessageSender for RialtoToMillauCliBridge {}
|
|
impl MessageSender for MillauToRialtoParachainCliBridge {}
|
|
impl MessageSender for RialtoParachainToMillauCliBridge {}
|
|
|
|
impl SendMessage {
|
|
/// Run the command.
|
|
pub async fn run(self) -> anyhow::Result<()> {
|
|
match self.bridge {
|
|
FullBridge::MillauToRialto => MillauToRialtoCliBridge::send_message(self),
|
|
FullBridge::RialtoToMillau => RialtoToMillauCliBridge::send_message(self),
|
|
FullBridge::MillauToRialtoParachain =>
|
|
MillauToRialtoParachainCliBridge::send_message(self),
|
|
FullBridge::RialtoParachainToMillau =>
|
|
RialtoParachainToMillauCliBridge::send_message(self),
|
|
FullBridge::BridgeHubRococoToBridgeHubWococo => unimplemented!(
|
|
"Sending message from BridgeHubRococo to BridgeHubWococo is not supported"
|
|
),
|
|
FullBridge::BridgeHubWococoToBridgeHubRococo => unimplemented!(
|
|
"Sending message from BridgeHubWococo to BridgeHubRococo is not supported"
|
|
),
|
|
FullBridge::BridgeHubKusamaToBridgeHubPolkadot => unimplemented!(
|
|
"Sending message from BridgeHubKusama to BridgeHubPolkadot is not supported"
|
|
),
|
|
FullBridge::BridgeHubPolkadotToBridgeHubKusama => unimplemented!(
|
|
"Sending message from BridgeHubPolkadot to BridgeHubKusama is not supported"
|
|
),
|
|
}
|
|
.await
|
|
}
|
|
}
|
|
|
|
/// Decode SCALE encoded raw XCM message.
|
|
pub(crate) 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::*;
|
|
use crate::cli::{ExplicitOrMaximal, HexBytes};
|
|
|
|
#[test]
|
|
fn send_raw_rialto_to_millau() {
|
|
// given
|
|
let send_message = SendMessage::from_iter(vec![
|
|
"send-message",
|
|
"rialto-to-millau",
|
|
"--source-port",
|
|
"1234",
|
|
"--source-signer",
|
|
"//Alice",
|
|
"raw",
|
|
"dead",
|
|
]);
|
|
|
|
// then
|
|
assert_eq!(send_message.bridge, FullBridge::RialtoToMillau);
|
|
assert_eq!(send_message.source.source_port, 1234);
|
|
assert_eq!(send_message.source_sign.source_signer, Some("//Alice".into()));
|
|
assert_eq!(
|
|
send_message.message,
|
|
crate::cli::encode_message::Message::Raw { data: HexBytes(vec![0xDE, 0xAD]) }
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn send_sized_rialto_to_millau() {
|
|
// given
|
|
let send_message = SendMessage::from_iter(vec![
|
|
"send-message",
|
|
"rialto-to-millau",
|
|
"--source-port",
|
|
"1234",
|
|
"--source-signer",
|
|
"//Alice",
|
|
"sized",
|
|
"max",
|
|
]);
|
|
|
|
// then
|
|
assert_eq!(send_message.bridge, FullBridge::RialtoToMillau);
|
|
assert_eq!(send_message.source.source_port, 1234);
|
|
assert_eq!(send_message.source_sign.source_signer, Some("//Alice".into()));
|
|
assert_eq!(
|
|
send_message.message,
|
|
crate::cli::encode_message::Message::Sized { size: ExplicitOrMaximal::Maximal }
|
|
);
|
|
}
|
|
}
|