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

[asset-hubs] Investigate usage of MultiLocation vs VersionedMultiLocation #1130

Open
3 tasks
bkontur opened this issue Jul 19, 2023 · 9 comments
Open
3 tasks
Labels
T6-XCM This PR/Issue is related to XCM.

Comments

@bkontur
Copy link
Contributor

bkontur commented Jul 19, 2023

Summary

Investigate and setup proper usage of MultiLocation for storage items.

Problem 1 - ForeignAssets - asset_id as xcm::prelude::MultiLocation

MultiLocation is used as pallet_assets::AssetId.

// AssetId type definition
pub type MultiLocationForAssetId = xcm::prelude::MultiLocation;
// ForeignAssets pallet instance
pub type ForeignAssetsInstance = pallet_assets::Instance2;
impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
  ...
	type AssetId = MultiLocationForAssetId;
  ...
}
//  `pallet_assets::AssetId` used by storage item
pub(super) type Asset<T: Config<I>, I: 'static = ()> = StorageMap<
		_,
		Blake2_128Concat,
		T::AssetId,
		...
	>;

Problem 2 - asset-conversion uses Box<xcm::opaque::v3::MultiLocation> for storage item

See asset conversion pallet MultiAssetId definition:

impl pallet_asset_conversion::Config for Runtime {
...
	type MultiAssetId = Box<xcm::opaque::v3::MultiLocation>;
...
}
// MultiAssetId is used for PoolId
pub(super) type PoolIdOf<T> = (<T as Config>::MultiAssetId, <T as Config>::MultiAssetId);
// PoolId is used by storage item 
pub type Pools<T: Config> =
		StorageMap<_, Blake2_128Concat, PoolIdOf<T>, PoolInfo<T::PoolAssetId>, OptionQuery>;

Problem 3 - asset-conversion uses Box<xcm::opaque::v3::MultiLocation> for public runtime api

See more description here.

Questions:

How should we handle MultiLocation vs VersionedMultiLocation in proper way?

TODO

  • should we change xcm::prelude::MultiLocation to xcm::VersionedMultiLocation ?
    • prepare some migration for that?
  • add some test that ensures compatibility of actually used xcm::v3::MultiLocation against xcm::prelude::MultiLocation ?
@joepetrowski
Copy link
Contributor

We have to be careful here, because if/when XCMv4 comes out, it will be a huge pain if all the asset IDs change. Hopefully the MultiLocation data structure does not change with future versions as it would cause the meaning of the Asset ID to change as well.

add some test that ensures compatibility of actually used xcm::v3::MultiLocation against xcm::prelude::MultiLocation

This seems sensible in any case.

@EmmanuellNorbertTulbure EmmanuellNorbertTulbure transferred this issue from paritytech/cumulus Aug 25, 2023
@the-right-joyce the-right-joyce transferred this issue from paritytech/polkadot-sdk Aug 25, 2023
@the-right-joyce the-right-joyce transferred this issue from paritytech/parity-bridges-common Aug 25, 2023
@bkontur bkontur mentioned this issue Sep 27, 2023
4 tasks
@franciscoaguirre
Copy link
Contributor

I also wrote in #1230 (comment) but we should definitely use Versioned* types for storage items

@bkontur
Copy link
Contributor Author

bkontur commented Sep 27, 2023

@franciscoaguirre
ok, thank you, I will continue this direction with PoC for VersionedLocation,

We just need to think that this two locations below are not the same - they point to the same but have different encodings because of V3/V4:

let location1 = VersionedMultiLocation::V3(v3::MultiLocation::new(1, v3::Junctions::Here));
let location2 = VersionedMultiLocation::V4(v4::MultiLocation::new(1, v4::Junctions::Here));

So maybe we will need something like LatestVersionedMultiLocation in pallet_xcm.

And the other thing is that xcm stuff like FungiblesTransferAdapter works with use xcm::latest::prelude::*; and if we use Versioned(Multi)Location for pallet_assets::Config::AssetId = VersionedMultiLocation it could start to be interesting.
Maybe we will use LatestVersionedMultiLocation-like feature instead of VersionedMultiLocation. Will see :)

@franciscoaguirre
Copy link
Contributor

franciscoaguirre commented Sep 27, 2023

If we use VersionedLocation across the board, we can always convert it into the latest version before dealing with it. The main issue is/was encoding and decoding.
v3 should almost always be able to convert to v4, and we always expect users to upgrade to the latest version.

@muharem
Copy link
Contributor

muharem commented Nov 3, 2023

I think there are different cases, for example for treasury AssetKind which stored together with spend proposal in the storage, I used VersionedMultiLocation, because a spend proposal will eventually expire and removed from the storage, so we can avoid storage migrations when new xcm version comes. And we wont have to support some old xcm versions.

In case with assets pallet, I see it different way. Some assets will be there for a while, and if we use versioned type, that asset can be identified only be specific version and that xcm version has to be supported "forever".
I think for this case it is more reasonable to have some generic storage migration, letting as to do that migration every time we migrate to new xcm version.

In addition we can have some label for the new version which can tell the clients if encodings are changed with new version. And tests proofing it.

@bkontur
Copy link
Contributor Author

bkontur commented Nov 23, 2023

In case with assets pallet, I see it different way. Some assets will be there for a while, and if we use versioned type, that asset can be identified only be specific version and that xcm version has to be supported "forever". I think for this case it is more reasonable to have some generic storage migration, letting as to do that migration every time we migrate to new xcm version.

yeah, this seems simple way to go, but maybe not used xcm::latest::MultiLocation but instead use exact version xcm::v3::MultiLocation and add compatiblity test to the AssetHub runtimes which check at least several predefined expected MultiLocations encoding for actual used xcm::v3 vs xcm::latest, if test fails, we need to apply migration.

But I am not sure about consequences and how this could affect e.g. external wallets, if versions wont be compatible.
If we use VersionedMultiLocation, we also need to add migration to the Latest because older versions are removed.

@bkontur
Copy link
Contributor Author

bkontur commented Feb 29, 2024

Just some hints for the future (when XCMv5 will come):

What about changing pallet_assets:

- type AssetIdParameter: Parameter + From<Self::AssetId> + Into<Self::AssetId>
+ type AssetIdParameter: Parameter + TryFrom<Self::AssetId> + TryInto<Self::AssetId>

This could escalate to enable setting up the runtime like this:

impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
   ...
	type AssetId = xcm::v3::Location;
	type AssetIdParameter = VersionedLocation;
   ...

AssetIdParameter is utilized for extrinsic parameters. Therefore, if it were VersionedLocation, external users such as wallets wouldn't need to make any changes when we release a new XCM version. This resolves only half of the problem.

The second problem concerns data retrieval. I'm unsure about how wallets are currently accessing or reading data, such as ForeignAssets. If they directly read from storage, they might encounter issues when we release a new XCM version with a different xcm::v*::Location encoding.

However, for data retrieval, we have the runtime API, which already utilizes VersionedAssets. This runtime_api is aware of new XCM versions, so there shouldn't be any issues:

impl assets_common::runtime_api::FungiblesApi<Block, AccountId,> for Runtime {
    fn query_account_balances(account: AccountId) -> Result<xcm::VersionedAssets, assets_common::runtime_api::FungiblesAccessError> {

@xlc
Copy link
Contributor

xlc commented Feb 29, 2024

dapps are usually subscribing to storage directly because it allows subscription, which is not yet possible for runtime API calls

@acatangiu acatangiu added the T6-XCM This PR/Issue is related to XCM. label Mar 1, 2024
@bkontur
Copy link
Contributor Author

bkontur commented Mar 6, 2024

dapps are usually subscribing to storage directly because it allows subscription, which is not yet possible for runtime API calls

@xlc something like this #3594?

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

No branches or pull requests

6 participants