# 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
+41 -28
View File
@@ -21,7 +21,7 @@ use frame_support::traits::{Currency, Imbalance, OnUnbalanced};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use primitives::Balance;
use sp_runtime::{traits::TryConvert, Perquintill, RuntimeDebug};
use xcm::VersionedMultiLocation;
use xcm::VersionedLocation;
/// Logic for the author to get a portion of fees.
pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>);
@@ -107,12 +107,9 @@ pub fn era_payout(
)]
pub enum VersionedLocatableAsset {
#[codec(index = 3)]
V3 {
/// The (relative) location in which the asset ID is meaningful.
location: xcm::v3::MultiLocation,
/// The asset's ID.
asset_id: xcm::v3::AssetId,
},
V3 { location: xcm::v3::MultiLocation, asset_id: xcm::v3::AssetId },
#[codec(index = 4)]
V4 { location: xcm::v4::Location, asset_id: xcm::v4::AssetId },
}
/// Converts the [`VersionedLocatableAsset`] to the [`xcm_builder::LocatableAssetId`].
@@ -125,22 +122,29 @@ impl TryConvert<VersionedLocatableAsset, xcm_builder::LocatableAssetId>
) -> Result<xcm_builder::LocatableAssetId, VersionedLocatableAsset> {
match asset {
VersionedLocatableAsset::V3 { location, asset_id } =>
Ok(xcm_builder::LocatableAssetId { asset_id, location }),
Ok(xcm_builder::LocatableAssetId {
location: location.try_into().map_err(|_| asset.clone())?,
asset_id: asset_id.try_into().map_err(|_| asset.clone())?,
}),
VersionedLocatableAsset::V4 { location, asset_id } =>
Ok(xcm_builder::LocatableAssetId { location, asset_id }),
}
}
}
/// Converts the [`VersionedMultiLocation`] to the [`xcm::latest::MultiLocation`].
pub struct VersionedMultiLocationConverter;
impl TryConvert<&VersionedMultiLocation, xcm::latest::MultiLocation>
for VersionedMultiLocationConverter
{
/// Converts the [`VersionedLocation`] to the [`xcm::latest::Location`].
pub struct VersionedLocationConverter;
impl TryConvert<&VersionedLocation, xcm::latest::Location> for VersionedLocationConverter {
fn try_convert(
location: &VersionedMultiLocation,
) -> Result<xcm::latest::MultiLocation, &VersionedMultiLocation> {
location: &VersionedLocation,
) -> Result<xcm::latest::Location, &VersionedLocation> {
let latest = match location.clone() {
VersionedMultiLocation::V2(l) => l.try_into().map_err(|_| location)?,
VersionedMultiLocation::V3(l) => l,
VersionedLocation::V2(l) => {
let v3: xcm::v3::MultiLocation = l.try_into().map_err(|_| location)?;
v3.try_into().map_err(|_| location)?
},
VersionedLocation::V3(l) => l.try_into().map_err(|_| location)?,
VersionedLocation::V4(l) => l,
};
Ok(latest)
}
@@ -161,11 +165,14 @@ pub mod benchmarks {
pub struct AssetRateArguments;
impl AssetKindFactory<VersionedLocatableAsset> for AssetRateArguments {
fn create_asset_kind(seed: u32) -> VersionedLocatableAsset {
VersionedLocatableAsset::V3 {
location: xcm::v3::MultiLocation::new(0, X1(Parachain(seed))),
asset_id: xcm::v3::MultiLocation::new(
VersionedLocatableAsset::V4 {
location: xcm::v4::Location::new(0, [xcm::v4::Junction::Parachain(seed)]),
asset_id: xcm::v4::Location::new(
0,
X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())),
[
xcm::v4::Junction::PalletInstance(seed.try_into().unwrap()),
xcm::v4::Junction::GeneralIndex(seed.into()),
],
)
.into(),
}
@@ -173,29 +180,35 @@ pub mod benchmarks {
}
/// Provide factory methods for the [`VersionedLocatableAsset`] and the `Beneficiary` of the
/// [`VersionedMultiLocation`]. The location of the asset is determined as a Parachain with an
/// [`VersionedLocation`]. The location of the asset is determined as a Parachain with an
/// ID equal to the passed seed.
pub struct TreasuryArguments<Parents = ConstU8<0>, ParaId = ConstU32<0>>(
PhantomData<(Parents, ParaId)>,
);
impl<Parents: Get<u8>, ParaId: Get<u32>>
TreasuryArgumentsFactory<VersionedLocatableAsset, VersionedMultiLocation>
TreasuryArgumentsFactory<VersionedLocatableAsset, VersionedLocation>
for TreasuryArguments<Parents, ParaId>
{
fn create_asset_kind(seed: u32) -> VersionedLocatableAsset {
VersionedLocatableAsset::V3 {
location: xcm::v3::MultiLocation::new(Parents::get(), X1(Parachain(ParaId::get()))),
location: xcm::v3::MultiLocation::new(
Parents::get(),
[xcm::v3::Junction::Parachain(ParaId::get())],
),
asset_id: xcm::v3::MultiLocation::new(
0,
X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())),
[
xcm::v3::Junction::PalletInstance(seed.try_into().unwrap()),
xcm::v3::Junction::GeneralIndex(seed.into()),
],
)
.into(),
}
}
fn create_beneficiary(seed: [u8; 32]) -> VersionedMultiLocation {
VersionedMultiLocation::V3(xcm::v3::MultiLocation::new(
fn create_beneficiary(seed: [u8; 32]) -> VersionedLocation {
VersionedLocation::V4(xcm::v4::Location::new(
0,
X1(AccountId32 { network: None, id: seed }),
[xcm::v4::Junction::AccountId32 { network: None, id: seed }],
))
}
}
+15 -15
View File
@@ -35,13 +35,13 @@ pub trait PriceForMessageDelivery {
/// Type used for charging different prices to different destinations
type Id;
/// Return the assets required to deliver `message` to the given `para` destination.
fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> MultiAssets;
fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> Assets;
}
impl PriceForMessageDelivery for () {
type Id = ();
fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets {
MultiAssets::new()
fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets {
Assets::new()
}
}
@@ -49,17 +49,17 @@ pub struct NoPriceForMessageDelivery<Id>(PhantomData<Id>);
impl<Id> PriceForMessageDelivery for NoPriceForMessageDelivery<Id> {
type Id = Id;
fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets {
MultiAssets::new()
fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets {
Assets::new()
}
}
/// Implementation of [`PriceForMessageDelivery`] which returns a fixed price.
pub struct ConstantPrice<T>(sp_std::marker::PhantomData<T>);
impl<T: Get<MultiAssets>> PriceForMessageDelivery for ConstantPrice<T> {
impl<T: Get<Assets>> PriceForMessageDelivery for ConstantPrice<T> {
type Id = ();
fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets {
fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets {
T::get()
}
}
@@ -84,7 +84,7 @@ impl<A: Get<AssetId>, B: Get<u128>, M: Get<u128>, F: FeeTracker> PriceForMessage
{
type Id = F::Id;
fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> MultiAssets {
fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> Assets {
let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get());
let fee_sum = B::get().saturating_add(msg_fee);
let amount = F::get_fee_factor(id).saturating_mul_int(fee_sum);
@@ -103,11 +103,11 @@ where
type Ticket = (HostConfiguration<BlockNumberFor<T>>, ParaId, Vec<u8>);
fn validate(
dest: &mut Option<MultiLocation>,
dest: &mut Option<Location>,
msg: &mut Option<Xcm<()>>,
) -> SendResult<(HostConfiguration<BlockNumberFor<T>>, ParaId, Vec<u8>)> {
let d = dest.take().ok_or(MissingArgument)?;
let id = if let MultiLocation { parents: 0, interior: X1(Parachain(id)) } = &d {
let id = if let (0, [Parachain(id)]) = d.unpack() {
*id
} else {
*dest = Some(d);
@@ -160,7 +160,7 @@ pub struct ToParachainDeliveryHelper<
#[cfg(feature = "runtime-benchmarks")]
impl<
XcmConfig: xcm_executor::Config,
ExistentialDeposit: Get<Option<MultiAsset>>,
ExistentialDeposit: Get<Option<Asset>>,
PriceForDelivery: PriceForMessageDelivery<Id = ParaId>,
Parachain: Get<ParaId>,
ToParachainHelper: EnsureForParachain,
@@ -174,10 +174,10 @@ impl<
>
{
fn ensure_successful_delivery(
origin_ref: &MultiLocation,
_dest: &MultiLocation,
origin_ref: &Location,
_dest: &Location,
fee_reason: xcm_executor::traits::FeeReason,
) -> (Option<xcm_executor::FeesMode>, Option<MultiAssets>) {
) -> (Option<xcm_executor::FeesMode>, Option<Assets>) {
use xcm_executor::{
traits::{FeeManager, TransactAsset},
FeesMode,
@@ -234,7 +234,7 @@ mod tests {
parameter_types! {
pub const BaseDeliveryFee: u128 = 300_000_000;
pub const TransactionByteFee: u128 = 1_000_000;
pub FeeAssetId: AssetId = Concrete(Here.into());
pub FeeAssetId: AssetId = AssetId(Here.into());
}
struct TestFeeTracker;