mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
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:
committed by
Bastian Köcher
parent
b21790b769
commit
c131a5e3c8
@@ -37,6 +37,7 @@ use sp_runtime::{
|
||||
};
|
||||
use sp_std::{cmp::PartialOrd, convert::TryFrom, fmt::Debug, marker::PhantomData, vec::Vec};
|
||||
use sp_trie::StorageProof;
|
||||
use xcm::latest::prelude::*;
|
||||
|
||||
/// Bidirectional message bridge.
|
||||
pub trait MessageBridge {
|
||||
@@ -524,6 +525,111 @@ pub mod source {
|
||||
|
||||
Ok((lane, inbound_lane_data))
|
||||
}
|
||||
|
||||
/// XCM bridge.
|
||||
pub trait XcmBridge {
|
||||
/// Runtime message bridge configuration.
|
||||
type MessageBridge: MessageBridge;
|
||||
/// Runtime message sender adapter.
|
||||
type MessageSender: bp_messages::source_chain::MessagesBridge<
|
||||
OriginOf<ThisChain<Self::MessageBridge>>,
|
||||
AccountIdOf<ThisChain<Self::MessageBridge>>,
|
||||
BalanceOf<ThisChain<Self::MessageBridge>>,
|
||||
FromThisChainMessagePayload,
|
||||
>;
|
||||
|
||||
/// Our location within the Consensus Universe.
|
||||
fn universal_location() -> InteriorMultiLocation;
|
||||
/// Verify that the adapter is responsible for handling given XCM destination.
|
||||
fn verify_destination(dest: &MultiLocation) -> bool;
|
||||
/// Build route from this chain to the XCM destination.
|
||||
fn build_destination() -> MultiLocation;
|
||||
/// Return message lane used to deliver XCM messages.
|
||||
fn xcm_lane() -> LaneId;
|
||||
}
|
||||
|
||||
/// XCM bridge adapter for `bridge-messages` pallet.
|
||||
pub struct XcmBridgeAdapter<T>(PhantomData<T>);
|
||||
|
||||
impl<T: XcmBridge> SendXcm for XcmBridgeAdapter<T>
|
||||
where
|
||||
BalanceOf<ThisChain<T::MessageBridge>>: Into<Fungibility>,
|
||||
OriginOf<ThisChain<T::MessageBridge>>: From<pallet_xcm::Origin>,
|
||||
{
|
||||
type Ticket = (BalanceOf<ThisChain<T::MessageBridge>>, FromThisChainMessagePayload);
|
||||
|
||||
fn validate(
|
||||
dest: &mut Option<MultiLocation>,
|
||||
msg: &mut Option<Xcm<()>>,
|
||||
) -> SendResult<Self::Ticket> {
|
||||
let d = dest.take().ok_or(SendError::MissingArgument)?;
|
||||
if !T::verify_destination(&d) {
|
||||
*dest = Some(d);
|
||||
return Err(SendError::NotApplicable)
|
||||
}
|
||||
|
||||
let route = T::build_destination();
|
||||
let msg = (route, msg.take().unwrap()).encode();
|
||||
|
||||
let fee = estimate_message_dispatch_and_delivery_fee::<T::MessageBridge>(
|
||||
&msg,
|
||||
T::MessageBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
);
|
||||
let fee = match fee {
|
||||
Ok(fee) => fee,
|
||||
Err(e) => {
|
||||
log::trace!(
|
||||
target: "runtime::bridge",
|
||||
"Failed to comupte fee for XCM message to {:?}: {:?}",
|
||||
T::MessageBridge::BRIDGED_CHAIN_ID,
|
||||
e,
|
||||
);
|
||||
*dest = Some(d);
|
||||
return Err(SendError::Transport(e))
|
||||
},
|
||||
};
|
||||
let fee_assets = MultiAssets::from((Here, fee));
|
||||
|
||||
Ok(((fee, msg), fee_assets))
|
||||
}
|
||||
|
||||
fn deliver(ticket: Self::Ticket) -> Result<XcmHash, SendError> {
|
||||
use bp_messages::source_chain::MessagesBridge;
|
||||
|
||||
let lane = T::xcm_lane();
|
||||
let (fee, msg) = ticket;
|
||||
let result = T::MessageSender::send_message(
|
||||
pallet_xcm::Origin::from(MultiLocation::from(T::universal_location())).into(),
|
||||
lane,
|
||||
msg,
|
||||
fee,
|
||||
);
|
||||
result
|
||||
.map(|artifacts| {
|
||||
let hash = (lane, artifacts.nonce).using_encoded(sp_io::hashing::blake2_256);
|
||||
log::debug!(
|
||||
target: "runtime::bridge",
|
||||
"Sent XCM message {:?}/{} to {:?}: {:?}",
|
||||
lane,
|
||||
artifacts.nonce,
|
||||
T::MessageBridge::BRIDGED_CHAIN_ID,
|
||||
hash,
|
||||
);
|
||||
hash
|
||||
})
|
||||
.map_err(|e| {
|
||||
log::debug!(
|
||||
target: "runtime::bridge",
|
||||
"Failed to send XCM message over lane {:?} to {:?}: {:?}",
|
||||
lane,
|
||||
T::MessageBridge::BRIDGED_CHAIN_ID,
|
||||
e,
|
||||
);
|
||||
SendError::Transport("Bridge has rejected the message")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sub-module that is declaring types required for processing Bridged -> This chain messages.
|
||||
@@ -641,8 +747,6 @@ pub mod target {
|
||||
_relayer_account: &AccountIdOf<ThisChain<B>>,
|
||||
message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
|
||||
) -> MessageDispatchResult {
|
||||
use xcm::latest::*;
|
||||
|
||||
let message_id = (message.key.lane_id, message.key.nonce);
|
||||
let do_dispatch = move || -> sp_std::result::Result<Outcome, codec::Error> {
|
||||
let FromBridgedChainMessagePayload { xcm: (location, xcm), weight: weight_limit } =
|
||||
|
||||
Reference in New Issue
Block a user