Skip to content

Commit

Permalink
add FeeManager to pallet xcm (#5363)
Browse files Browse the repository at this point in the history
Closes #2082

change send xcm to use `xcm::executor::FeeManager` to determine if the
sender should be charged.

I had to change the `FeeManager` of the penpal config to ensure the same
test behaviour as before. For the other tests, I'm using the
`FeeManager` from the `xcm::executor::FeeManager` as this one is used to
check if the fee can be waived on the charge fees method.

---------

Co-authored-by: Adrian Catangiu <[email protected]>
Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
3 people authored Nov 11, 2024
1 parent a5de3b1 commit dd9514f
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ use xcm_builder::{
use xcm_executor::XcmExecutor;

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const TokenLocation: Location = Location::parent();
pub const RelayNetwork: NetworkId = NetworkId::ByGenesis(ROCOCO_GENESIS_HASH);
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
Expand Down Expand Up @@ -315,6 +316,7 @@ pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
/// either execution or delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ use xcm_builder::{
use xcm_executor::XcmExecutor;

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const WestendLocation: Location = Location::parent();
pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH));
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
Expand Down Expand Up @@ -336,6 +337,7 @@ pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
/// either execution or delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
FellowshipEntities,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ use xcm_executor::{
};

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const TokenLocation: Location = Location::parent();
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub RelayNetwork: NetworkId = NetworkId::ByGenesis(ROCOCO_GENESIS_HASH);
Expand Down Expand Up @@ -164,6 +165,7 @@ pub type Barrier = TrailingSetTopicAsId<
/// either execution or delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use xcm_executor::{
};

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const WestendLocation: Location = Location::parent();
pub const RelayNetwork: NetworkId = NetworkId::ByGenesis(WESTEND_GENESIS_HASH);
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
Expand Down Expand Up @@ -161,6 +162,7 @@ pub type Barrier = TrailingSetTopicAsId<
/// either execution or delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use xcm_builder::{
use xcm_executor::XcmExecutor;

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const RelayLocation: Location = Location::parent();
pub const RelayNetwork: NetworkId = NetworkId::ByGenesis(ROCOCO_GENESIS_HASH);
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
Expand Down Expand Up @@ -166,6 +167,7 @@ pub type Barrier = TrailingSetTopicAsId<
/// either execution or delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use xcm_builder::{
use xcm_executor::XcmExecutor;

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const RocRelayLocation: Location = Location::parent();
pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(ROCOCO_GENESIS_HASH));
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
Expand Down Expand Up @@ -177,6 +178,7 @@ parameter_types! {
/// Locations that will not be charged fees in the executor, neither for execution nor delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use xcm_builder::{
use xcm_executor::XcmExecutor;

parameter_types! {
pub const RootLocation: Location = Location::here();
pub const TokenRelayLocation: Location = Location::parent();
pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH));
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
Expand Down Expand Up @@ -185,6 +186,7 @@ parameter_types! {
/// Locations that will not be charged fees in the executor, neither for execution nor delivery.
/// We only waive fees for system functions, which these locations represent.
pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
);
Expand Down
6 changes: 4 additions & 2 deletions cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use core::marker::PhantomData;
use frame_support::{
parameter_types,
traits::{
tokens::imbalance::ResolveAssetTo, ConstU32, Contains, ContainsPair, Everything,
tokens::imbalance::ResolveAssetTo, ConstU32, Contains, ContainsPair, Equals, Everything,
EverythingBut, Get, Nothing, PalletInfoAccess,
},
weights::Weight,
Expand Down Expand Up @@ -210,6 +210,7 @@ pub type XcmOriginToTransactDispatchOrigin = (
);

parameter_types! {
pub const RootLocation: Location = Location::here();
// One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate.
pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
pub const MaxInstructions: u32 = 100;
Expand Down Expand Up @@ -336,6 +337,7 @@ pub type TrustedReserves = (
pub type TrustedTeleporters =
(AssetFromChain<LocalTeleportableToAssetHub, SystemAssetHubLocation>,);

pub type WaivedLocations = Equals<RootLocation>;
/// `AssetId`/`Balance` converter for `TrustBackedAssets`.
pub type TrustBackedAssetsConvertedConcreteId =
assets_common::TrustBackedAssetsConvertedConcreteId<AssetsPalletLocation, Balance>;
Expand Down Expand Up @@ -399,7 +401,7 @@ impl xcm_executor::Config for XcmConfig {
type AssetLocker = ();
type AssetExchanger = PoolAssetsExchanger;
type FeeManager = XcmFeeManagerFromComponents<
(),
WaivedLocations,
SendXcmFeeToAccount<Self::AssetTransactor, TreasuryAccount>,
>;
type MessageExporter = ();
Expand Down
17 changes: 9 additions & 8 deletions polkadot/xcm/pallet-xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ use xcm_runtime_apis::{

#[cfg(any(feature = "try-runtime", test))]
use sp_runtime::TryRuntimeError;
use xcm_executor::traits::{FeeManager, FeeReason};

pub trait WeightInfo {
fn send() -> Weight;
Expand Down Expand Up @@ -240,7 +241,7 @@ pub mod pallet {
type XcmExecuteFilter: Contains<(Location, Xcm<<Self as Config>::RuntimeCall>)>;

/// Something to execute an XCM message.
type XcmExecutor: ExecuteXcm<<Self as Config>::RuntimeCall> + XcmAssetTransfers;
type XcmExecutor: ExecuteXcm<<Self as Config>::RuntimeCall> + XcmAssetTransfers + FeeManager;

/// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass.
type XcmTeleportFilter: Contains<(Location, Vec<Asset>)>;
Expand Down Expand Up @@ -2468,17 +2469,17 @@ impl<T: Config> Pallet<T> {
mut message: Xcm<()>,
) -> Result<XcmHash, SendError> {
let interior = interior.into();
let local_origin = interior.clone().into();
let dest = dest.into();
let maybe_fee_payer = if interior != Junctions::Here {
let is_waived =
<T::XcmExecutor as FeeManager>::is_waived(Some(&local_origin), FeeReason::ChargeFees);
if interior != Junctions::Here {
message.0.insert(0, DescendOrigin(interior.clone()));
Some(interior.into())
} else {
None
};
}
tracing::debug!(target: "xcm::send_xcm", "{:?}, {:?}", dest.clone(), message.clone());
let (ticket, price) = validate_send::<T::XcmRouter>(dest, message)?;
if let Some(fee_payer) = maybe_fee_payer {
Self::charge_fees(fee_payer, price).map_err(|e| {
if !is_waived {
Self::charge_fees(local_origin, price).map_err(|e| {
tracing::error!(
target: "xcm::pallet_xcm::send_xcm",
?e,
Expand Down
10 changes: 10 additions & 0 deletions polkadot/xcm/xcm-executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ impl<Config: config::Config> XcmAssetTransfers for XcmExecutor<Config> {
type AssetTransactor = Config::AssetTransactor;
}

impl<Config: config::Config> FeeManager for XcmExecutor<Config> {
fn is_waived(origin: Option<&Location>, r: FeeReason) -> bool {
Config::FeeManager::is_waived(origin, r)
}

fn handle_fee(fee: Assets, context: Option<&XcmContext>, r: FeeReason) {
Config::FeeManager::handle_fee(fee, context, r)
}
}

#[derive(Debug)]
pub struct ExecutorError {
pub index: u32,
Expand Down
14 changes: 14 additions & 0 deletions prdoc/pr_5363.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: "[pallet-xcm] waive transport fees based on XcmConfig"

doc:
- audience: Runtime Dev
description: |
pallet-xcm::send() no longer implicitly waives transport fees for the local root location,
but instead relies on xcm_executor::Config::FeeManager to determine whether certain locations have free transport.

🚨 Warning: 🚨 If your chain relies on free transport for local root, please make
sure to add Location::here() to the waived-fee locations in your configured xcm_executor::Config::FeeManager.

crates:
- name: pallet-xcm
bump: major

0 comments on commit dd9514f

Please sign in to comment.