Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pallet-xcm: add new flexible transfer_assets() call/extrinsic #2388

Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1cb3e4f
pallet-xcm: check filters in inner helper functions
acatangiu Nov 17, 2023
df85fce
pallet-xcm: refactor asset transfer for more general use-case
acatangiu Nov 17, 2023
97a06b5
pallet-xcm: add new flexible transfer_assets() call/extrinsic
acatangiu Nov 17, 2023
c16290a
add benchmark stubs
acatangiu Nov 17, 2023
296ab0b
WIP xcm-emulator: add bidirectional reserve transfers between local P…
acatangiu Nov 17, 2023
f9b262e
WIP bidirectional foreign assets transfer
acatangiu Nov 28, 2023
1e6f724
DNM add debug logs
acatangiu Nov 28, 2023
abebdab
pallet-xcm: support teleporting assets while paying with reserve-base…
acatangiu Nov 28, 2023
770185c
buy enough execution
acatangiu Nov 28, 2023
5a941d1
xcm-emulator: refine foreign assets transfer test
acatangiu Nov 29, 2023
25dbb41
xcm-emulator: dedup code and add tests to asset hub westend
acatangiu Nov 29, 2023
eea1e1d
xcm-emulator: deduplicate code even more
acatangiu Nov 29, 2023
0e38a63
move foreign assets transfers tests to teleport.rs
acatangiu Nov 29, 2023
5ff9d1f
pallet-xcm: refactor transfers XCMs building for better readability
acatangiu Nov 29, 2023
fbc22b1
pallet-xcm: more tests
acatangiu Nov 30, 2023
861627e
palle-xcm: more tests
acatangiu Nov 30, 2023
0d24ff9
remove unused import
acatangiu Nov 30, 2023
0ce572b
pallet-xcm: tests for teleported assets using reserve fees
acatangiu Nov 30, 2023
1ab9c5c
pallet-xcm: fix benchmarks
acatangiu Nov 30, 2023
e41f8af
pallet-xcm: add benchmark for transfer_assets()
acatangiu Dec 4, 2023
679da71
runtimes: implement pallet-xcm benchmarks
acatangiu Dec 4, 2023
e0a5bba
asset-hubs: fix pallet-xcm benchmarks
acatangiu Dec 4, 2023
a07298a
Merge branch 'master' of github.com:paritytech/polkadot-sdk into xcm-…
acatangiu Dec 4, 2023
76c4e2e
Revert "DNM add debug logs"
acatangiu Dec 4, 2023
926add5
add prdoc
acatangiu Dec 4, 2023
204d262
integration-tests: remove debug prints
acatangiu Dec 4, 2023
83947c0
Merge branch 'master' of github.com:paritytech/polkadot-sdk into xcm-…
acatangiu Dec 5, 2023
a394581
address review feedback
acatangiu Dec 5, 2023
8bd616f
".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime…
Dec 5, 2023
35c41c3
".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime…
Dec 5, 2023
ba92481
fix tests
acatangiu Dec 5, 2023
53fbf51
run pallet-xcm benchmarks
acatangiu Dec 5, 2023
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
2 changes: 0 additions & 2 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 @@ -15,6 +15,7 @@

mod genesis;
pub use genesis::{genesis, ED, PARA_ID_A, PARA_ID_B};
pub use penpal_runtime::xcm_config::{LocalTeleportableToAssetHub, XcmConfig};

// Substrate
use frame_support::traits::OnInitialize;
Expand Down Expand Up @@ -67,6 +68,7 @@ decl_test_parachains! {

// Penpal implementation
impl_accounts_helpers_for_parachain!(PenpalA);
impl_accounts_helpers_for_parachain!(PenpalB);
impl_assets_helpers_for_parachain!(PenpalA, Rococo);
impl_assets_helpers_for_parachain!(PenpalB, Westend);
impl_assert_events_helpers_for_parachain!(PenpalA);
Expand Down
104 changes: 104 additions & 0 deletions cumulus/parachains/integration-tests/emulated/common/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,107 @@ macro_rules! test_parachain_is_trusted_teleporter {
}
};
}

#[macro_export]
macro_rules! include_penpal_create_foreign_asset_on_asset_hub {
( $penpal:ident, $asset_hub:ident, $relay_ed:expr, $weight_to_fee:expr) => {
$crate::impls::paste::paste! {
pub fn penpal_create_foreign_asset_on_asset_hub(
asset_id_on_penpal: u32,
foreign_asset_at_asset_hub: MultiLocation,
ah_as_seen_by_penpal: MultiLocation,
is_sufficient: bool,
asset_owner: AccountId,
prefund_amount: u128,
) {
use frame_support::weights::WeightToFee;
let ah_check_account = $asset_hub::execute_with(|| {
<$asset_hub as [<$asset_hub Pallet>]>::PolkadotXcm::check_account()
});
let penpal_check_account =
$penpal::execute_with(|| <$penpal as [<$penpal Pallet>]>::PolkadotXcm::check_account());
let penpal_as_seen_by_ah = $asset_hub::sibling_location_of($penpal::para_id());

// prefund SA of Penpal on AssetHub with enough native tokens to pay for creating
// new foreign asset, also prefund CheckingAccount with ED, because teleported asset
// itself might not be sufficient and CheckingAccount cannot be created otherwise
let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah);
$asset_hub::fund_accounts(vec![
(sov_penpal_on_ah.clone().into(), $relay_ed * 100_000_000_000),
(ah_check_account.clone().into(), $relay_ed * 1000),
]);

// prefund SA of AssetHub on Penpal with native asset
let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal);
$penpal::fund_accounts(vec![
(sov_ah_on_penpal.into(), $relay_ed * 1_000_000_000),
(penpal_check_account.clone().into(), $relay_ed * 1000),
]);

// Force create asset on $penpal and prefund [<$penpal Sender>]
$penpal::force_create_and_mint_asset(
asset_id_on_penpal,
ASSET_MIN_BALANCE,
is_sufficient,
asset_owner,
None,
prefund_amount,
);

let require_weight_at_most = Weight::from_parts(1_100_000_000_000, 30_000);
let origin_kind = OriginKind::Xcm;
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
let sov_penpal_on_ah_as_location = MultiLocation {
parents: 0,
interior: X1(
AccountId32Junction { network: None, id: sov_penpal_on_ah.clone().into() }
),
};
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
let call_create_foreign_assets =
<$asset_hub as Chain>::RuntimeCall::ForeignAssets(pallet_assets::Call::<
<$asset_hub as Chain>::Runtime,
pallet_assets::Instance2,
>::create {
id: foreign_asset_at_asset_hub,
min_balance: ASSET_MIN_BALANCE,
admin: sov_penpal_on_ah.into(),
})
.encode();
let buy_execution_fee_amount = $weight_to_fee::weight_to_fee(
&Weight::from_parts(10_100_000_000_000, 300_000),
);
let buy_execution_fee = MultiAsset {
id: Concrete(MultiLocation { parents: 1, interior: Here }),
fun: Fungible(buy_execution_fee_amount),
};
let xcm = VersionedXcm::from(Xcm(vec![
WithdrawAsset { 0: vec![buy_execution_fee.clone()].into() },
BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited },
Transact { require_weight_at_most, origin_kind, call: call_create_foreign_assets.into() },
ExpectTransactStatus(MaybeErrorCode::Success),
RefundSurplus,
DepositAsset { assets: All.into(), beneficiary: sov_penpal_on_ah_as_location },
]));
// Send XCM message from penpal => asset_hub
let sudo_penpal_origin = <$penpal as Chain>::RuntimeOrigin::root();
$penpal::execute_with(|| {
assert_ok!(<$penpal as [<$penpal Pallet>]>::PolkadotXcm::send(
sudo_penpal_origin.clone(),
bx!(ah_as_seen_by_penpal.into()),
bx!(xcm),
));
type RuntimeEvent = <$penpal as Chain>::RuntimeEvent;
assert_expected_events!(
$penpal,
vec![
RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {},
]
);
});
$asset_hub::execute_with(|| {
type ForeignAssets = <$asset_hub as [<$asset_hub Pallet>]>::ForeignAssets;
assert!(ForeignAssets::asset_exists(foreign_asset_at_asset_hub));
});
}
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,17 @@ pub fn xcm_transact_unpaid_execution(
Transact { require_weight_at_most, origin_kind, call },
]))
}

/// Helper method to get the non-fee asset used in multiple assets transfer
pub fn non_fee_asset(assets: &MultiAssets, fee_idx: usize) -> Option<(MultiLocation, u128)> {
let asset = assets.inner().into_iter().enumerate().find(|a| a.0 != fee_idx)?.1.clone();
let asset_id = match asset.id {
Concrete(id) => id,
_ => return None,
};
let asset_amount = match asset.fun {
Fungible(amount) => amount,
_ => return None,
};
Some((asset_id, asset_amount))
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,4 @@ asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
parachains-common = { path = "../../../../../../parachains/common" }
asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
emulated-integration-tests-common = { path = "../../../common", default-features = false }
penpal-runtime = { path = "../../../../../runtimes/testing/penpal" }
rococo-system-emulated-network = { path = "../../../networks/rococo-system" }
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ mod send;
mod set_xcm_versions;
mod swap;
mod teleport;

use crate::*;
emulated_integration_tests_common::include_penpal_create_foreign_asset_on_asset_hub!(
PenpalA,
AssetHubRococo,
ROCOCO_ED,
parachains_common::rococo::fee::WeightToFee
);
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@

use crate::*;
use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig;
use penpal_runtime::xcm_config::XcmConfig as PenpalRococoXcmConfig;
use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;
use rococo_system_emulated_network::penpal_emulated_chain::XcmConfig as PenpalRococoXcmConfig;

fn relay_to_para_sender_assertions(t: RelayToParaTest) {
type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;

Rococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(864_610_000, 8_799)));

assert_expected_events!(
Rococo,
vec![
Expand All @@ -42,12 +40,10 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) {

fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;

AssetHubRococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
864_610_000,
8_799,
)));

assert_expected_events!(
AssetHubRococo,
vec![
Expand Down Expand Up @@ -80,9 +76,7 @@ fn para_receiver_assertions<Test>(_: Test) {

fn para_to_system_para_sender_assertions(t: ParaToSystemParaTest) {
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;

PenpalA::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(864_610_000, 8_799)));

assert_expected_events!(
PenpalA,
vec![
Expand All @@ -99,15 +93,13 @@ fn para_to_system_para_sender_assertions(t: ParaToSystemParaTest) {

fn para_to_system_para_receiver_assertions(t: ParaToSystemParaTest) {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;

let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(
AssetHubRococo::sibling_location_of(PenpalA::para_id()),
);

assert_expected_events!(
AssetHubRococo,
vec![
// Amount to reserve transfer is transferred to Parachain's Sovereign account
// Amount to reserve transfer is withdrawn from Parachain's Sovereign account
RuntimeEvent::Balances(
pallet_balances::Event::Withdraw { who, amount }
) => {
Expand All @@ -124,12 +116,10 @@ fn para_to_system_para_receiver_assertions(t: ParaToSystemParaTest) {

fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;

AssetHubRococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
864_610_000,
8799,
)));

assert_expected_events!(
AssetHubRococo,
vec![
Expand Down Expand Up @@ -162,7 +152,7 @@ fn system_para_to_para_assets_receiver_assertions<Test>(_: Test) {
);
}

fn relay_to_para_limited_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
<Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
Expand All @@ -173,7 +163,7 @@ fn relay_to_para_limited_reserve_transfer_assets(t: RelayToParaTest) -> Dispatch
)
}

fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
Expand All @@ -184,7 +174,7 @@ fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest)
)
}

fn para_to_system_para_limited_reserve_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult {
fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult {
<PenpalA as PenpalAPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
Expand Down Expand Up @@ -285,7 +275,7 @@ fn reserve_transfer_native_asset_from_relay_to_para() {

test.set_assertion::<Rococo>(relay_to_para_sender_assertions);
test.set_assertion::<PenpalA>(para_receiver_assertions);
test.set_dispatchable::<Rococo>(relay_to_para_limited_reserve_transfer_assets);
test.set_dispatchable::<Rococo>(relay_to_para_reserve_transfer_assets);
test.assert();

let delivery_fees = Rococo::execute_with(|| {
Expand Down Expand Up @@ -329,7 +319,7 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {

test.set_assertion::<AssetHubRococo>(system_para_to_para_sender_assertions);
test.set_assertion::<PenpalA>(para_receiver_assertions);
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_limited_reserve_transfer_assets);
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_reserve_transfer_assets);
test.assert();

let sender_balance_after = test.sender.balance;
Expand Down Expand Up @@ -379,7 +369,7 @@ fn reserve_transfer_native_asset_from_para_to_system_para() {

test.set_assertion::<PenpalA>(para_to_system_para_sender_assertions);
test.set_assertion::<AssetHubRococo>(para_to_system_para_receiver_assertions);
test.set_dispatchable::<PenpalA>(para_to_system_para_limited_reserve_transfer_assets);
test.set_dispatchable::<PenpalA>(para_to_system_para_reserve_transfer_assets);
test.assert();

let sender_balance_after = test.sender.balance;
Expand Down Expand Up @@ -474,7 +464,7 @@ fn reserve_transfer_assets_from_system_para_to_para() {

test.set_assertion::<AssetHubRococo>(system_para_to_para_assets_sender_assertions);
test.set_assertion::<PenpalA>(system_para_to_para_assets_receiver_assertions);
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_limited_reserve_transfer_assets);
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_reserve_transfer_assets);
test.assert();

let sender_balance_after = test.sender.balance;
Expand Down
Loading