mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-20 22:05:42 +00:00
XCMv4 (#1230)
# 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:
committed by
GitHub
parent
ec7bfae00a
commit
8428f678fe
@@ -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 }],
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user