# 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,7 +21,8 @@ pub use sp_runtime::DispatchError;
pub use xcm::{
latest::ParentThen,
prelude::{AccountId32 as AccountId32Junction, *},
v3::{
v3,
v4::{
Error,
NetworkId::{Rococo as RococoId, Westend as WestendId},
},
@@ -14,14 +14,14 @@
// limitations under the License.
use crate::tests::*;
fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amount: u128) {
fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: Location, amount: u128) {
let destination = asset_hub_rococo_location();
// fund the AHW's SA on BHW for paying bridge transport fees
BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128);
// set XCM versions
AssetHubWestend::force_xcm_version(destination, XCM_VERSION);
AssetHubWestend::force_xcm_version(destination.clone(), XCM_VERSION);
BridgeHubWestend::force_xcm_version(bridge_hub_rococo_location(), XCM_VERSION);
// send message over bridge
@@ -32,9 +32,9 @@ fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amou
#[test]
fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() {
let wnd_at_asset_hub_westend: MultiLocation = Parent.into();
let wnd_at_asset_hub_westend: Location = Parent.into();
let wnd_at_asset_hub_rococo =
MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) };
v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]);
let owner: AccountId = AssetHubRococo::account_id_of(ALICE);
AssetHubRococo::force_create_foreign_asset(
wnd_at_asset_hub_rococo,
@@ -61,7 +61,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() {
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::create_pool(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
Box::new(Parent.into()),
Box::new(xcm::v3::Parent.into()),
Box::new(wnd_at_asset_hub_rococo),
));
@@ -74,7 +74,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() {
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::add_liquidity(
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
Box::new(Parent.into()),
Box::new(xcm::v3::Parent.into()),
Box::new(wnd_at_asset_hub_rococo),
1_000_000_000_000,
2_000_000_000_000,
@@ -141,7 +141,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() {
fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() {
let prefund_amount = 10_000_000_000_000u128;
let roc_at_asset_hub_westend =
MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) };
v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]);
let owner: AccountId = AssetHubWestend::account_id_of(ALICE);
AssetHubWestend::force_create_foreign_asset(
roc_at_asset_hub_westend,
@@ -169,8 +169,12 @@ fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() {
let receiver_rocs_before =
<AssetHubRococo as Chain>::account_data_of(AssetHubRococoReceiver::get()).free;
let roc_at_asset_hub_westend_latest: Location = roc_at_asset_hub_westend.try_into().unwrap();
let amount_to_send = ASSET_HUB_ROCOCO_ED * 1_000;
send_asset_from_asset_hub_westend_to_asset_hub_rococo(roc_at_asset_hub_westend, amount_to_send);
send_asset_from_asset_hub_westend_to_asset_hub_rococo(
roc_at_asset_hub_westend_latest.clone(),
amount_to_send,
);
AssetHubRococo::execute_with(|| {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
assert_expected_events!(
@@ -19,37 +19,31 @@ mod asset_transfers;
mod send_xcm;
mod teleport;
pub(crate) fn asset_hub_rococo_location() -> MultiLocation {
MultiLocation {
parents: 2,
interior: X2(
GlobalConsensus(NetworkId::Rococo),
Parachain(AssetHubRococo::para_id().into()),
),
}
pub(crate) fn asset_hub_rococo_location() -> Location {
Location::new(
2,
[GlobalConsensus(NetworkId::Rococo), Parachain(AssetHubRococo::para_id().into())],
)
}
pub(crate) fn bridge_hub_rococo_location() -> MultiLocation {
MultiLocation {
parents: 2,
interior: X2(
GlobalConsensus(NetworkId::Rococo),
Parachain(BridgeHubRococo::para_id().into()),
),
}
pub(crate) fn bridge_hub_rococo_location() -> Location {
Location::new(
2,
[GlobalConsensus(NetworkId::Rococo), Parachain(BridgeHubRococo::para_id().into())],
)
}
pub(crate) fn send_asset_from_asset_hub_westend(
destination: MultiLocation,
(id, amount): (MultiLocation, u128),
destination: Location,
(id, amount): (Location, u128),
) -> DispatchResult {
let signed_origin =
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get().into());
let beneficiary: MultiLocation =
let beneficiary: Location =
AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into();
let assets: MultiAssets = (id, amount).into();
let assets: Assets = (id, amount).into();
let fee_asset_item = 0;
AssetHubWestend::execute_with(|| {
@@ -30,7 +30,7 @@ fn send_xcm_from_westend_relay_to_rococo_asset_hub_should_fail_on_not_applicable
UnpaidExecution { weight_limit, check_origin },
ExportMessage {
network: RococoId,
destination: X1(Parachain(AssetHubRococo::para_id().into())),
destination: [Parachain(AssetHubRococo::para_id().into())].into(),
xcm: remote_xcm,
},
]));
@@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
// prepare data
let destination = asset_hub_rococo_location();
let native_token = MultiLocation::parent();
let native_token = Location::parent();
let amount = ASSET_HUB_WESTEND_ED * 1_000;
// fund the AHR's SA on BHR for paying bridge transport fees
@@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
// send XCM from AssetHubWestend - fails - destination version not known
assert_err!(
send_asset_from_asset_hub_westend(destination, (native_token, amount)),
send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)),
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [1, 0, 0, 0],
@@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
);
// set destination version
AssetHubWestend::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION);
AssetHubWestend::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION);
// TODO: remove this block, when removing `xcm:v2`
{
@@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
// version, which does not have the `ExportMessage` instruction. If the default `2` is
// changed to `3`, then this assert can go away"
assert_err!(
send_asset_from_asset_hub_westend(destination, (native_token, amount)),
send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)),
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [1, 0, 0, 0],
@@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
);
// send XCM from AssetHubWestend - fails - `ExportMessage` is not in `2`
assert_err!(
send_asset_from_asset_hub_westend(destination, (native_token, amount)),
send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)),
DispatchError::Module(sp_runtime::ModuleError {
index: 31,
error: [1, 0, 0, 0],
@@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
xcm::v3::prelude::XCM_VERSION,
);
// send XCM from AssetHubWestend - ok
assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount)));
assert_ok!(send_asset_from_asset_hub_westend(
destination.clone(),
(native_token.clone(), amount)
));
// `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known
assert_bridge_hub_westend_message_accepted(false);
@@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
);
// send XCM from AssetHubWestend - ok
assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount)));
assert_ok!(send_asset_from_asset_hub_westend(
destination.clone(),
(native_token.clone(), amount)
));
assert_bridge_hub_westend_message_accepted(true);
assert_bridge_hub_rococo_message_received();
// message delivered and processed at destination
@@ -19,7 +19,7 @@ use bridge_hub_westend_runtime::xcm_config::XcmConfig;
#[test]
fn teleport_to_other_system_parachains_works() {
let amount = BRIDGE_HUB_WESTEND_ED * 100;
let native_asset: MultiAssets = (Parent, amount).into();
let native_asset: Assets = (Parent, amount).into();
test_parachain_is_trusted_teleporter!(
BridgeHubWestend, // Origin