Skip to content

Commit

Permalink
Migrate foreign assets v3::Location to v4::Location (#4129)
Browse files Browse the repository at this point in the history
In the move from XCMv3 to XCMv4, the `AssetId` for `ForeignAssets` in
`asset-hub-rococo` and `asset-hub-westend` was left as `v3::Location` to
be later migrated to `v4::Location`.

This is that migration PR.

Because the encoding of `v3::Location` and `v4::Location` is the same,
we don't need to do any data migration, the keys will still be
decodable.
The [original idea by
Jan](paritytech/polkadot#7236) was to make the
v4 changes in v3 since the ABI (the encoding/decoding) didn't change.
Corroborated the ABI is the same iterating over all storage, the code is
on [another
branch](https://github.com/paritytech/polkadot-sdk/blob/cisco-assert-v3-v4-encodings-equal/cumulus/parachains/runtimes/assets/migrations/src/foreign_assets_to_v4/mod.rs).

We will need a data migration when we want to update from `v4::Location`
to `v5::Location` because of [the accepted RFC changing the NetworkId
enum](polkadot-fellows/RFCs#108).
I'll configure MBMs (Multi-Block Migrations) then and make the actual
migration.

Fixes #4128

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: command-bot <>
  • Loading branch information
franciscoaguirre and ggwpez authored Aug 14, 2024
1 parent 0cd577b commit be74fe9
Show file tree
Hide file tree
Showing 29 changed files with 951 additions and 886 deletions.
924 changes: 512 additions & 412 deletions Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ impl_accounts_helpers_for_parachain!(AssetHubRococo);
impl_assert_events_helpers_for_parachain!(AssetHubRococo);
impl_assets_helpers_for_system_parachain!(AssetHubRococo, Rococo);
impl_assets_helpers_for_parachain!(AssetHubRococo);
impl_foreign_assets_helpers_for_parachain!(AssetHubRococo, xcm::v3::Location);
impl_foreign_assets_helpers_for_parachain!(AssetHubRococo, xcm::v4::Location);
impl_xcm_helpers_for_parachain!(AssetHubRococo);
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ impl_accounts_helpers_for_parachain!(AssetHubWestend);
impl_assert_events_helpers_for_parachain!(AssetHubWestend);
impl_assets_helpers_for_system_parachain!(AssetHubWestend, Westend);
impl_assets_helpers_for_parachain!(AssetHubWestend);
impl_foreign_assets_helpers_for_parachain!(AssetHubWestend, xcm::v3::Location);
impl_foreign_assets_helpers_for_parachain!(AssetHubWestend, xcm::v4::Location);
impl_xcm_helpers_for_parachain!(AssetHubWestend);
10 changes: 5 additions & 5 deletions cumulus/parachains/integration-tests/emulated/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ pub const PENPAL_ID: u32 = 2000;
pub const ASSETS_PALLET_ID: u8 = 50;

parameter_types! {
pub PenpalTeleportableAssetLocation: xcm::v3::Location
= xcm::v3::Location::new(1, [
xcm::v3::Junction::Parachain(PENPAL_ID),
xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID),
xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into()),
pub PenpalTeleportableAssetLocation: xcm::v4::Location
= xcm::v4::Location::new(1, [
xcm::v4::Junction::Parachain(PENPAL_ID),
xcm::v4::Junction::PalletInstance(ASSETS_PALLET_ID),
xcm::v4::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into()),
]
);
pub PenpalSiblingSovereignAccount: AccountId = Sibling::from(PENPAL_ID).into_account_truncating();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,18 @@ fn send_xcm_from_para_to_system_para_paying_fee_with_system_assets_works() {
let para_sovereign_account = AssetHubRococo::sovereign_account_id_of(
AssetHubRococo::sibling_location_of(PenpalA::para_id()),
);
let asset_location_on_penpal = v3::Location::new(
let asset_location_on_penpal = Location::new(
0,
[
v3::Junction::PalletInstance(ASSETS_PALLET_ID),
v3::Junction::GeneralIndex(ASSET_ID.into()),
],
[Junction::PalletInstance(ASSETS_PALLET_ID), Junction::GeneralIndex(ASSET_ID.into())],
);
let foreign_asset_at_asset_hub =
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
Location::new(1, [Junction::Parachain(PenpalA::para_id().into())])
.appended_with(asset_location_on_penpal)
.unwrap();

// Encoded `create_asset` call to be executed in AssetHub
let call = AssetHubRococo::create_foreign_asset_call(
foreign_asset_at_asset_hub,
foreign_asset_at_asset_hub.clone(),
ASSET_MIN_BALANCE,
para_sovereign_account.clone(),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ use crate::imports::*;

#[test]
fn swap_locally_on_chain_using_local_assets() {
let asset_native = Box::new(v3::Location::try_from(RelayLocation::get()).unwrap());
let asset_one = Box::new(v3::Location::new(
let asset_native = Box::new(Location::try_from(RelayLocation::get()).unwrap());
let asset_one = Box::new(Location::new(
0,
[
v3::Junction::PalletInstance(ASSETS_PALLET_ID),
v3::Junction::GeneralIndex(ASSET_ID.into()),
],
[Junction::PalletInstance(ASSETS_PALLET_ID), Junction::GeneralIndex(ASSET_ID.into())],
));

AssetHubRococo::execute_with(|| {
Expand Down Expand Up @@ -112,11 +109,11 @@ fn swap_locally_on_chain_using_local_assets() {

#[test]
fn swap_locally_on_chain_using_foreign_assets() {
let asset_native = Box::new(v3::Location::try_from(RelayLocation::get()).unwrap());
let asset_native = Box::new(Location::try_from(RelayLocation::get()).unwrap());
let asset_location_on_penpal =
v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).unwrap();
Location::try_from(PenpalLocalTeleportableToAssetHub::get()).unwrap();
let foreign_asset_at_asset_hub_rococo =
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
Location::new(1, [Junction::Parachain(PenpalA::para_id().into())])
.appended_with(asset_location_on_penpal)
.unwrap();

Expand All @@ -141,7 +138,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
// 1. Mint foreign asset (in reality this should be a teleport or some such)
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::ForeignAssets::mint(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone().into()),
foreign_asset_at_asset_hub_rococo,
foreign_asset_at_asset_hub_rococo.clone(),
sov_penpal_on_ahr.clone().into(),
ASSET_HUB_ROCOCO_ED * 3_000_000_000_000,
));
Expand All @@ -157,7 +154,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::create_pool(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
asset_native.clone(),
Box::new(foreign_asset_at_asset_hub_rococo),
Box::new(foreign_asset_at_asset_hub_rococo.clone()),
));

assert_expected_events!(
Expand All @@ -171,7 +168,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::add_liquidity(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
asset_native.clone(),
Box::new(foreign_asset_at_asset_hub_rococo),
Box::new(foreign_asset_at_asset_hub_rococo.clone()),
1_000_000_000_000,
2_000_000_000_000,
0,
Expand All @@ -189,7 +186,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
);

// 4. Swap!
let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo)];
let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo.clone())];

assert_ok!(
<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::swap_exact_tokens_for_tokens(
Expand All @@ -216,7 +213,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::remove_liquidity(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
asset_native.clone(),
Box::new(foreign_asset_at_asset_hub_rococo),
Box::new(foreign_asset_at_asset_hub_rococo.clone()),
1414213562273 - ASSET_HUB_ROCOCO_ED * 2, // all but the 2 EDs can't be retrieved.
0,
0,
Expand Down Expand Up @@ -252,8 +249,8 @@ fn cannot_create_pool_from_pool_assets() {
assert_matches::assert_matches!(
<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::create_pool(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
Box::new(v3::Location::try_from(asset_native).unwrap()),
Box::new(v3::Location::try_from(asset_one).unwrap()),
Box::new(Location::try_from(asset_native).unwrap()),
Box::new(Location::try_from(asset_one).unwrap()),
),
Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown"))
);
Expand All @@ -262,12 +259,12 @@ fn cannot_create_pool_from_pool_assets() {

#[test]
fn pay_xcm_fee_with_some_asset_swapped_for_native() {
let asset_native = v3::Location::try_from(RelayLocation::get()).unwrap();
let asset_one = xcm::v3::Location {
let asset_native = Location::try_from(RelayLocation::get()).unwrap();
let asset_one = Location {
parents: 0,
interior: [
xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID),
xcm::v3::Junction::GeneralIndex(ASSET_ID.into()),
Junction::PalletInstance(ASSETS_PALLET_ID),
Junction::GeneralIndex(ASSET_ID.into()),
]
.into(),
};
Expand Down Expand Up @@ -296,8 +293,8 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() {

assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::create_pool(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
Box::new(asset_native),
Box::new(asset_one),
Box::new(asset_native.clone()),
Box::new(asset_one.clone()),
));

assert_expected_events!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
);
let (expected_foreign_asset_id, expected_foreign_asset_amount) =
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap();

AssetHubRococo::assert_xcmp_queue_success(None);

Expand All @@ -159,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
who: *who == t.receiver.account_id,
},
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => {
asset_id: *asset_id == expected_foreign_asset_id_v3,
asset_id: *asset_id == expected_foreign_asset_id,
owner: *owner == t.receiver.account_id,
amount: *amount == expected_foreign_asset_amount,
},
Expand All @@ -173,7 +172,6 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) {
AssetHubRococo::assert_xcm_pallet_attempted_complete(None);
let (expected_foreign_asset_id, expected_foreign_asset_amount) =
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap();
assert_expected_events!(
AssetHubRococo,
vec![
Expand All @@ -189,7 +187,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) {
},
// foreign asset is burned locally as part of teleportation
RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
asset_id: *asset_id == expected_foreign_asset_id_v3,
asset_id: *asset_id == expected_foreign_asset_id,
owner: *owner == t.sender.account_id,
balance: *balance == expected_foreign_asset_amount,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ mod imports {
};

// Polkadot
pub use xcm::{
prelude::{AccountId32 as AccountId32Junction, *},
v3,
};
pub use xcm::prelude::{AccountId32 as AccountId32Junction, *};
pub use xcm_executor::traits::TransferType;

// Cumulus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,18 @@ fn send_xcm_from_para_to_system_para_paying_fee_with_system_assets_works() {
let para_sovereign_account = AssetHubWestend::sovereign_account_id_of(
AssetHubWestend::sibling_location_of(PenpalA::para_id()),
);
let asset_location_on_penpal = v3::Location::new(
let asset_location_on_penpal = Location::new(
0,
[
v3::Junction::PalletInstance(ASSETS_PALLET_ID),
v3::Junction::GeneralIndex(ASSET_ID.into()),
],
[Junction::PalletInstance(ASSETS_PALLET_ID), Junction::GeneralIndex(ASSET_ID.into())],
);
let foreign_asset_at_asset_hub =
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
Location::new(1, [Junction::Parachain(PenpalA::para_id().into())])
.appended_with(asset_location_on_penpal)
.unwrap();

// Encoded `create_asset` call to be executed in AssetHub
let call = AssetHubWestend::create_foreign_asset_call(
foreign_asset_at_asset_hub,
foreign_asset_at_asset_hub.clone(),
ASSET_MIN_BALANCE,
para_sovereign_account.clone(),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ use crate::imports::*;
#[test]
fn swap_locally_on_chain_using_local_assets() {
let asset_native =
Box::new(v3::Location::try_from(RelayLocation::get()).expect("conversion works"));
let asset_one = Box::new(v3::Location {
Box::new(Location::try_from(RelayLocation::get()).expect("conversion works"));
let asset_one = Box::new(Location {
parents: 0,
interior: [
v3::Junction::PalletInstance(ASSETS_PALLET_ID),
v3::Junction::GeneralIndex(ASSET_ID.into()),
Junction::PalletInstance(ASSETS_PALLET_ID),
Junction::GeneralIndex(ASSET_ID.into()),
]
.into(),
});
Expand Down Expand Up @@ -112,11 +112,11 @@ fn swap_locally_on_chain_using_local_assets() {

#[test]
fn swap_locally_on_chain_using_foreign_assets() {
let asset_native = Box::new(v3::Location::try_from(RelayLocation::get()).unwrap());
let asset_native = Box::new(Location::try_from(RelayLocation::get()).unwrap());
let asset_location_on_penpal =
v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion_works");
Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion_works");
let foreign_asset_at_asset_hub_westend =
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
Location::new(1, [Junction::Parachain(PenpalA::para_id().into())])
.appended_with(asset_location_on_penpal)
.unwrap();

Expand All @@ -141,7 +141,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
// 1. Mint foreign asset (in reality this should be a teleport or some such)
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::ForeignAssets::mint(
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone().into()),
foreign_asset_at_asset_hub_westend,
foreign_asset_at_asset_hub_westend.clone(),
sov_penpal_on_ahr.clone().into(),
ASSET_HUB_WESTEND_ED * 3_000_000_000_000,
));
Expand All @@ -157,7 +157,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
asset_native.clone(),
Box::new(foreign_asset_at_asset_hub_westend),
Box::new(foreign_asset_at_asset_hub_westend.clone()),
));

assert_expected_events!(
Expand All @@ -171,7 +171,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::add_liquidity(
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
asset_native.clone(),
Box::new(foreign_asset_at_asset_hub_westend),
Box::new(foreign_asset_at_asset_hub_westend.clone()),
1_000_000_000_000_000,
2_000_000_000_000_000,
0,
Expand All @@ -189,7 +189,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
);

// 4. Swap!
let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend)];
let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend.clone())];

assert_ok!(
<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::swap_exact_tokens_for_tokens(
Expand Down Expand Up @@ -252,8 +252,8 @@ fn cannot_create_pool_from_pool_assets() {
assert_matches::assert_matches!(
<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
Box::new(v3::Location::try_from(asset_native).expect("conversion works")),
Box::new(v3::Location::try_from(asset_one).expect("conversion works")),
Box::new(Location::try_from(asset_native).expect("conversion works")),
Box::new(Location::try_from(asset_one).expect("conversion works")),
),
Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown"))
);
Expand All @@ -262,12 +262,12 @@ fn cannot_create_pool_from_pool_assets() {

#[test]
fn pay_xcm_fee_with_some_asset_swapped_for_native() {
let asset_native = v3::Location::try_from(RelayLocation::get()).expect("conversion works");
let asset_one = xcm::v3::Location {
let asset_native = Location::try_from(RelayLocation::get()).expect("conversion works");
let asset_one = Location {
parents: 0,
interior: [
xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID),
xcm::v3::Junction::GeneralIndex(ASSET_ID.into()),
Junction::PalletInstance(ASSETS_PALLET_ID),
Junction::GeneralIndex(ASSET_ID.into()),
]
.into(),
};
Expand Down Expand Up @@ -296,8 +296,8 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() {

assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
Box::new(asset_native),
Box::new(asset_one),
Box::new(asset_native.clone()),
Box::new(asset_one.clone()),
));

assert_expected_events!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
);
let (expected_foreign_asset_id, expected_foreign_asset_amount) =
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap();

AssetHubWestend::assert_xcmp_queue_success(None);

Expand All @@ -159,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
who: *who == t.receiver.account_id,
},
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => {
asset_id: *asset_id == expected_foreign_asset_id_v3,
asset_id: *asset_id == expected_foreign_asset_id,
owner: *owner == t.receiver.account_id,
amount: *amount == expected_foreign_asset_amount,
},
Expand All @@ -173,7 +172,6 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) {
AssetHubWestend::assert_xcm_pallet_attempted_complete(None);
let (expected_foreign_asset_id, expected_foreign_asset_amount) =
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap();
assert_expected_events!(
AssetHubWestend,
vec![
Expand All @@ -189,7 +187,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) {
},
// foreign asset is burned locally as part of teleportation
RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
asset_id: *asset_id == expected_foreign_asset_id_v3,
asset_id: *asset_id == expected_foreign_asset_id,
owner: *owner == t.sender.account_id,
balance: *balance == expected_foreign_asset_amount,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ mod imports {
pub use xcm::{
latest::ParentThen,
prelude::{AccountId32 as AccountId32Junction, *},
v3::{self, NetworkId::Westend as WestendId},
v4,
v4::NetworkId::Westend as WestendId,
};
pub use xcm_executor::traits::TransferType;

Expand Down
Loading

0 comments on commit be74fe9

Please sign in to comment.