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

Migrate foreign assets v3::Location to v4::Location #4129

Merged
merged 44 commits into from
Aug 14, 2024

Conversation

franciscoaguirre
Copy link
Contributor

@franciscoaguirre franciscoaguirre commented Apr 15, 2024

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 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.

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.
I'll configure MBMs (Multi-Block Migrations) then and make the actual migration.

Fixes #4128

@acatangiu
Copy link
Contributor

Can we migrate to VersionedLocation instead?

@franciscoaguirre
Copy link
Contributor Author

Can we migrate to VersionedLocation instead?

We can. The only issue with that is we might have two versions of the same asset.
Say we do migrate to VersionedLocation, then we could have both VersionedLocation::V3(usdt) and VersionedLocation::V4(usdt) for example.

We'd still need a migration to change values to the newest version. It's either that or migrating to change types to the newest version. I say fixing the version in this case doesn't sound like a bad idea. What do you think?

@acatangiu
Copy link
Contributor

I was thinking to keep assets with mixed versions in storage, but you're right that it won't work (or rather it could work but with many corner cases and ultimately more complexity).

I agree we keep it simple and migrate assets to latest version.

@franciscoaguirre franciscoaguirre added the T6-XCM This PR/Issue is related to XCM. label Jun 26, 2024
@franciscoaguirre
Copy link
Contributor Author

I was thinking to keep assets with mixed versions in storage, but you're right that it won't work (or rather it could work but with many corner cases and ultimately more complexity).

I agree we keep it simple and migrate assets to latest version.

Rethinking this, it might be better to migrate them to VersionedAssets. The only way to create foreign assets is via XCM and the sender doesn't specify the asset id. We can just use V4 all the time and change it when we migrate. This means we'll have more leeway whenever a new XCM version comes out. What do you think?

@acatangiu
Copy link
Contributor

@xlc I remember seeing another thread on this topic where you had some input, but can't find it now.
(I might also be imagining things 😆 , but tagging you here just in case)

@bkontur
Copy link
Contributor

bkontur commented Jul 15, 2024

@xlc I remember seeing another thread on this topic where you had some input, but can't find it now. (I might also be imagining things 😆 , but tagging you here just in case)

This is the original issue for this foreign asset id problem: #1130,

Rethinking this, it might be better to migrate them to VersionedAssets. The only way to create foreign assets is via XCM and the sender doesn't specify the asset id. We can just use V4 all the time and change it when we migrate. This means we'll have more leeway whenever a new XCM version comes out. What do you think?

I was proposing there something like this - to use VersionedLocation for Transact(ForeignAssets::create(asset_id as VersionedLocation, ...):

        type AssetId = xcm::v3::Location;                    // requires storage migration
	type AssetIdParameter = VersionedLocation;           // this is used for extrinsics

which would solve xcm::Transact versioning problem from other parachains,
but another part of the problem is how the dapps will read ForeignAssets with v3/v4::Location:

  • if they read directly from storage, they could have a problem when we migrate to new version
  • if they use new dedicated runtime API (with input parameter as desired XcmVersion - as we do for query_acceptable_payment_assets(xcm_version: xcm::Version)), where we can return VersionedLocation -> no problem
  • something else?

If we use VersionedLocation for AssetId:

        type AssetId = VersionedLocation

I don't know, it could lead maybe to other problems, at least we would need to use something like for pallet_xcm with LatestVersionedLocation

@franciscoaguirre
Copy link
Contributor Author

I was initially convinced by the argument that if we use VersionedLocation, we could have two versions of the same asset. However, now I'm not so sure. Since we can only create foreign assets via an XCM and the runtime assigns the id, we can always assign the latest version. When we upgrade, we bump the version and migrate all ids to VersionedLocation::V{n + 1}.

@xlc
Copy link
Contributor

xlc commented Jul 15, 2024

@xlc I remember seeing another thread on this topic where you had some input, but can't find it now. (I might also be imagining things 😆 , but tagging you here just in case)

Yeah I made a comment somewhere but also can't find it anymore...
But basically there isn't much reason to migrate from v3 to v4 as they are exactly the same thing except version number.
Yeah there is no harm to do so but also no benefit and less work is better than more work.
Also I always use a fixed XCM version for storage item and Versioned for extrinsic (this applies to Acala and ORML).
This means it is less likely to have unexpected storage item format change as a fixed version type should never change but Versioned type is a moving target. e.g. when XCM V2 is removed, runtime using V2 type will not be able to compile but runtime using Versioned type that is V2 will get bad decoding error. It also means there could be multiple representation of a same thing and that can makes consumer of the storage item harder (e.g. UI, block explorer). It could be a critical issue when such thing is used as storage key.

It is possible to have runtime migration to keep the version is always at latest but we might as well use fixed version and do the migration at our own pace. i.e. we can upgrade from v3 to v4 anytime we want before v3 is removed but with Versioned type, we have to upgrade as soon as a new version is introduced or there will be unexpected things.

In the end, there are little upside to use Versioned type but many downsides.

@franciscoaguirre franciscoaguirre changed the title Add a migration from foreign assets v3::Location to v4::Location Migrate foreign assets v3::Location to v4::Location Aug 8, 2024
@acatangiu acatangiu self-requested a review August 13, 2024 10:50
Copy link
Contributor

@serban300 serban300 left a comment

Choose a reason for hiding this comment

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

Looks good to me, modulo Adrian's comment related to pallet_collator_selection::migration::v1::MigrateToV1<Runtime>,

prdoc/pr_4129.prdoc Outdated Show resolved Hide resolved
@acatangiu
Copy link
Contributor

needs a review from @paritytech/frame-coders

.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(),
Copy link
Contributor

Choose a reason for hiding this comment

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

@franciscoaguirre just thinking, if we add xcm::v5 this won't compile again, I am not sure, but maybe:
foreign_asset_at_asset_hub.clone().try_into().unwrap() would do the trick?

@@ -1781,64 +1784,3 @@ cumulus_pallet_parachain_system::register_validate_block! {
Runtime = Runtime,
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
}

#[cfg(test)]
mod tests {
Copy link
Contributor

Choose a reason for hiding this comment

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

@franciscoaguirre I'm not aware of any specific rule here. All other runtimes have tests in this file as well as in separate tests.rs files or in a separate tests directory. If that's the case, we should also clean up the other runtimes. Since these tests only check some basic constants, I think we could keep them here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or even just a tests.rs file, instead of tests/mod.rs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Guess I ended up moving tests early in the PR for some reason. I'll put them back

@@ -1781,64 +1784,3 @@ cumulus_pallet_parachain_system::register_validate_block! {
Runtime = Runtime,
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
}

#[cfg(test)]
mod tests {
Copy link
Contributor

Choose a reason for hiding this comment

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

Or even just a tests.rs file, instead of tests/mod.rs.

@franciscoaguirre franciscoaguirre added this pull request to the merge queue Aug 14, 2024
Merged via the queue into master with commit be74fe9 Aug 14, 2024
175 of 178 checks passed
@franciscoaguirre franciscoaguirre deleted the migrate-assets-to-v4 branch August 14, 2024 09:06
ordian added a commit that referenced this pull request Aug 14, 2024
* master: (35 commits)
  Fix OurViewChange small race (#5356)
  Make ticket non-optional and add ensure_successful method to Consideration trait (#5359)
  [tests] dedup test code, add more tests, improve naming and docs (#5338)
  Stop running the wishlist workflow on forks (#5297)
  Migrate foreign assets v3::Location to v4::Location (#4129)
  Minor clean up (#5284)
  [Pools] Ensure members can always exit the pool gracefully (#4998)
  StorageWeightReclaim: set to node pov size if higher (#5281)
  [Bot] Add prdoc generation (#5331)
  Small nits found accidentally along the way (#5341)
  Create subsystem-benchmarks.yml (#5325)
  Bump libp2p-identity from 0.2.8 to 0.2.9 (#5232)
  Bump authoring duration for async backing to 2s. (#5195)
  Fix spelling issues (#5206)
  Bump the known_good_semver group across 1 directory with 3 updates (#5315)
  `polkadot-node-core-pvf-common`: Fix test compilation error (#5310)
  ci: Paused `cmd-action` commenter (#5287)
  Remove unnecessary mut (#5318)
  chain-spec: minor clarification on the genesis config patch (#5324)
  fix av-distribution Jaeger spans mem leak (#5321)
  ...
ordian added a commit that referenced this pull request Aug 14, 2024
* master: (35 commits)
  Fix OurViewChange small race (#5356)
  Make ticket non-optional and add ensure_successful method to Consideration trait (#5359)
  [tests] dedup test code, add more tests, improve naming and docs (#5338)
  Stop running the wishlist workflow on forks (#5297)
  Migrate foreign assets v3::Location to v4::Location (#4129)
  Minor clean up (#5284)
  [Pools] Ensure members can always exit the pool gracefully (#4998)
  StorageWeightReclaim: set to node pov size if higher (#5281)
  [Bot] Add prdoc generation (#5331)
  Small nits found accidentally along the way (#5341)
  Create subsystem-benchmarks.yml (#5325)
  Bump libp2p-identity from 0.2.8 to 0.2.9 (#5232)
  Bump authoring duration for async backing to 2s. (#5195)
  Fix spelling issues (#5206)
  Bump the known_good_semver group across 1 directory with 3 updates (#5315)
  `polkadot-node-core-pvf-common`: Fix test compilation error (#5310)
  ci: Paused `cmd-action` commenter (#5287)
  Remove unnecessary mut (#5318)
  chain-spec: minor clarification on the genesis config patch (#5324)
  fix av-distribution Jaeger spans mem leak (#5321)
  ...
@serban300
Copy link
Contributor

@franciscoaguirre I think this PR broke the zombienet-bridges-0001-asset-transfer-works test.

Can you take a look please ?

@franciscoaguirre
Copy link
Contributor Author

Sure, I'll take a look

@bkontur
Copy link
Contributor

bkontur commented Aug 14, 2024

Sure, I'll take a look

hmm, strange, https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6991678

2024-08-13 14:37:42             VEC: Unable to decode on index 0 createType(Lookup37):: Struct: failed on interior: {"_enum":{"Here":"Null","X1":"[Lookup40;1]","X2":"[Lookup40;2]","X3":"[Lookup40;3]","X4":"[Lookup40;4]","X5":"[Lookup40;5]","X6":"[Lookup40;6]","X7":"[Lookup40;7]","X8":"[Lookup40;8]"}}:: Enum(X1):: decodeU8aVec: failed at 0x5b6f626a656374204f626a6563745d… (index 1/1): {"_enum":{"Parachain":"Compact<u32>","AccountId32":"{\"network\":\"Option<StagingXcmV4JunctionNetworkId>\",\"id\":\"[u8;32]\"}","AccountIndex64":"{\"network\":\"Option<StagingXcmV4JunctionNetworkId>\",\"index\":\"Compact<u64>\"}","AccountKey20":"{\"network\":\"Option<StagingXcmV4JunctionNetworkId>\",\"key\":\"[u8;20]\"}","PalletInstance":"u8","GeneralIndex":"Compact<u128>","GeneralKey":"{\"length\":\"u8\",\"data\":\"[u8;32]\"}","OnlyChild":"Null","Plurality":"{\"id\":\"XcmV3JunctionBodyId\",\"part\":\"XcmV3JunctionBodyPart\"}","GlobalConsensus":"StagingXcmV4JunctionNetworkId"}}:: Unable to create Enum via index 91, in Parachain, AccountId32, AccountIndex64, AccountKey20, PalletInstance, GeneralIndex, GeneralKey, OnlyChild, Plurality, GlobalConsensus
2024-08-13 14:37:42        RPC-CORE: queryStorageAt(keys: Vec<StorageKey>, at?: BlockHash): Vec<StorageChangeSet>:: createType(Vec<StorageKey>):: createType(Lookup37):: Struct: failed on interior: {"_enum":{"Here":"Null","X1":"[Lookup40;1]","X2":"[Lookup40;2]","X3":"[Lookup40;3]","X4":"[Lookup40;4]","X5":"[Lookup40;5]","X6":"[Lookup40;6]","X7":"[Lookup40;7]","X8":"[Lookup40;8]"}}:: Enum(X1):: decodeU8aVec: failed at 0x5b6f626a656374204f626a6563745d… (index 1/1): {"_enum":{"Parachain":"Compact<u32>","AccountId32":"{\"network\":\"Option<StagingXcmV4JunctionNetworkId>\",\"id\":\"[u8;32]\"}","AccountIndex64":"{\"network\":\"Option<StagingXcmV4JunctionNetworkId>\",\"index\":\"Compact<u64>\"}","AccountKey20":"{\"network\":\"Option<StagingXcmV4JunctionNetworkId>\",\"key\":\"[u8;20]\"}","PalletInstance":"u8","GeneralIndex":"Compact<u128>","GeneralKey":"{\"length\":\"u8\",\"data\":\"[u8;32]\"}","OnlyChild":"Null","Plurality":"{\"id\":\"XcmV3JunctionBodyId\",\"part\":\"XcmV3JunctionBodyPart\"}","GlobalConsensus":"StagingXcmV4JunctionNetworkId"}}:: Unable to create Enum via index 91, in Parachain, AccountId32, AccountIndex64, AccountKey20, PalletInstance, GeneralIndex, GeneralKey, OnlyChild, Plurality, GlobalConsensus
 Error running script: /home/nonroot/bridges-polkadot-sdk/bridges/testing/framework/js-helpers/wrapped-assets-balance.js

probably this lines: https://github.com/paritytech/polkadot-sdk/blob/master/bridges/testing/framework/js-helpers/wrapped-assets-balance.js#L10-L11:

const foreignAssetAccount = await api.query.foreignAssets.account(
            { parents: 2, interior: { X1: { GlobalConsensus: bridgedNetworkName } } },

are not compatible with xcm::v4?

ordian added a commit that referenced this pull request Aug 15, 2024
* master: (167 commits)
  Upgrade accidentally downgraded deps (#5365)
  [Pools] Fix issues with member migration to `DelegateStake` (#4822)
  Unify `no_genesis` check (#5360)
  [CI] Fix prdoc command (#5358)
  Beefy: add benchmarks for `report_fork_voting()` (#5188)
  Fix OurViewChange small race (#5356)
  Make ticket non-optional and add ensure_successful method to Consideration trait (#5359)
  [tests] dedup test code, add more tests, improve naming and docs (#5338)
  Stop running the wishlist workflow on forks (#5297)
  Migrate foreign assets v3::Location to v4::Location (#4129)
  Minor clean up (#5284)
  [Pools] Ensure members can always exit the pool gracefully (#4998)
  StorageWeightReclaim: set to node pov size if higher (#5281)
  [Bot] Add prdoc generation (#5331)
  Small nits found accidentally along the way (#5341)
  Create subsystem-benchmarks.yml (#5325)
  Bump libp2p-identity from 0.2.8 to 0.2.9 (#5232)
  Bump authoring duration for async backing to 2s. (#5195)
  Fix spelling issues (#5206)
  Bump the known_good_semver group across 1 directory with 3 updates (#5315)
  ...
@franciscoaguirre
Copy link
Contributor Author

franciscoaguirre commented Aug 15, 2024

Ahh indeed, that must be the issue. In v4, interior is now an array, so it should be:

const foreignAssetAccount = await api.query.foreignAssets.account(
            { parents: 2, interior: { X1: [{ GlobalConsensus: bridgedNetworkName }] } },

I'll try it and see if that solves it

github-merge-queue bot pushed a commit that referenced this pull request Aug 16, 2024
After #4129, a zombienet
bridge test was broken.
This is because XCMv4 locations have an array in the `interior` field,
which also has to appear in PJS.

---------

Co-authored-by: Serban Iorga <serban@parity.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T6-XCM This PR/Issue is related to XCM.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migration from v3::Location to v4::Location for ForeignAssets
9 participants