Skip to content

Commit

Permalink
[pallet-xcm] fix transport fees for remote reserve transfers (parityt…
Browse files Browse the repository at this point in the history
…ech#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 <[email protected]>
  • Loading branch information
2 people authored and dharjeezy committed Mar 24, 2024
1 parent 3c7d6b0 commit 0aeb09f
Show file tree
Hide file tree
Showing 17 changed files with 291 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -552,24 +551,15 @@ 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(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
<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`;
Expand All @@ -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
Expand Down Expand Up @@ -634,24 +624,15 @@ 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;
<ForeignAssets as Inspect<_>>::balance(relay_native_asset_location.into(), &sender)
});
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`;
Expand Down Expand Up @@ -705,25 +686,15 @@ 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(|| {
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
<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`;
Expand All @@ -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");
Expand All @@ -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
Expand Down Expand Up @@ -788,24 +759,15 @@ 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;
<ForeignAssets as Inspect<_>>::balance(system_para_native_asset_location, &sender)
});
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`;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
});
Expand Down Expand Up @@ -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)
});
Expand Down Expand Up @@ -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)
});
Expand Down Expand Up @@ -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)
});
Expand Down Expand Up @@ -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)
});
Expand Down Expand Up @@ -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)
});
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 0aeb09f

Please sign in to comment.