[pallet-xcm] fix transport fees for remote reserve transfers (#3792)

Currently `transfer_assets` from pallet-xcm covers 4 main different
transfer types:
- `localReserve`
- `DestinationReserve`
- `Teleport`
- `RemoteReserve`

For the first three, the local execution and the remote message sending
are separated, and fees are deducted in pallet-xcm itself:
https://github.com/paritytech/polkadot-sdk/blob/3410dfb3929462da88be2da813f121d8b1cf46b3/polkadot/xcm/pallet-xcm/src/lib.rs#L1758.

For the 4th case `RemoteReserve`, pallet-xcm is still relying on the
xcm-executor itself to send the message (through the
`initiateReserveWithdraw` instruction). In this case, if delivery fees
need to be charged, it is not possible to do so because the
`jit_withdraw` mode has not being set.

This PR proposes to still use the `initiateReserveWithdraw` but
prepending a `setFeesMode { jit_withdraw: true }` to make sure delivery
fees can be paid.

A test-case is also added to present the aforementioned case

---------

Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
girazoki
2024-03-22 19:48:15 +01:00
committed by GitHub
parent 2f59e9efa8
commit 9a04ebbfb0
17 changed files with 291 additions and 164 deletions
@@ -115,7 +115,7 @@ macro_rules! test_parachain_is_trusted_teleporter {
let para_receiver_balance_after =
<$receiver_para as $crate::macros::Chain>::account_data_of(receiver.clone()).free;
let delivery_fees = <$sender_para>::execute_with(|| {
$crate::macros::asset_test_utils::xcm_helpers::transfer_assets_delivery_fees::<
$crate::macros::asset_test_utils::xcm_helpers::teleport_assets_delivery_fees::<
<$sender_xcm_config as xcm_executor::Config>::XcmSender,
>($assets.clone(), fee_asset_item, weight_limit.clone(), beneficiary, para_destination)
});
@@ -63,17 +63,13 @@ mod imports {
// Runtimes
pub use asset_hub_rococo_runtime::xcm_config::{
TokenLocation as RelayLocation, UniversalLocation as AssetHubRococoUniversalLocation,
XcmConfig as AssetHubRococoXcmConfig,
TokenLocation as RelayLocation, XcmConfig as AssetHubRococoXcmConfig,
};
pub use penpal_runtime::xcm_config::{
LocalReservableFromAssetHub as PenpalLocalReservableFromAssetHub,
LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub,
UniversalLocation as PenpalUniversalLocation, XcmConfig as PenpalRococoXcmConfig,
};
pub use rococo_runtime::xcm_config::{
UniversalLocation as RococoUniversalLocation, XcmConfig as RococoXcmConfig,
};
pub use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;
pub const ASSET_ID: u32 = 3;
pub const ASSET_MIN_BALANCE: u128 = 1000;
@@ -524,7 +524,6 @@ fn reserve_transfer_native_asset_from_relay_to_para() {
let destination = Rococo::child_location_of(PenpalA::para_id());
let sender = RococoSender::get();
let amount_to_send: Balance = ROCOCO_ED * 1000;
let assets: Assets = (Here, amount_to_send).into();
// Init values fot Parachain
let relay_native_asset_location =
@@ -552,15 +551,6 @@ fn reserve_transfer_native_asset_from_relay_to_para() {
test.set_dispatchable::<Rococo>(relay_to_para_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = Rococo::execute_with(|| {
let reanchored_assets =
assets.reanchored(&destination, &RococoUniversalLocation::get()).unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_balance_after = test.sender.balance;
let receiver_assets_after = PenpalA::execute_with(|| {
@@ -568,8 +558,8 @@ fn reserve_transfer_native_asset_from_relay_to_para() {
<ForeignAssets as Inspect<_>>::balance(relay_native_asset_location.into(), &receiver)
});
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_balance_after < sender_balance_before - amount_to_send);
// Receiver's asset balance is increased
assert!(receiver_assets_after > receiver_assets_before);
// Receiver's asset balance increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -595,7 +585,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner),
relay_native_asset_location,
sender.clone(),
amount_to_send,
amount_to_send * 2,
);
// Init values for Relay
@@ -634,15 +624,6 @@ fn reserve_transfer_native_asset_from_para_to_relay() {
test.set_dispatchable::<PenpalA>(para_to_relay_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = PenpalA::execute_with(|| {
let reanchored_assets =
assets.reanchored(&destination, &PenpalUniversalLocation::get()).unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_assets_after = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
@@ -650,8 +631,8 @@ fn reserve_transfer_native_asset_from_para_to_relay() {
});
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_assets_before - amount_to_send - delivery_fees, sender_assets_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_assets_after < sender_assets_before - amount_to_send);
// Receiver's asset balance is increased
assert!(receiver_balance_after > receiver_balance_before);
// Receiver's asset balance increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -705,16 +686,6 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = AssetHubRococo::execute_with(|| {
let reanchored_assets = assets
.reanchored(&destination, &AssetHubRococoUniversalLocation::get())
.unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<AssetHubRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_balance_after = test.sender.balance;
let receiver_assets_after = PenpalA::execute_with(|| {
@@ -722,8 +693,8 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
<ForeignAssets as Inspect<_>>::balance(system_para_native_asset_location, &receiver)
});
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_balance_after < sender_balance_before - amount_to_send);
// Receiver's assets is increased
assert!(receiver_assets_after > receiver_assets_before);
// Receiver's assets increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -738,7 +709,7 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
// Init values for Parachain
let destination = PenpalA::sibling_location_of(AssetHubRococo::para_id());
let sender = PenpalASender::get();
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000;
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 10000;
let assets: Assets = (Parent, amount_to_send).into();
let system_para_native_asset_location =
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
@@ -749,7 +720,7 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner),
system_para_native_asset_location,
sender.clone(),
amount_to_send,
amount_to_send * 2,
);
// Init values for System Parachain
@@ -788,15 +759,6 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
test.set_dispatchable::<PenpalA>(para_to_system_para_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = PenpalA::execute_with(|| {
let reanchored_assets =
assets.reanchored(&destination, &PenpalUniversalLocation::get()).unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_assets_after = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
@@ -804,8 +766,8 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
});
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_assets_before - amount_to_send - delivery_fees, sender_assets_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_assets_after < sender_assets_before - amount_to_send);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
// Receiver's balance increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -1084,7 +1046,7 @@ fn reserve_transfer_native_asset_from_para_to_para_trough_relay() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner),
relay_native_asset_location,
sender.clone(),
amount_to_send,
amount_to_send * 2,
);
// fund the Parachain Origin's SA on Relay Chain with the native tokens held in reserve
@@ -1118,13 +1080,6 @@ fn reserve_transfer_native_asset_from_para_to_para_trough_relay() {
test.set_dispatchable::<PenpalA>(para_to_para_through_relay_limited_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = PenpalA::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_assets_after = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
@@ -1135,8 +1090,8 @@ fn reserve_transfer_native_asset_from_para_to_para_trough_relay() {
<ForeignAssets as Inspect<_>>::balance(relay_native_asset_location, &receiver)
});
// Sender's balance is reduced
assert_eq!(sender_assets_before - amount_to_send - delivery_fees, sender_assets_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_assets_after < sender_assets_before - amount_to_send);
// Receiver's balance is increased
assert!(receiver_assets_after > receiver_assets_before);
}
@@ -322,7 +322,7 @@ fn limited_teleport_native_assets_from_relay_to_system_para_works() {
test.assert();
let delivery_fees = Rococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -369,7 +369,7 @@ fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = AssetHubRococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -410,7 +410,7 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = AssetHubRococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -445,7 +445,7 @@ fn teleport_native_assets_from_relay_to_system_para_works() {
test.assert();
let delivery_fees = Rococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -492,7 +492,7 @@ fn teleport_native_assets_back_from_system_para_to_relay_works() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = AssetHubRococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -530,7 +530,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() {
test.assert();
let delivery_fees = AssetHubRococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -593,7 +593,7 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner.clone()),
system_para_native_asset_location,
sender.clone(),
fee_amount_to_send,
fee_amount_to_send * 2,
);
// No need to create the asset (only mint) as it exists in genesis.
PenpalA::mint_asset(
@@ -67,17 +67,13 @@ mod imports {
// Runtimes
pub use asset_hub_westend_runtime::xcm_config::{
UniversalLocation as AssetHubWestendUniversalLocation, WestendLocation as RelayLocation,
XcmConfig as AssetHubWestendXcmConfig,
WestendLocation as RelayLocation, XcmConfig as AssetHubWestendXcmConfig,
};
pub use penpal_runtime::xcm_config::{
LocalReservableFromAssetHub as PenpalLocalReservableFromAssetHub,
LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub,
UniversalLocation as PenpalUniversalLocation, XcmConfig as PenpalWestendXcmConfig,
};
pub use westend_runtime::xcm_config::{
UniversalLocation as WestendUniversalLocation, XcmConfig as WestendXcmConfig,
};
pub use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig;
pub const ASSET_ID: u32 = 3;
pub const ASSET_MIN_BALANCE: u128 = 1000;
@@ -524,7 +524,6 @@ fn reserve_transfer_native_asset_from_relay_to_para() {
let destination = Westend::child_location_of(PenpalA::para_id());
let sender = WestendSender::get();
let amount_to_send: Balance = WESTEND_ED * 1000;
let assets: Assets = (Here, amount_to_send).into();
// Init values fot Parachain
let relay_native_asset_location =
@@ -552,15 +551,6 @@ fn reserve_transfer_native_asset_from_relay_to_para() {
test.set_dispatchable::<Westend>(relay_to_para_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = Westend::execute_with(|| {
let reanchored_assets =
assets.reanchored(&destination, &WestendUniversalLocation::get()).unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<WestendXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_balance_after = test.sender.balance;
let receiver_assets_after = PenpalA::execute_with(|| {
@@ -568,8 +558,8 @@ fn reserve_transfer_native_asset_from_relay_to_para() {
<ForeignAssets as Inspect<_>>::balance(relay_native_asset_location.into(), &receiver)
});
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_balance_after < sender_balance_before - amount_to_send);
// Receiver's asset balance is increased
assert!(receiver_assets_after > receiver_assets_before);
// Receiver's asset balance increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -595,7 +585,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner),
relay_native_asset_location,
sender.clone(),
amount_to_send,
amount_to_send * 2,
);
// Init values for Relay
@@ -634,15 +624,6 @@ fn reserve_transfer_native_asset_from_para_to_relay() {
test.set_dispatchable::<PenpalA>(para_to_relay_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = PenpalA::execute_with(|| {
let reanchored_assets =
assets.reanchored(&destination, &PenpalUniversalLocation::get()).unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_assets_after = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
@@ -650,8 +631,8 @@ fn reserve_transfer_native_asset_from_para_to_relay() {
});
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_assets_before - amount_to_send - delivery_fees, sender_assets_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_assets_after < sender_assets_before - amount_to_send);
// Receiver's asset balance is increased
assert!(receiver_balance_after > receiver_balance_before);
// Receiver's asset balance increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -705,16 +686,6 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
test.set_dispatchable::<AssetHubWestend>(system_para_to_para_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = AssetHubWestend::execute_with(|| {
let reanchored_assets = assets
.reanchored(&destination, &AssetHubWestendUniversalLocation::get())
.unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<AssetHubWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_balance_after = test.sender.balance;
let receiver_assets_after = PenpalA::execute_with(|| {
@@ -722,8 +693,8 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
<ForeignAssets as Inspect<_>>::balance(system_para_native_asset_location, &receiver)
});
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_balance_after < sender_balance_before - amount_to_send);
// Receiver's assets is increased
assert!(receiver_assets_after > receiver_assets_before);
// Receiver's assets increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -749,7 +720,7 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner),
system_para_native_asset_location,
sender.clone(),
amount_to_send,
amount_to_send * 2,
);
// Init values for System Parachain
@@ -789,15 +760,6 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
test.set_dispatchable::<PenpalA>(para_to_system_para_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = PenpalA::execute_with(|| {
let reanchored_assets =
assets.reanchored(&destination, &PenpalUniversalLocation::get()).unwrap();
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(reanchored_assets, 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_assets_after = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
@@ -805,8 +767,8 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {
});
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_assets_before - amount_to_send - delivery_fees, sender_assets_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_assets_after < sender_assets_before - amount_to_send);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
// Receiver's balance increased by `amount_to_send - delivery_fees - bought_execution`;
@@ -1086,7 +1048,7 @@ fn reserve_transfer_native_asset_from_para_to_para_trough_relay() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner),
relay_native_asset_location,
sender.clone(),
amount_to_send,
amount_to_send * 2,
);
// fund the Parachain Origin's SA on Relay Chain with the native tokens held in reserve
@@ -1120,13 +1082,6 @@ fn reserve_transfer_native_asset_from_para_to_para_trough_relay() {
test.set_dispatchable::<PenpalA>(para_to_para_through_relay_limited_reserve_transfer_assets);
test.assert();
// Calculate delivery fees
let delivery_fees = PenpalA::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
<PenpalWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
// Query final balances
let sender_assets_after = PenpalA::execute_with(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
@@ -1137,8 +1092,8 @@ fn reserve_transfer_native_asset_from_para_to_para_trough_relay() {
<ForeignAssets as Inspect<_>>::balance(relay_native_asset_location, &receiver)
});
// Sender's balance is reduced
assert_eq!(sender_assets_before - amount_to_send - delivery_fees, sender_assets_after);
// Sender's balance is reduced by amount sent plus delivery fees
assert!(sender_assets_after < sender_assets_before - amount_to_send);
// Receiver's balance is increased
assert!(receiver_assets_after > receiver_assets_before);
}
@@ -322,7 +322,7 @@ fn limited_teleport_native_assets_from_relay_to_system_para_works() {
test.assert();
let delivery_fees = Westend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<WestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -369,7 +369,7 @@ fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = AssetHubWestend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -410,7 +410,7 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = AssetHubWestend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -445,7 +445,7 @@ fn teleport_native_assets_from_relay_to_system_para_works() {
test.assert();
let delivery_fees = Westend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<WestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -492,7 +492,7 @@ fn teleport_native_assets_back_from_system_para_to_relay_works() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = AssetHubWestend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -530,7 +530,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() {
test.assert();
let delivery_fees = AssetHubWestend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<AssetHubWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -593,7 +593,7 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner.clone()),
system_para_native_asset_location,
sender.clone(),
fee_amount_to_send,
fee_amount_to_send * 2,
);
// No need to create the asset (only mint) as it exists in genesis.
PenpalA::mint_asset(
@@ -155,7 +155,7 @@ fn limited_teleport_native_assets_from_relay_to_system_para_works() {
test.assert();
let delivery_fees = Rococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -204,7 +204,7 @@ fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = PeopleRococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<PeopleRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -248,7 +248,7 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = PeopleRococo::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<PeopleRococoXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -155,7 +155,7 @@ fn limited_teleport_native_assets_from_relay_to_system_para_works() {
test.assert();
let delivery_fees = Westend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<WestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -204,7 +204,7 @@ fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = PeopleWestend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<PeopleWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -248,7 +248,7 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
let receiver_balance_after = test.receiver.balance;
let delivery_fees = PeopleWestend::execute_with(|| {
xcm_helpers::transfer_assets_delivery_fees::<
xcm_helpers::teleport_assets_delivery_fees::<
<PeopleWestendXcmConfig as xcm_executor::Config>::XcmSender,
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
});
@@ -186,7 +186,7 @@ pub fn teleports_for_native_asset_works<
// Mint funds into account to ensure it has enough balance to pay delivery fees
let delivery_fees =
xcm_helpers::transfer_assets_delivery_fees::<XcmConfig::XcmSender>(
xcm_helpers::teleport_assets_delivery_fees::<XcmConfig::XcmSender>(
(native_asset_id.clone(), native_asset_to_teleport_away.into()).into(),
0,
Unlimited,
@@ -579,7 +579,7 @@ pub fn teleports_for_foreign_assets_works<
// Make sure the target account has enough native asset to pay for delivery fees
let delivery_fees =
xcm_helpers::transfer_assets_delivery_fees::<XcmConfig::XcmSender>(
xcm_helpers::teleport_assets_delivery_fees::<XcmConfig::XcmSender>(
(foreign_asset_id_location_latest.clone(), asset_to_teleport_away).into(),
0,
Unlimited,
@@ -18,11 +18,10 @@
use xcm::latest::prelude::*;
/// Returns the delivery fees amount for pallet xcm's `teleport_assets` and
/// `reserve_transfer_assets` extrinsics.
/// Returns the delivery fees amount for pallet xcm's `teleport_assets` extrinsics.
/// Because it returns only a `u128`, it assumes delivery fees are only paid
/// in one asset and that asset is known.
pub fn transfer_assets_delivery_fees<S: SendXcm>(
pub fn teleport_assets_delivery_fees<S: SendXcm>(
assets: Assets,
fee_asset_item: u32,
weight_limit: WeightLimit,
@@ -57,7 +57,6 @@ use parachains_common::{
impls::{AssetsToBlockAuthor, NonZeroIssuance},
message_queue::{NarrowOriginToSibling, ParaIdToSibling},
};
use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
use smallvec::smallvec;
use sp_api::impl_runtime_apis;
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -85,7 +84,7 @@ use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
// XCM Imports
use parachains_common::{AccountId, Signature};
use xcm::latest::prelude::BodyId;
use xcm::latest::prelude::{AssetId as AssetLocationId, BodyId};
/// Balance of an account.
pub type Balance = u128;
@@ -545,6 +544,20 @@ impl pallet_message_queue::Config for Runtime {
impl cumulus_pallet_aura_ext::Config for Runtime {}
parameter_types! {
/// The asset ID for the asset that we use to pay for message delivery fees.
pub FeeAssetId: AssetLocationId = AssetLocationId(xcm_config::RelayLocation::get());
/// The base fee for the message delivery fees (3 CENTS).
pub const BaseDeliveryFee: u128 = (1_000_000_000_000u128 / 100).saturating_mul(3);
}
pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
FeeAssetId,
BaseDeliveryFee,
TransactionByteFee,
XcmpQueue,
>;
impl cumulus_pallet_xcmp_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ChannelInfo = ParachainSystem;
@@ -555,7 +568,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ControllerOrigin = EnsureRoot<AccountId>;
type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
type WeightInfo = ();
type PriceForSiblingDelivery = NoPriceForMessageDelivery<ParaId>;
type PriceForSiblingDelivery = PriceForSiblingParachainDelivery;
}
parameter_types! {
@@ -28,6 +28,7 @@ use super::{
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee,
XcmpQueue,
};
use crate::{BaseDeliveryFee, FeeAssetId, TransactionByteFee};
use core::marker::PhantomData;
use frame_support::{
parameter_types,
@@ -36,10 +37,10 @@ use frame_support::{
};
use frame_system::EnsureRoot;
use pallet_xcm::XcmPassthrough;
use parachains_common::xcm_config::AssetFeeAsExistentialDepositMultiplier;
use parachains_common::{xcm_config::AssetFeeAsExistentialDepositMultiplier, TREASURY_PALLET_ID};
use polkadot_parachain_primitives::primitives::Sibling;
use polkadot_runtime_common::impls::ToAuthor;
use sp_runtime::traits::ConvertInto;
use polkadot_runtime_common::{impls::ToAuthor, xcm_sender::ExponentialPrice};
use sp_runtime::traits::{AccountIdConversion, ConvertInto};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
@@ -49,6 +50,7 @@ use xcm_builder::{
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, StartsWith, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
XcmFeeManagerFromComponents, XcmFeeToAccount,
};
use xcm_executor::{traits::JustTry, XcmExecutor};
@@ -59,6 +61,7 @@ parameter_types! {
pub const RelayNetwork: Option<NetworkId> = None;
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into();
pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating();
}
/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
@@ -331,7 +334,10 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager = XcmFeeManagerFromComponents<
(),
XcmFeeToAccount<Self::AssetTransactor, AccountId, TreasuryAccount>,
>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = RuntimeCall;
@@ -355,11 +361,14 @@ pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
pub type PriceForParentDelivery =
ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
/// The means for routing XCM messages which are not for local execution into the right message
/// queues.
pub type XcmRouter = WithUniqueTopic<(
// Two routers - use UMP to communicate with the relay chain:
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, ()>,
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, PriceForParentDelivery>,
// ..and XCMP to communicate with the sibling chains.
XcmpQueue,
)>;