Skip to content
Merged
Show file tree
Hide file tree
Changes from 89 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
5ac5af0
Add expensive scenario for asset exchange
raymondkfcheung Mar 18, 2025
5d2049d
Update from github-actions[bot] running command 'prdoc --audience run…
github-actions[bot] Mar 18, 2025
c6ff6ec
Use MAX_ITEMS_IN_ASSETS
raymondkfcheung Mar 18, 2025
f53a889
Update comment
raymondkfcheung Mar 18, 2025
bb505c1
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 18, 2025
5dfe33a
Add TODO
raymondkfcheung Mar 18, 2025
6df104a
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 18, 2025
6a8d95b
Create pool
raymondkfcheung Mar 18, 2025
4b205ba
Update comment
raymondkfcheung Mar 18, 2025
b5c98a6
Update code style
raymondkfcheung Mar 18, 2025
1904c4e
Update cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
raymondkfcheung Mar 19, 2025
2e6338b
Update lib.rs
raymondkfcheung Mar 19, 2025
59cc394
Update lib.rs
raymondkfcheung Mar 19, 2025
0e3c3ff
Update cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
raymondkfcheung Mar 20, 2025
6ff1374
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 20, 2025
827725c
Remove comments
raymondkfcheung Mar 20, 2025
b7c2992
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 20, 2025
1461d11
Add placeholder for weight
raymondkfcheung Mar 20, 2025
6562e6b
Merge remote-tracking branch 'origin/ray-fix-worst-case' into ray-fix…
raymondkfcheung Mar 20, 2025
d35cc0a
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 20, 2025
9780a89
Update cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
raymondkfcheung Mar 20, 2025
5486afd
Update cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
raymondkfcheung Mar 20, 2025
1f0b7ad
Update 1:1
raymondkfcheung Mar 20, 2025
39a1a76
Merge remote-tracking branch 'origin/ray-fix-worst-case' into ray-fix…
raymondkfcheung Mar 20, 2025
3778d76
Update format
raymondkfcheung Mar 20, 2025
f0a235e
Remove clone
raymondkfcheung Mar 20, 2025
7651c63
Revert change
raymondkfcheung Mar 20, 2025
7603169
Update lib.rs
raymondkfcheung Mar 20, 2025
0e8612f
Update lib.rs
raymondkfcheung Mar 20, 2025
1a228a6
Add debug logs
raymondkfcheung Mar 20, 2025
d73c4d4
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 20, 2025
4cc5a61
Merge remote-tracking branch 'origin/ray-fix-worst-case' into ray-fix…
raymondkfcheung Mar 20, 2025
b9ed27f
Try to fix
raymondkfcheung Mar 20, 2025
b9d03b9
Try to fix #2
raymondkfcheung Mar 20, 2025
7ccf2a7
Try to fix #3
raymondkfcheung Mar 20, 2025
0918335
Try to fix #4
raymondkfcheung Mar 20, 2025
816318f
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 20, 2025
9f014d5
Nits
bkontur Mar 20, 2025
259eb64
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 21, 2025
3ab0af6
Use assert
raymondkfcheung Mar 21, 2025
7d8b94c
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 21, 2025
ed6e2b9
Fix fmt
raymondkfcheung Mar 21, 2025
0973019
Add more logs
raymondkfcheung Mar 21, 2025
b617e1a
Make it pass
raymondkfcheung Mar 21, 2025
1062900
Make it pass v2
raymondkfcheung Mar 21, 2025
5da20d2
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 21, 2025
27755de
Add tracing
raymondkfcheung Mar 21, 2025
e31db53
Remove tracing
raymondkfcheung Mar 21, 2025
04a0dfe
Comment exchange_asset
raymondkfcheung Mar 21, 2025
d938368
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 21, 2025
8e0bc75
Comment assert_eq only
raymondkfcheung Mar 21, 2025
d00fcf5
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 24, 2025
e589021
Uncomment
raymondkfcheung Mar 24, 2025
409e5e8
Fix ratio
raymondkfcheung Mar 24, 2025
77bb4fc
Uncomment assert_eq
raymondkfcheung Mar 24, 2025
3164a77
Use contains
raymondkfcheung Mar 24, 2025
4ba3627
Remove logs
raymondkfcheung Mar 24, 2025
6c7f1c3
Use BenchmarkError
raymondkfcheung Mar 24, 2025
ba6d264
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 24, 2025
e13dca2
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 25, 2025
e891567
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 25, 2025
04cb06a
Use fixed weight
raymondkfcheung Mar 25, 2025
bca15f5
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 25, 2025
89a33bc
Add test placeholder
raymondkfcheung Mar 25, 2025
1d1c384
Revert "Use fixed weight"
raymondkfcheung Mar 25, 2025
afd9fc1
Update from github-actions[bot] running command 'bench --pallet palle…
github-actions[bot] Mar 25, 2025
bbbc8f1
Use max(give, receive)
raymondkfcheung Mar 25, 2025
17aa6d6
Remove unused import
raymondkfcheung Mar 25, 2025
22f73ce
Simplify the code
raymondkfcheung Mar 25, 2025
9eba60e
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 25, 2025
f60ce0b
Use BenchmarkError
raymondkfcheung Mar 25, 2025
6b846d1
Remove comments
raymondkfcheung Mar 25, 2025
791a851
Add tests
raymondkfcheung Mar 25, 2025
ed7607b
Fix tests
raymondkfcheung Mar 25, 2025
c8173e4
Fix tests v2
raymondkfcheung Mar 26, 2025
5b50223
Use assert_ok
raymondkfcheung Mar 26, 2025
dfd0975
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 26, 2025
443c2e0
Update PRDoc
raymondkfcheung Mar 26, 2025
aec4409
Fix test
raymondkfcheung Mar 26, 2025
dbaf905
Fix test
raymondkfcheung Mar 26, 2025
7da94cd
Fix test
raymondkfcheung Mar 26, 2025
80c410d
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 26, 2025
11c91b5
Fix fmt
raymondkfcheung Mar 26, 2025
7c0e1be
Fix test
raymondkfcheung Mar 26, 2025
c13e62b
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 26, 2025
ab2bc50
Fix test
raymondkfcheung Mar 26, 2025
aac1a42
Fix test
raymondkfcheung Mar 26, 2025
861c026
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 26, 2025
318c692
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 26, 2025
58b3365
Merge branch 'master' into ray-fix-worst-case
raymondkfcheung Mar 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ cumulus-pallet-xcmp-queue = { workspace = true }
emulated-integration-tests-common = { workspace = true }
parachains-common = { workspace = true, default-features = true }
westend-system-emulated-network = { workspace = true }

[dev-dependencies]
sp-tracing = { features = ["test-utils"], workspace = true, default-features = true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{
create_pool_with_wnd_on,
imports::{
asset_hub_westend_runtime::{ExistentialDeposit, Runtime},
*,
},
};
use asset_hub_westend_runtime::{
xcm_config::WestendLocation, Balances, ForeignAssets, PolkadotXcm, RuntimeOrigin,
};
use emulated_integration_tests_common::{accounts::ALICE, xcm_emulator::TestExt};
use frame_support::{
assert_err_ignore_postinfo, assert_ok,
traits::fungible::{Inspect, Mutate},
};
use parachains_common::{AccountId, Balance};
use sp_tracing::capture_test_logs;
use std::convert::Into;
use xcm::latest::{Assets, Location, Xcm};

const UNITS: Balance = 1_000_000_000;

#[test]
fn exchange_asset_success() {
test_exchange_asset(true, 500 * UNITS, 665 * UNITS, true);
}

#[test]
fn exchange_asset_insufficient_liquidity() {
let log_capture = capture_test_logs!({
test_exchange_asset(true, 1_000 * UNITS, 2_000 * UNITS, false);
});
assert!(log_capture.contains("NoDeal"));
}

#[test]
fn exchange_asset_insufficient_balance() {
let log_capture = capture_test_logs!({
test_exchange_asset(true, 5_000 * UNITS, 1_665 * UNITS, false);
});
assert!(log_capture.contains("Funds are unavailable"));
}

#[test]
fn exchange_asset_pool_not_created() {
test_exchange_asset(false, 500 * UNITS, 665 * UNITS, false);
}
Comment on lines +39 to +62
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this tests interact just with AssetHubWestend runtimes, so they could be added as unit-tests directly to the AssetHubWestend runtime module - for that we have also asset-test-utils with predefined test-cases, co we don't need to copy those tests.

For emulated, I would expect here some cross-chain/runtimes interaction - e.g. Penpal wants to exchange assets on AssetHub and pay fees there or something like that.

Copy link
Copy Markdown
Contributor Author

@raymondkfcheung raymondkfcheung Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll do it on the follow-up PR #8074.


fn test_exchange_asset(
create_pool: bool,
give_amount: Balance,
want_amount: Balance,
should_succeed: bool,
) {
let alice: AccountId = Westend::account_id_of(ALICE);
let native_asset_location = WestendLocation::get();
let native_asset_id = AssetId(native_asset_location.clone());
let origin = RuntimeOrigin::signed(alice.clone());
let asset_location = Location::new(1, [Parachain(2001)]);
let asset_id = AssetId(asset_location.clone());

// Setup initial state
AssetHubWestend::execute_with(|| {
assert_ok!(<Balances as Mutate<_>>::mint_into(
&alice,
ExistentialDeposit::get() + (1_000 * UNITS)
));

assert_ok!(ForeignAssets::force_create(
RuntimeOrigin::root(),
asset_location.clone().into(),
alice.clone().into(),
true,
1
));
});

if create_pool {
create_pool_with_wnd_on!(AssetHubWestend, asset_location.clone(), true, alice.clone());
}

// Execute and verify swap
AssetHubWestend::execute_with(|| {
let foreign_balance_before = ForeignAssets::balance(asset_location.clone(), &alice);
let wnd_balance_before = Balances::total_balance(&alice);

let give: Assets = (native_asset_id, give_amount).into();
let want: Assets = (asset_id, want_amount).into();
let xcm = Xcm(vec![
WithdrawAsset(give.clone().into()),
ExchangeAsset { give: give.into(), want: want.into(), maximal: true },
DepositAsset { assets: Wild(All), beneficiary: alice.clone().into() },
]);

let result = PolkadotXcm::execute(origin, bx!(xcm::VersionedXcm::from(xcm)), Weight::MAX);

let foreign_balance_after = ForeignAssets::balance(asset_location, &alice);
let wnd_balance_after = Balances::total_balance(&alice);

if should_succeed {
assert_ok!(result);
assert!(
foreign_balance_after >= foreign_balance_before + want_amount,
"Expected foreign balance to increase by at least {want_amount} units, got {foreign_balance_after} from {foreign_balance_before}"
);
assert_eq!(
wnd_balance_after, wnd_balance_before - give_amount,
"Expected WND balance to decrease by {give_amount} units, got {wnd_balance_after} from {wnd_balance_before}"
);
} else {
assert_err_ignore_postinfo!(
result,
pallet_xcm::Error::<Runtime>::LocalExecutionIncomplete
);
assert_eq!(
foreign_balance_after, foreign_balance_before,
"Foreign balance changed unexpectedly: got {foreign_balance_after}, expected {foreign_balance_before}"
);
assert_eq!(
wnd_balance_after, wnd_balance_before,
"WND balance changed unexpectedly: got {wnd_balance_after}, expected {wnd_balance_before}"
);
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.

mod claim_assets;
mod exchange_asset;
mod fellowship_treasury;
mod hybrid_transfers;
mod reserve_transfer;
Expand Down
49 changes: 48 additions & 1 deletion cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2167,7 +2167,54 @@ impl_runtime_apis! {
}

fn worst_case_asset_exchange() -> Result<(XcmAssets, XcmAssets), BenchmarkError> {
Err(BenchmarkError::Skip)
let native_asset_location = WestendLocation::get();
let native_asset_id = AssetId(native_asset_location.clone());
let (account, _) = pallet_xcm_benchmarks::account_and_location::<Runtime>(1);
let origin = RuntimeOrigin::signed(account.clone());
let asset_location = Location::new(1, [Parachain(2001)]);
let asset_id = AssetId(asset_location.clone());

assert_ok!(<Balances as fungible::Mutate<_>>::mint_into(
&account,
ExistentialDeposit::get() + (1_000 * UNITS)
));

assert_ok!(ForeignAssets::force_create(
RuntimeOrigin::root(),
asset_location.clone().into(),
account.clone().into(),
true,
1,
));

assert_ok!(ForeignAssets::mint(
origin.clone(),
asset_location.clone().into(),
account.clone().into(),
3_000 * UNITS,
));

assert_ok!(AssetConversion::create_pool(
origin.clone(),
native_asset_location.clone().into(),
asset_location.clone().into(),
));

assert_ok!(AssetConversion::add_liquidity(
origin,
native_asset_location.into(),
asset_location.into(),
1_000 * UNITS,
2_000 * UNITS,
1,
1,
account.into(),
));

let give_assets: XcmAssets = (native_asset_id, 500 * UNITS).into();
let receive_assets: XcmAssets = (asset_id, 660 * UNITS).into();

Ok((give_assets, receive_assets))
}

fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,11 @@ impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> {
fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
assets.weigh_assets(XcmFungibleWeight::<Runtime>::deposit_reserve_asset())
}
fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight {
XcmFungibleWeight::<Runtime>::exchange_asset()
fn exchange_asset(give: &AssetFilter, receive: &Assets, _maximal: &bool) -> Weight {
let base_weight = XcmGeneric::<Runtime>::exchange_asset();
let give_weight = give.weigh_assets(base_weight);
let receive_weight = receive.weigh_assets(base_weight);
give_weight.max(receive_weight)
}
fn initiate_reserve_withdraw(
assets: &AssetFilter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
//! Autogenerated weights for `pallet_xcm_benchmarks::fungible`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-03-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2025-03-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `20719bd74377`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! HOSTNAME: `c2cc39483446`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024

// Executed Command:
Expand Down Expand Up @@ -64,8 +64,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `527`
// Estimated: `3675`
// Minimum execution time: 56_528_000 picoseconds.
Weight::from_parts(58_602_000, 3675)
// Minimum execution time: 55_738_000 picoseconds.
Weight::from_parts(57_700_000, 3675)
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(5))
}
Expand All @@ -81,8 +81,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `426`
// Estimated: `6208`
// Minimum execution time: 52_035_000 picoseconds.
Weight::from_parts(53_454_000, 6208)
// Minimum execution time: 52_416_000 picoseconds.
Weight::from_parts(53_673_000, 6208)
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(4))
}
Expand All @@ -108,17 +108,17 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `638`
// Estimated: `8799`
// Minimum execution time: 128_026_000 picoseconds.
Weight::from_parts(133_433_000, 8799)
// Minimum execution time: 130_383_000 picoseconds.
Weight::from_parts(134_409_000, 8799)
.saturating_add(T::DbWeight::get().reads(12))
.saturating_add(T::DbWeight::get().writes(7))
}
pub fn reserve_asset_deposited() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 1_272_000 picoseconds.
Weight::from_parts(1_371_000, 0)
// Minimum execution time: 1_397_000 picoseconds.
Weight::from_parts(1_511_000, 0)
}
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
Expand All @@ -136,17 +136,17 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `212`
// Estimated: `6196`
// Minimum execution time: 109_813_000 picoseconds.
Weight::from_parts(112_513_000, 6196)
// Minimum execution time: 109_295_000 picoseconds.
Weight::from_parts(120_413_000, 6196)
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(3))
}
pub fn receive_teleported_asset() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 2_885_000 picoseconds.
Weight::from_parts(3_112_000, 0)
// Minimum execution time: 2_910_000 picoseconds.
Weight::from_parts(3_056_000, 0)
}
// Storage: `Assets::Asset` (r:1 w:1)
// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
Expand All @@ -158,8 +158,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `314`
// Estimated: `3675`
// Minimum execution time: 32_702_000 picoseconds.
Weight::from_parts(33_820_000, 3675)
// Minimum execution time: 32_342_000 picoseconds.
Weight::from_parts(34_037_000, 3675)
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(3))
}
Expand All @@ -183,8 +183,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `425`
// Estimated: `3890`
// Minimum execution time: 70_293_000 picoseconds.
Weight::from_parts(73_276_000, 3890)
// Minimum execution time: 72_043_000 picoseconds.
Weight::from_parts(74_586_000, 3890)
.saturating_add(T::DbWeight::get().reads(8))
.saturating_add(T::DbWeight::get().writes(4))
}
Expand All @@ -204,8 +204,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `425`
// Estimated: `3890`
// Minimum execution time: 53_316_000 picoseconds.
Weight::from_parts(55_533_000, 3890)
// Minimum execution time: 53_342_000 picoseconds.
Weight::from_parts(56_209_000, 3890)
.saturating_add(T::DbWeight::get().reads(6))
.saturating_add(T::DbWeight::get().writes(1))
}
Expand All @@ -229,19 +229,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `425`
// Estimated: `6196`
// Minimum execution time: 87_707_000 picoseconds.
Weight::from_parts(92_810_000, 6196)
// Minimum execution time: 89_970_000 picoseconds.
Weight::from_parts(92_829_000, 6196)
.saturating_add(T::DbWeight::get().reads(9))
.saturating_add(T::DbWeight::get().writes(5))
}

pub fn exchange_asset() -> Weight {
// Proof Size summary in bytes:
// Measured: `159`
// Estimated: `6196`
// Minimum execution time: 87_253_000 picoseconds.
Weight::from_parts(88_932_000, 6196)
.saturating_add(T::DbWeight::get().reads(9))
.saturating_add(T::DbWeight::get().writes(4))
}
}
Loading
Loading