# Note for reviewer

Most changes are just syntax changes necessary for the new version.
Most important files should be the ones under the `xcm` folder.

# Description 

Added XCMv4.

## Removed `Multi` prefix
The following types have been renamed:
- MultiLocation -> Location
- MultiAsset -> Asset
- MultiAssets -> Assets
- InteriorMultiLocation -> InteriorLocation
- MultiAssetFilter -> AssetFilter
- VersionedMultiAsset -> VersionedAsset
- WildMultiAsset -> WildAsset
- VersionedMultiLocation -> VersionedLocation

In order to fix a name conflict, the `Assets` in `xcm-executor` were
renamed to `HoldingAssets`, as they represent assets in holding.

## Removed `Abstract` asset id

It was not being used anywhere and this simplifies the code.

Now assets are just constructed as follows:

```rust
let asset: Asset = (AssetId(Location::new(1, Here)), 100u128).into();
```

No need for specifying `Concrete` anymore.

## Outcome is now a named fields struct

Instead of

```rust
pub enum Outcome {
  Complete(Weight),
  Incomplete(Weight, Error),
  Error(Error),
}
```

we now have

```rust
pub enum Outcome {
  Complete { used: Weight },
  Incomplete { used: Weight, error: Error },
  Error { error: Error },
}
```

## Added Reanchorable trait

Now both locations and assets implement this trait, making it easier to
reanchor both.

## New syntax for building locations and junctions

Now junctions are built using the following methods:

```rust
let location = Location {
    parents: 1,
    interior: [Parachain(1000), PalletInstance(50), GeneralIndex(1984)].into()
};
```

or

```rust
let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]);
```

And they are matched like so:

```rust
match location.unpack() {
  (1, [Parachain(id)]) => ...
  (0, Here) => ...,
  (1, [_]) => ...,
}
```

This syntax is mandatory in v4, and has been also implemented for v2 and
v3 for easier migration.

This was needed to make all sizes smaller.

# TODO
- [x] Scaffold v4
- [x] Port github.com/paritytech/polkadot/pull/7236
- [x] Remove `Multi` prefix
- [x] Remove `Abstract` asset id

---------

Co-authored-by: command-bot <>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
This commit is contained in:
Francisco Aguirre
2024-01-16 19:18:04 +01:00
committed by GitHub
parent ec7bfae00a
commit 8428f678fe
255 changed files with 12425 additions and 6726 deletions
+21 -21
View File
@@ -41,18 +41,18 @@ pub trait Config: frame_system::Config {
/// `TransactAsset` is implemented.
type XcmConfig: XcmConfig;
/// A converter between a multi-location to a sovereign account.
/// A converter between a location to a sovereign account.
type AccountIdConverter: ConvertLocation<Self::AccountId>;
/// Helper that ensures successful delivery for XCM instructions which need `SendXcm`.
type DeliveryHelper: EnsureDelivery;
/// Does any necessary setup to create a valid destination for XCM messages.
/// Returns that destination's multi-location to be used in benchmarks.
fn valid_destination() -> Result<MultiLocation, BenchmarkError>;
/// Returns that destination's location to be used in benchmarks.
fn valid_destination() -> Result<Location, BenchmarkError>;
/// Worst case scenario for a holding account in this runtime.
fn worst_case_holding(depositable_count: u32) -> MultiAssets;
fn worst_case_holding(depositable_count: u32) -> Assets;
}
const SEED: u32 = 0;
@@ -66,21 +66,21 @@ pub type AssetTransactorOf<T> = <<T as Config>::XcmConfig as XcmConfig>::AssetTr
/// The call type of executor's config. Should eventually resolve to the same overarching call type.
pub type XcmCallOf<T> = <<T as Config>::XcmConfig as XcmConfig>::RuntimeCall;
pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> MultiAssets {
pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> Assets {
let fungibles_amount: u128 = 100;
let holding_fungibles = max_assets / 2 - depositable_count;
let holding_non_fungibles = holding_fungibles;
(0..holding_fungibles)
.map(|i| {
MultiAsset {
id: Concrete(GeneralIndex(i as u128).into()),
Asset {
id: AssetId(GeneralIndex(i as u128).into()),
fun: Fungible(fungibles_amount * i as u128),
}
.into()
})
.chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) }))
.chain((0..holding_non_fungibles).map(|i| MultiAsset {
id: Concrete(GeneralIndex(i as u128).into()),
.chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) }))
.chain((0..holding_non_fungibles).map(|i| Asset {
id: AssetId(GeneralIndex(i as u128).into()),
fun: NonFungible(asset_instance_from(i)),
}))
.collect::<Vec<_>>()
@@ -94,11 +94,11 @@ pub fn asset_instance_from(x: u32) -> AssetInstance {
AssetInstance::Array4(instance)
}
pub fn new_executor<T: Config>(origin: MultiLocation) -> ExecutorOf<T> {
pub fn new_executor<T: Config>(origin: Location) -> ExecutorOf<T> {
ExecutorOf::<T>::new(origin, [0; 32])
}
/// Build a multi-location from an account id.
/// Build a location from an account id.
fn account_id_junction<T: frame_system::Config>(index: u32) -> Junction {
let account: T::AccountId = account("account", index, SEED);
let mut encoded = account.encode();
@@ -108,8 +108,8 @@ fn account_id_junction<T: frame_system::Config>(index: u32) -> Junction {
Junction::AccountId32 { network: None, id }
}
pub fn account_and_location<T: Config>(index: u32) -> (T::AccountId, MultiLocation) {
let location: MultiLocation = account_id_junction::<T>(index).into();
pub fn account_and_location<T: Config>(index: u32) -> (T::AccountId, Location) {
let location: Location = account_id_junction::<T>(index).into();
let account = T::AccountIdConverter::convert_location(&location).unwrap();
(account, location)
@@ -121,21 +121,21 @@ pub trait EnsureDelivery {
/// Prepare all requirements for successful `XcmSender: SendXcm` passing (accounts, balances,
/// channels ...). Returns:
/// - possible `FeesMode` which is expected to be set to executor
/// - possible `MultiAssets` which are expected to be subsume to the Holding Register
/// - possible `Assets` which are expected to be subsume to the Holding Register
fn ensure_successful_delivery(
origin_ref: &MultiLocation,
dest: &MultiLocation,
origin_ref: &Location,
dest: &Location,
fee_reason: FeeReason,
) -> (Option<FeesMode>, Option<MultiAssets>);
) -> (Option<FeesMode>, Option<Assets>);
}
/// `()` implementation does nothing which means no special requirements for environment.
impl EnsureDelivery for () {
fn ensure_successful_delivery(
_origin_ref: &MultiLocation,
_dest: &MultiLocation,
_origin_ref: &Location,
_dest: &Location,
_fee_reason: FeeReason,
) -> (Option<FeesMode>, Option<MultiAssets>) {
) -> (Option<FeesMode>, Option<Assets>) {
// doing nothing
(None, None)
}