Skip to content

Commit

Permalink
[xcm] Use Weight::MAX for reserve_asset_deposited, `receive_telep…
Browse files Browse the repository at this point in the history
…orted_asset` benchmarks (#1726)

# Description

## Summary

Previously, the `pallet_xcm::do_reserve_transfer_assets` and
`pallet_xcm::do_teleport_assets` functions relied on weight estimation
for remote chain execution, which was based on guesswork derived from
the local chain. This approach led to complications for runtimes that
did not provide or support specific [XCM
configurations](https://github.com/paritytech/polkadot-sdk/blob/7cbe0c76ef8fd2aabf9f07de0156941ce3ed44b0/polkadot/xcm/xcm-executor/src/config.rs#L43-L47)
for `IsReserve` or `IsTeleporter`. Consequently, such runtimes had to
resort to implementing hard-coded weights for XCM instructions like
`reserve_asset_deposited` or `receive_teleported_asset` to support
extrinsics such as `pallet_xcm::reserve_transfer_assets` and
`pallet_xcm::teleport_assets`, which depended on remote weight
estimation.

The issue of remote weight estimation was addressed and resolved by
[Pull Request
#1645](#1645), which
removed the need for remote weight estimation.

## Solution

As a continuation of this improvement, the current PR proposes further
cleanup by removing unnecessary hard-coded values and rectifying
benchmark results with `Weight::MAX` that previously used
`T::BlockWeights::get().max_block` as an override for unsupported XCM
instructions like `ReserveAssetDeposited` and `ReceiveTeleportedAsset`.


## Questions

- [x] Can we remove now also `Hardcoded till the XCM pallet is fixed`
for `deposit_asset`? E.g. for AssetHubKusama
[here](https://github.com/paritytech/polkadot-sdk/blob/7cbe0c76ef8fd2aabf9f07de0156941ce3ed44b0/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/xcm/mod.rs#L129-L134)
- [x] Are comments like
[this](https://github.com/paritytech/polkadot-sdk/blob/7cbe0c76ef8fd2aabf9f07de0156941ce3ed44b0/polkadot/runtime/kusama/src/weights/xcm/mod.rs#L94)
`// Kusama doesn't support ReserveAssetDeposited, so this benchmark has
a default weight` still relevant? Shouldnt be removed/changed?


## TODO

- [x] `bench bot` regenerate xcm weights for all runtimes
- [x] remove hard-coded stuff from system parachain weight files
- [ ] when merged, open `polkadot-fellow/runtimes` PR

## References

Fixes #1132
Closes #1132
Old polkadot repo [PR](paritytech/polkadot#7546)

---------

Co-authored-by: command-bot <>
  • Loading branch information
bkontur authored Oct 10, 2023
1 parent ebf4423 commit e3c97e4
Show file tree
Hide file tree
Showing 21 changed files with 381 additions and 454 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ fn relay_origin_assertions(t: RelayToSystemParaTest) {
);
}

fn system_para_dest_assertions_incomplete(_t: RelayToSystemParaTest) {
AssetHubWestend::assert_dmp_queue_incomplete(
Some(Weight::from_parts(1_000_000_000, 0)),
Some(Error::UntrustedReserveLocation),
);
fn system_para_dest_assertions(_t: RelayToSystemParaTest) {
AssetHubWestend::assert_dmp_queue_error(Error::WeightNotComputable);
}

fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) {
Expand Down Expand Up @@ -178,7 +175,7 @@ fn limited_reserve_transfer_native_asset_from_relay_to_system_para_fails() {
let receiver_balance_before = test.receiver.balance;

test.set_assertion::<Westend>(relay_origin_assertions);
test.set_assertion::<AssetHubWestend>(system_para_dest_assertions_incomplete);
test.set_assertion::<AssetHubWestend>(system_para_dest_assertions);
test.set_dispatchable::<Westend>(relay_limited_reserve_transfer_assets);
test.assert();

Expand Down Expand Up @@ -237,7 +234,7 @@ fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
let receiver_balance_before = test.receiver.balance;

test.set_assertion::<Westend>(relay_origin_assertions);
test.set_assertion::<AssetHubWestend>(system_para_dest_assertions_incomplete);
test.set_assertion::<AssetHubWestend>(system_para_dest_assertions);
test.set_dispatchable::<Westend>(relay_reserve_transfer_assets);
test.assert();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;

AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts(
2_176_414_000,
203_593,
16_290_336_000,
562_893,
)));

assert_expected_events!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn para_origin_assertions(t: SystemParaToRelayTest) {
fn para_dest_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;

AssetHubWestend::assert_dmp_queue_complete(Some(Weight::from_parts(164_733_000, 0)));
AssetHubWestend::assert_dmp_queue_complete(Some(Weight::from_parts(164_793_000, 3593)));

assert_expected_events!(
AssetHubWestend,
Expand Down Expand Up @@ -142,16 +142,15 @@ fn system_para_limited_teleport_assets(t: SystemParaToRelayTest) -> DispatchResu
)
}

// TODO: Uncomment when https://github.com/paritytech/polkadot/pull/7424 is merged
// fn system_para_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
// <AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::teleport_assets(
// t.signed_origin,
// bx!(t.args.dest),
// bx!(t.args.beneficiary),
// bx!(t.args.assets),
// t.args.fee_asset_item,
// )
// }
fn system_para_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}

/// Limited Teleport of native asset from Relay Chain to the System Parachain should work
#[test]
Expand Down Expand Up @@ -286,78 +285,75 @@ fn teleport_native_assets_from_relay_to_system_para_works() {
assert!(receiver_balance_after > receiver_balance_before);
}

// TODO: Uncomment when https://github.com/paritytech/polkadot/pull/7424 is merged

// Right now it is failing in the Relay Chain with a
// `messageQueue.ProcessingFailed` event `error: Unsupported`.
// The reason is the `Weigher` in `pallet_xcm` is not properly calculating the `remote_weight`
// and it cause an `Overweight` error in `AllowTopLevelPaidExecutionFrom` barrier

// /// Teleport of native asset from System Parachains to the Relay Chain
// /// should work when there is enough balance in Relay Chain's `CheckAccount`
// #[test]
// fn teleport_native_assets_back_from_system_para_to_relay_works() {
// // Dependency - Relay Chain's `CheckAccount` should have enough balance
// teleport_native_assets_from_relay_to_system_para_works();

// // Init values for Relay Chain
// let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
// let test_args = TestContext {
// sender: AssetHubWestendSender::get(),
// receiver: WestendReceiver::get(),
// args: get_para_dispatch_args(amount_to_send),
// };

// let mut test = SystemParaToRelayTest::new(test_args);

// let sender_balance_before = test.sender.balance;
// let receiver_balance_before = test.receiver.balance;

// test.set_assertion::<AssetHubWestend>(para_origin_assertions);
// test.set_assertion::<Westend>(relay_dest_assertions);
// test.set_dispatchable::<AssetHubWestend>(system_para_teleport_assets);
// test.assert();

// let sender_balance_after = test.sender.balance;
// let receiver_balance_after = test.receiver.balance;

// // Sender's balance is reduced
// assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// // Receiver's balance is increased
// assert!(receiver_balance_after > receiver_balance_before);
// }

// /// Teleport of native asset from System Parachain to Relay Chain
// /// shouldn't work when there is not enough balance in Relay Chain's `CheckAccount`
// #[test]
// fn teleport_native_assets_from_system_para_to_relay_fails() {
// // Init values for Relay Chain
// let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
// let assets = (Parent, amount_to_send).into();
//
// let test_args = TestContext {
// sender: AssetHubWestendSender::get(),
// receiver: WestendReceiver::get(),
// args: system_para_test_args(amount_to_send),
// assets,
// None
// };

// let mut test = SystemParaToRelayTest::new(test_args);

// let sender_balance_before = test.sender.balance;
// let receiver_balance_before = test.receiver.balance;

// test.set_assertion::<AssetHubWestend>(para_origin_assertions);
// test.set_assertion::<Westend>(relay_dest_assertions);
// test.set_dispatchable::<AssetHubWestend>(system_para_teleport_assets);
// test.assert();

// let sender_balance_after = test.sender.balance;
// let receiver_balance_after = test.receiver.balance;

// // Sender's balance is reduced
// assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// // Receiver's balance does not change
// assert_eq!(receiver_balance_after, receiver_balance_before);
// }
/// Teleport of native asset from System Parachains to the Relay Chain
/// should work when there is enough balance in Relay Chain's `CheckAccount`
#[test]
fn teleport_native_assets_back_from_system_para_to_relay_works() {
// Dependency - Relay Chain's `CheckAccount` should have enough balance
teleport_native_assets_from_relay_to_system_para_works();

// Init values for Relay Chain
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
let destination = AssetHubWestend::parent_location();
let beneficiary_id = WestendReceiver::get();
let assets = (Parent, amount_to_send).into();

let test_args = TestContext {
sender: AssetHubWestendSender::get(),
receiver: WestendReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};

let mut test = SystemParaToRelayTest::new(test_args);

let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;

test.set_assertion::<AssetHubWestend>(para_origin_assertions);
test.set_assertion::<Westend>(relay_dest_assertions);
test.set_dispatchable::<AssetHubWestend>(system_para_teleport_assets);
test.assert();

let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;

// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}

/// Teleport of native asset from System Parachain to Relay Chain
/// shouldn't work when there is not enough balance in Relay Chain's `CheckAccount`
#[test]
fn teleport_native_assets_from_system_para_to_relay_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
let destination = AssetHubWestend::parent_location();
let beneficiary_id = WestendReceiver::get();
let assets = (Parent, amount_to_send).into();

let test_args = TestContext {
sender: AssetHubWestendSender::get(),
receiver: WestendReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};

let mut test = SystemParaToRelayTest::new(test_args);

let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;

test.set_assertion::<AssetHubWestend>(para_origin_assertions);
test.set_assertion::<Westend>(relay_dest_assertions_fail);
test.set_dispatchable::<AssetHubWestend>(system_para_teleport_assets);
test.assert();

let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;

// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance does not change
assert_eq!(receiver_balance_after, receiver_balance_before);
}
16 changes: 16 additions & 0 deletions cumulus/parachains/integration-tests/emulated/common/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,22 @@ macro_rules! impl_assert_events_helpers_for_parachain {
);
}

/// Asserts a XCM from Relay Chain is executed with error
pub fn assert_dmp_queue_error(
expected_error: $crate::impls::Error,
) {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::DmpQueue($crate::impls::cumulus_pallet_dmp_queue::Event::ExecutedDownward {
outcome: $crate::impls::Outcome::Error(error), ..
}) => {
error: *error == expected_error,
},
]
);
}

/// Asserts a XCM from another Parachain is completely executed
pub fn assert_xcmp_queue_success(expected_weight: Option<$crate::impls::Weight>) {
$crate::impls::assert_expected_events!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,8 @@ impl<Call> XcmWeightInfo<Call> for AssetHubKusamaXcmWeight<Call> {
fn withdraw_asset(assets: &MultiAssets) -> Weight {
assets.weigh_multi_assets(XcmFungibleWeight::<Runtime>::withdraw_asset())
}
// Currently there is no trusted reserve (`IsReserve = ()`),
// but we need this hack for `pallet_xcm::reserve_transfer_assets`
// (TODO) fix https://github.com/paritytech/polkadot/pull/7424
// (TODO) fix https://github.com/paritytech/polkadot/pull/7546
fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight {
// TODO: if we change `IsReserve = ...` then use this line...
// TODO: or if remote weight estimation is fixed, then remove
// TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974
let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0);
hardcoded_weight.min(XcmFungibleWeight::<Runtime>::reserve_asset_deposited())
fn reserve_asset_deposited(assets: &MultiAssets) -> Weight {
assets.weigh_multi_assets(XcmFungibleWeight::<Runtime>::reserve_asset_deposited())
}
fn receive_teleported_asset(assets: &MultiAssets) -> Weight {
assets.weigh_multi_assets(XcmFungibleWeight::<Runtime>::receive_teleported_asset())
Expand Down Expand Up @@ -127,10 +119,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubKusamaXcmWeight<Call> {
}

fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight {
// Hardcoded till the XCM pallet is fixed
let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0);
let weight = assets.weigh_multi_assets(XcmFungibleWeight::<Runtime>::deposit_asset());
hardcoded_weight.min(weight)
assets.weigh_multi_assets(XcmFungibleWeight::<Runtime>::deposit_asset())
}
fn deposit_reserve_asset(
assets: &MultiAssetFilter,
Expand Down
Loading

0 comments on commit e3c97e4

Please sign in to comment.