From fb1d3f2a2be1d06c34440cf49a9f369f75483e11 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 11 Mar 2022 23:56:56 -0800 Subject: [PATCH] Make the price of UMP/XCMP message sending configurable --- pallets/xcmp-queue/src/lib.rs | 24 +++++++++++++++++++++++- primitives/utility/src/lib.rs | 30 +++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/pallets/xcmp-queue/src/lib.rs b/pallets/xcmp-queue/src/lib.rs index 112aaf378d..31885c4fa9 100644 --- a/pallets/xcmp-queue/src/lib.rs +++ b/pallets/xcmp-queue/src/lib.rs @@ -99,6 +99,9 @@ pub mod pallet { /// superuser origin. type ControllerOriginConverter: ConvertOrigin; + /// The price for delivering an XCM to a sibling parachain destination. + type PriceForSiblingDelivery: PriceForSiblingDelivery; + /// The weight information of this pallet. type WeightInfo: WeightInfo; } @@ -1077,6 +1080,23 @@ impl XcmpMessageSource for Pallet { } } +pub trait PriceForSiblingDelivery { + fn price_for_sibling_delivery(id: ParaId, message: &Xcm<()>) -> MultiAssets; +} + +impl PriceForSiblingDelivery for () { + fn price_for_sibling_delivery(_: ParaId, _: &Xcm<()>) -> MultiAssets { + MultiAssets::new() + } +} + +pub struct ConstantPrice(sp_std::marker::PhantomData); +impl> PriceForSiblingDelivery for ConstantPrice { + fn price_for_sibling_delivery(_: ParaId, _: &Xcm<()>) -> MultiAssets { + T::get() + } +} + /// Xcm sender for sending to a sibling parachain. impl SendXcm for Pallet { type Ticket = (ParaId, VersionedXcm<()>); @@ -1091,9 +1111,11 @@ impl SendXcm for Pallet { match &d { // An HRMP message for a sibling parachain. MultiLocation { parents: 1, interior: X1(Parachain(id)) } => { + let id = ParaId::from(*id); + let price = T::PriceForSiblingDelivery::price_for_sibling_delivery(id, &xcm); let versioned_xcm = T::VersionWrapper::wrap_version(&d, xcm) .map_err(|()| SendError::DestinationUnsupported)?; - Ok((((*id).into(), versioned_xcm), MultiAssets::new())) + Ok(((id, versioned_xcm), price)) }, // Anything else is unhandled. This includes a message this is meant for us. _ => { diff --git a/primitives/utility/src/lib.rs b/primitives/utility/src/lib.rs index f99ebce9ec..ac5b783eba 100644 --- a/primitives/utility/src/lib.rs +++ b/primitives/utility/src/lib.rs @@ -21,9 +21,27 @@ use codec::Encode; use cumulus_primitives_core::{MessageSendError, UpwardMessageSender}; +use frame_support::traits::Get; use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, WrapVersion}; +pub trait PriceForParentDelivery { + fn price_for_parent_delivery(message: &Xcm<()>) -> MultiAssets; +} + +impl PriceForParentDelivery for () { + fn price_for_parent_delivery(_: &Xcm<()>) -> MultiAssets { + MultiAssets::new() + } +} + +pub struct ConstantPrice(PhantomData); +impl> PriceForParentDelivery for ConstantPrice { + fn price_for_parent_delivery(_: &Xcm<()>) -> MultiAssets { + T::get() + } +} + /// Xcm router which recognises the `Parent` destination and handles it by sending the message into /// the given UMP `UpwardMessageSender` implementation. Thus this essentially adapts an /// `UpwardMessageSender` trait impl into a `SendXcm` trait impl. @@ -31,8 +49,13 @@ use xcm::{latest::prelude::*, WrapVersion}; /// NOTE: This is a pretty dumb "just send it" router; we will probably want to introduce queuing /// to UMP eventually and when we do, the pallet which implements the queuing will be responsible /// for the `SendXcm` implementation. -pub struct ParentAsUmp(PhantomData<(T, W)>); -impl SendXcm for ParentAsUmp { +pub struct ParentAsUmp(PhantomData<(T, W, P)>); +impl SendXcm for ParentAsUmp +where + T: UpwardMessageSender, + W: WrapVersion, + P: PriceForParentDelivery, +{ type Ticket = Vec; fn validate( @@ -44,11 +67,12 @@ impl SendXcm for ParentAsUmp { if d.contains_parents_only(1) { // An upward message for the relay chain. + let price = P::price_for_parent_delivery(&xcm); let versioned_xcm = W::wrap_version(&d, xcm).map_err(|()| SendError::DestinationUnsupported)?; let data = versioned_xcm.encode(); - Ok((data, MultiAssets::new())) + Ok((data, price)) } else { *dest = Some(d); // Anything else is unhandled. This includes a message this is meant for us.