mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 18:01:03 +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
@@ -24,8 +24,8 @@ use pallet_asset_tx_payment::HandleCredit;
|
||||
use sp_runtime::traits::Zero;
|
||||
use sp_std::{marker::PhantomData, prelude::*};
|
||||
use xcm::latest::{
|
||||
AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, MultiAsset,
|
||||
MultiLocation, Parent, WeightLimit,
|
||||
Asset, AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, Location,
|
||||
Parent, WeightLimit,
|
||||
};
|
||||
use xcm_executor::traits::ConvertLocation;
|
||||
|
||||
@@ -113,11 +113,11 @@ where
|
||||
|
||||
/// Asset filter that allows all assets from a certain location.
|
||||
pub struct AssetsFrom<T>(PhantomData<T>);
|
||||
impl<T: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation> for AssetsFrom<T> {
|
||||
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||
impl<T: Get<Location>> ContainsPair<Asset, Location> for AssetsFrom<T> {
|
||||
fn contains(asset: &Asset, origin: &Location) -> bool {
|
||||
let loc = T::get();
|
||||
&loc == origin &&
|
||||
matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) }
|
||||
matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) }
|
||||
if asset_loc.match_and_split(&loc).is_some())
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,7 @@ where
|
||||
Err(amount) => amount,
|
||||
};
|
||||
let imbalance = amount.peek();
|
||||
let root_location: MultiLocation = Here.into();
|
||||
let root_location: Location = Here.into();
|
||||
let root_account: AccountIdOf<T> =
|
||||
match AccountIdConverter::convert_location(&root_location) {
|
||||
Some(a) => a,
|
||||
@@ -329,13 +329,13 @@ mod tests {
|
||||
#[test]
|
||||
fn assets_from_filters_correctly() {
|
||||
parameter_types! {
|
||||
pub SomeSiblingParachain: MultiLocation = MultiLocation::new(1, X1(Parachain(1234)));
|
||||
pub SomeSiblingParachain: Location = (Parent, Parachain(1234)).into();
|
||||
}
|
||||
|
||||
let asset_location = SomeSiblingParachain::get()
|
||||
.pushed_with_interior(GeneralIndex(42))
|
||||
.expect("multilocation will only have 2 junctions; qed");
|
||||
let asset = MultiAsset { id: Concrete(asset_location), fun: 1_000_000u128.into() };
|
||||
.expect("location will only have 2 junctions; qed");
|
||||
let asset = Asset { id: AssetId(asset_location), fun: 1_000_000u128.into() };
|
||||
assert!(
|
||||
AssetsFrom::<SomeSiblingParachain>::contains(&asset, &SomeSiblingParachain::get()),
|
||||
"AssetsFrom should allow assets from any of its interior locations"
|
||||
|
||||
@@ -66,37 +66,36 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Accepts an asset if it is a native asset from a particular `MultiLocation`.
|
||||
pub struct ConcreteNativeAssetFrom<Location>(PhantomData<Location>);
|
||||
impl<Location: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation>
|
||||
for ConcreteNativeAssetFrom<Location>
|
||||
/// Accepts an asset if it is a native asset from a particular `Location`.
|
||||
pub struct ConcreteNativeAssetFrom<LocationValue>(PhantomData<LocationValue>);
|
||||
impl<LocationValue: Get<Location>> ContainsPair<Asset, Location>
|
||||
for ConcreteNativeAssetFrom<LocationValue>
|
||||
{
|
||||
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||
fn contains(asset: &Asset, origin: &Location) -> bool {
|
||||
log::trace!(target: "xcm::filter_asset_location",
|
||||
"ConcreteNativeAsset asset: {:?}, origin: {:?}, location: {:?}",
|
||||
asset, origin, Location::get());
|
||||
matches!(asset.id, Concrete(ref id) if id == origin && origin == &Location::get())
|
||||
asset, origin, LocationValue::get());
|
||||
asset.id.0 == *origin && origin == &LocationValue::get()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RelayOrOtherSystemParachains<
|
||||
SystemParachainMatcher: Contains<MultiLocation>,
|
||||
SystemParachainMatcher: Contains<Location>,
|
||||
Runtime: parachain_info::Config,
|
||||
> {
|
||||
_runtime: PhantomData<(SystemParachainMatcher, Runtime)>,
|
||||
}
|
||||
impl<SystemParachainMatcher: Contains<MultiLocation>, Runtime: parachain_info::Config>
|
||||
Contains<MultiLocation> for RelayOrOtherSystemParachains<SystemParachainMatcher, Runtime>
|
||||
impl<SystemParachainMatcher: Contains<Location>, Runtime: parachain_info::Config> Contains<Location>
|
||||
for RelayOrOtherSystemParachains<SystemParachainMatcher, Runtime>
|
||||
{
|
||||
fn contains(l: &MultiLocation) -> bool {
|
||||
fn contains(l: &Location) -> bool {
|
||||
let self_para_id: u32 = parachain_info::Pallet::<Runtime>::get().into();
|
||||
if let MultiLocation { parents: 0, interior: X1(Parachain(para_id)) } = l {
|
||||
if let (0, [Parachain(para_id)]) = l.unpack() {
|
||||
if *para_id == self_para_id {
|
||||
return false
|
||||
}
|
||||
}
|
||||
matches!(l, MultiLocation { parents: 1, interior: Here }) ||
|
||||
SystemParachainMatcher::contains(l)
|
||||
matches!(l.unpack(), (1, [])) || SystemParachainMatcher::contains(l)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,14 +104,12 @@ impl<SystemParachainMatcher: Contains<MultiLocation>, Runtime: parachain_info::C
|
||||
/// This structure can only be used at a parachain level. In the Relay Chain, please use
|
||||
/// the `xcm_builder::IsChildSystemParachain` matcher.
|
||||
pub struct AllSiblingSystemParachains;
|
||||
|
||||
impl Contains<MultiLocation> for AllSiblingSystemParachains {
|
||||
fn contains(l: &MultiLocation) -> bool {
|
||||
impl Contains<Location> for AllSiblingSystemParachains {
|
||||
fn contains(l: &Location) -> bool {
|
||||
log::trace!(target: "xcm::contains", "AllSiblingSystemParachains location: {:?}", l);
|
||||
match *l {
|
||||
match l.unpack() {
|
||||
// System parachain
|
||||
MultiLocation { parents: 1, interior: X1(Parachain(id)) } =>
|
||||
ParaId::from(id).is_system(),
|
||||
(1, [Parachain(id)]) => ParaId::from(*id).is_system(),
|
||||
// Everything else
|
||||
_ => false,
|
||||
}
|
||||
@@ -121,21 +118,20 @@ impl Contains<MultiLocation> for AllSiblingSystemParachains {
|
||||
|
||||
/// Accepts an asset if it is a concrete asset from the system (Relay Chain or system parachain).
|
||||
pub struct ConcreteAssetFromSystem<AssetLocation>(PhantomData<AssetLocation>);
|
||||
impl<AssetLocation: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation>
|
||||
impl<AssetLocation: Get<Location>> ContainsPair<Asset, Location>
|
||||
for ConcreteAssetFromSystem<AssetLocation>
|
||||
{
|
||||
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||
fn contains(asset: &Asset, origin: &Location) -> bool {
|
||||
log::trace!(target: "xcm::contains", "ConcreteAssetFromSystem asset: {:?}, origin: {:?}", asset, origin);
|
||||
let is_system = match origin {
|
||||
let is_system = match origin.unpack() {
|
||||
// The Relay Chain
|
||||
MultiLocation { parents: 1, interior: Here } => true,
|
||||
(1, []) => true,
|
||||
// System parachain
|
||||
MultiLocation { parents: 1, interior: X1(Parachain(id)) } =>
|
||||
ParaId::from(*id).is_system(),
|
||||
(1, [Parachain(id)]) => ParaId::from(*id).is_system(),
|
||||
// Others
|
||||
_ => false,
|
||||
};
|
||||
matches!(asset.id, Concrete(id) if id == AssetLocation::get()) && is_system
|
||||
asset.id.0 == AssetLocation::get() && is_system
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +140,9 @@ impl<AssetLocation: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation>
|
||||
/// This type should only be used within the context of a parachain, since it does not verify that
|
||||
/// the parent is indeed a Relay Chain.
|
||||
pub struct ParentRelayOrSiblingParachains;
|
||||
impl Contains<MultiLocation> for ParentRelayOrSiblingParachains {
|
||||
fn contains(location: &MultiLocation) -> bool {
|
||||
matches!(
|
||||
location,
|
||||
MultiLocation { parents: 1, interior: Here } |
|
||||
MultiLocation { parents: 1, interior: X1(Parachain(_)) }
|
||||
)
|
||||
impl Contains<Location> for ParentRelayOrSiblingParachains {
|
||||
fn contains(location: &Location) -> bool {
|
||||
matches!(location.unpack(), (1, []) | (1, [Parachain(_)]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,20 +151,20 @@ mod tests {
|
||||
use frame_support::{parameter_types, traits::Contains};
|
||||
|
||||
use super::{
|
||||
AllSiblingSystemParachains, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, Here,
|
||||
MultiAsset, MultiLocation, PalletInstance, Parachain, Parent,
|
||||
AllSiblingSystemParachains, Asset, ConcreteAssetFromSystem, ContainsPair, GeneralIndex,
|
||||
Here, Location, PalletInstance, Parachain, Parent,
|
||||
};
|
||||
use polkadot_primitives::LOWEST_PUBLIC_ID;
|
||||
use xcm::latest::prelude::*;
|
||||
|
||||
parameter_types! {
|
||||
pub const RelayLocation: MultiLocation = MultiLocation::parent();
|
||||
pub const RelayLocation: Location = Location::parent();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concrete_asset_from_relay_works() {
|
||||
let expected_asset: MultiAsset = (Parent, 1000000).into();
|
||||
let expected_origin: MultiLocation = (Parent, Here).into();
|
||||
let expected_asset: Asset = (Parent, 1000000).into();
|
||||
let expected_origin: Location = (Parent, Here).into();
|
||||
|
||||
assert!(<ConcreteAssetFromSystem<RelayLocation>>::contains(
|
||||
&expected_asset,
|
||||
@@ -182,12 +174,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn concrete_asset_from_sibling_system_para_fails_for_wrong_asset() {
|
||||
let unexpected_assets: Vec<MultiAsset> = vec![
|
||||
let unexpected_assets: Vec<Asset> = vec![
|
||||
(Here, 1000000).into(),
|
||||
((PalletInstance(50), GeneralIndex(1)), 1000000).into(),
|
||||
((Parent, Parachain(1000), PalletInstance(50), GeneralIndex(1)), 1000000).into(),
|
||||
];
|
||||
let expected_origin: MultiLocation = (Parent, Parachain(1000)).into();
|
||||
let expected_origin: Location = (Parent, Parachain(1000)).into();
|
||||
|
||||
unexpected_assets.iter().for_each(|asset| {
|
||||
assert!(!<ConcreteAssetFromSystem<RelayLocation>>::contains(asset, &expected_origin));
|
||||
@@ -206,10 +198,10 @@ mod tests {
|
||||
(2001, false), // Not a System Parachain
|
||||
];
|
||||
|
||||
let expected_asset: MultiAsset = (Parent, 1000000).into();
|
||||
let expected_asset: Asset = (Parent, 1000000).into();
|
||||
|
||||
for (para_id, expected_result) in test_data {
|
||||
let origin: MultiLocation = (Parent, Parachain(para_id)).into();
|
||||
let origin: Location = (Parent, Parachain(para_id)).into();
|
||||
assert_eq!(
|
||||
expected_result,
|
||||
<ConcreteAssetFromSystem<RelayLocation>>::contains(&expected_asset, &origin)
|
||||
@@ -220,15 +212,15 @@ mod tests {
|
||||
#[test]
|
||||
fn all_sibling_system_parachains_works() {
|
||||
// system parachain
|
||||
assert!(AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(Parachain(1)))));
|
||||
assert!(AllSiblingSystemParachains::contains(&Location::new(1, [Parachain(1)])));
|
||||
// non-system parachain
|
||||
assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(
|
||||
assert!(!AllSiblingSystemParachains::contains(&Location::new(
|
||||
1,
|
||||
X1(Parachain(LOWEST_PUBLIC_ID.into()))
|
||||
[Parachain(LOWEST_PUBLIC_ID.into())]
|
||||
)));
|
||||
// when used at relay chain
|
||||
assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(0, X1(Parachain(1)))));
|
||||
assert!(!AllSiblingSystemParachains::contains(&Location::new(0, [Parachain(1)])));
|
||||
// when used with non-parachain
|
||||
assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(OnlyChild))));
|
||||
assert!(!AllSiblingSystemParachains::contains(&Location::new(1, [OnlyChild])));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user