mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 08:41:02 +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
+1
-1
@@ -22,7 +22,7 @@ pub use xcm::{
|
||||
latest::ParentThen,
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{
|
||||
Error,
|
||||
self, Error,
|
||||
NetworkId::{Rococo as RococoId, Westend as WestendId},
|
||||
},
|
||||
};
|
||||
|
||||
+14
-9
@@ -15,14 +15,14 @@
|
||||
|
||||
use crate::tests::*;
|
||||
|
||||
fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amount: u128) {
|
||||
fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: Location, amount: u128) {
|
||||
let destination = asset_hub_westend_location();
|
||||
|
||||
// fund the AHR's SA on BHR for paying bridge transport fees
|
||||
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128);
|
||||
|
||||
// set XCM versions
|
||||
AssetHubRococo::force_xcm_version(destination, XCM_VERSION);
|
||||
AssetHubRococo::force_xcm_version(destination.clone(), XCM_VERSION);
|
||||
BridgeHubRococo::force_xcm_version(bridge_hub_westend_location(), XCM_VERSION);
|
||||
|
||||
// send message over bridge
|
||||
@@ -33,9 +33,9 @@ fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amou
|
||||
|
||||
#[test]
|
||||
fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
let roc_at_asset_hub_rococo: MultiLocation = Parent.into();
|
||||
let roc_at_asset_hub_rococo: v3::Location = v3::Parent.into();
|
||||
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,
|
||||
@@ -62,7 +62,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
Box::new(Parent.into()),
|
||||
Box::new(xcm::v3::Parent.into()),
|
||||
Box::new(roc_at_asset_hub_westend),
|
||||
));
|
||||
|
||||
@@ -75,7 +75,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::add_liquidity(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
Box::new(Parent.into()),
|
||||
Box::new(xcm::v3::Parent.into()),
|
||||
Box::new(roc_at_asset_hub_westend),
|
||||
1_000_000_000_000,
|
||||
2_000_000_000_000,
|
||||
@@ -101,8 +101,9 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
<Assets as Inspect<_>>::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get())
|
||||
});
|
||||
|
||||
let roc_at_asset_hub_rococo_latest: Location = roc_at_asset_hub_rococo.try_into().unwrap();
|
||||
let amount = ASSET_HUB_ROCOCO_ED * 1_000_000;
|
||||
send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount);
|
||||
send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo_latest, amount);
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
@@ -142,7 +143,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
let prefund_amount = 10_000_000_000_000u128;
|
||||
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 = AssetHubWestend::account_id_of(ALICE);
|
||||
AssetHubRococo::force_create_foreign_asset(
|
||||
wnd_at_asset_hub_rococo,
|
||||
@@ -170,8 +171,12 @@ fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() {
|
||||
let receiver_wnds_before =
|
||||
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendReceiver::get()).free;
|
||||
|
||||
let wnd_at_asset_hub_rococo_latest: Location = wnd_at_asset_hub_rococo.try_into().unwrap();
|
||||
let amount_to_send = ASSET_HUB_WESTEND_ED * 1_000;
|
||||
send_asset_from_asset_hub_rococo_to_asset_hub_westend(wnd_at_asset_hub_rococo, amount_to_send);
|
||||
send_asset_from_asset_hub_rococo_to_asset_hub_westend(
|
||||
wnd_at_asset_hub_rococo_latest.clone(),
|
||||
amount_to_send,
|
||||
);
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
|
||||
+14
-20
@@ -20,37 +20,31 @@ mod send_xcm;
|
||||
mod snowbridge;
|
||||
mod teleport;
|
||||
|
||||
pub(crate) fn asset_hub_westend_location() -> MultiLocation {
|
||||
MultiLocation {
|
||||
parents: 2,
|
||||
interior: X2(
|
||||
GlobalConsensus(NetworkId::Westend),
|
||||
Parachain(AssetHubWestend::para_id().into()),
|
||||
),
|
||||
}
|
||||
pub(crate) fn asset_hub_westend_location() -> Location {
|
||||
Location::new(
|
||||
2,
|
||||
[GlobalConsensus(NetworkId::Westend), Parachain(AssetHubWestend::para_id().into())],
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn bridge_hub_westend_location() -> MultiLocation {
|
||||
MultiLocation {
|
||||
parents: 2,
|
||||
interior: X2(
|
||||
GlobalConsensus(NetworkId::Westend),
|
||||
Parachain(BridgeHubWestend::para_id().into()),
|
||||
),
|
||||
}
|
||||
pub(crate) fn bridge_hub_westend_location() -> Location {
|
||||
Location::new(
|
||||
2,
|
||||
[GlobalConsensus(NetworkId::Westend), Parachain(BridgeHubWestend::para_id().into())],
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn send_asset_from_asset_hub_rococo(
|
||||
destination: MultiLocation,
|
||||
(id, amount): (MultiLocation, u128),
|
||||
destination: Location,
|
||||
(id, amount): (Location, u128),
|
||||
) -> DispatchResult {
|
||||
let signed_origin =
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get().into());
|
||||
|
||||
let beneficiary: MultiLocation =
|
||||
let beneficiary: Location =
|
||||
AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into();
|
||||
|
||||
let assets: MultiAssets = (id, amount).into();
|
||||
let assets: Assets = (id, amount).into();
|
||||
let fee_asset_item = 0;
|
||||
|
||||
AssetHubRococo::execute_with(|| {
|
||||
|
||||
+15
-9
@@ -29,8 +29,8 @@ fn send_xcm_from_rococo_relay_to_westend_asset_hub_should_fail_on_not_applicable
|
||||
let xcm = VersionedXcm::from(Xcm(vec![
|
||||
UnpaidExecution { weight_limit, check_origin },
|
||||
ExportMessage {
|
||||
network: WestendId,
|
||||
destination: X1(Parachain(AssetHubWestend::para_id().into())),
|
||||
network: WestendId.into(),
|
||||
destination: [Parachain(AssetHubWestend::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_westend_location();
|
||||
let native_token = MultiLocation::parent();
|
||||
let native_token = Location::parent();
|
||||
let amount = ASSET_HUB_ROCOCO_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 AssetHubRococo - fails - destination version not known
|
||||
assert_err!(
|
||||
send_asset_from_asset_hub_rococo(destination, (native_token, amount)),
|
||||
send_asset_from_asset_hub_rococo(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
|
||||
AssetHubRococo::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION);
|
||||
AssetHubRococo::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_rococo(destination, (native_token, amount)),
|
||||
send_asset_from_asset_hub_rococo(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 AssetHubRococo - fails - `ExportMessage` is not in `2`
|
||||
assert_err!(
|
||||
send_asset_from_asset_hub_rococo(destination, (native_token, amount)),
|
||||
send_asset_from_asset_hub_rococo(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 AssetHubRococo - ok
|
||||
assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount)));
|
||||
assert_ok!(send_asset_from_asset_hub_rococo(
|
||||
destination.clone(),
|
||||
(native_token.clone(), amount)
|
||||
));
|
||||
|
||||
// `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known
|
||||
assert_bridge_hub_rococo_message_accepted(false);
|
||||
@@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
|
||||
);
|
||||
|
||||
// send XCM from AssetHubRococo - ok
|
||||
assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount)));
|
||||
assert_ok!(send_asset_from_asset_hub_rococo(
|
||||
destination.clone(),
|
||||
(native_token.clone(), amount)
|
||||
));
|
||||
assert_bridge_hub_rococo_message_accepted(true);
|
||||
assert_bridge_hub_westend_message_received();
|
||||
// message delivered and processed at destination
|
||||
|
||||
+30
-33
@@ -61,7 +61,7 @@ fn create_agent() {
|
||||
|
||||
let remote_xcm = VersionedXcm::from(Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
DescendOrigin(X1(Parachain(origin_para))),
|
||||
DescendOrigin(Parachain(origin_para).into()),
|
||||
Transact {
|
||||
require_weight_at_most: 3000000000.into(),
|
||||
origin_kind: OriginKind::Xcm,
|
||||
@@ -109,14 +109,14 @@ fn create_channel() {
|
||||
BridgeHubRococo::fund_para_sovereign(origin_para.into(), INITIAL_FUND);
|
||||
|
||||
let sudo_origin = <Rococo as Chain>::RuntimeOrigin::root();
|
||||
let destination: VersionedMultiLocation =
|
||||
let destination: VersionedLocation =
|
||||
Rococo::child_location_of(BridgeHubRococo::para_id()).into();
|
||||
|
||||
let create_agent_call = SnowbridgeControl::Control(ControlCall::CreateAgent {});
|
||||
|
||||
let create_agent_xcm = VersionedXcm::from(Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
DescendOrigin(X1(Parachain(origin_para))),
|
||||
DescendOrigin(Parachain(origin_para).into()),
|
||||
Transact {
|
||||
require_weight_at_most: 3000000000.into(),
|
||||
origin_kind: OriginKind::Xcm,
|
||||
@@ -129,7 +129,7 @@ fn create_channel() {
|
||||
|
||||
let create_channel_xcm = VersionedXcm::from(Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
DescendOrigin(X1(Parachain(origin_para))),
|
||||
DescendOrigin(Parachain(origin_para).into()),
|
||||
Transact {
|
||||
require_weight_at_most: 3000000000.into(),
|
||||
origin_kind: OriginKind::Xcm,
|
||||
@@ -218,10 +218,10 @@ fn register_weth_token_from_ethereum_to_asset_hub() {
|
||||
|
||||
#[test]
|
||||
fn send_token_from_ethereum_to_penpal() {
|
||||
let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation {
|
||||
parents: 1,
|
||||
interior: X1(Parachain(AssetHubRococo::para_id().into())),
|
||||
});
|
||||
let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new(
|
||||
1,
|
||||
[Parachain(AssetHubRococo::para_id().into())],
|
||||
));
|
||||
BridgeHubRococo::fund_accounts(vec![(asset_hub_sovereign.clone(), INITIAL_FUND)]);
|
||||
|
||||
PenpalA::fund_accounts(vec![
|
||||
@@ -229,9 +229,9 @@ fn send_token_from_ethereum_to_penpal() {
|
||||
(PenpalASender::get(), INITIAL_FUND),
|
||||
]);
|
||||
|
||||
let weth_asset_location: MultiLocation =
|
||||
let weth_asset_location: Location =
|
||||
(Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into();
|
||||
let weth_asset_id = weth_asset_location.into();
|
||||
let weth_asset_id: v3::Location = weth_asset_location.try_into().unwrap();
|
||||
|
||||
let origin_location = (Parent, Parent, EthereumNetwork::get()).into();
|
||||
|
||||
@@ -375,18 +375,15 @@ fn send_token_from_ethereum_to_asset_hub() {
|
||||
#[test]
|
||||
fn send_weth_asset_from_asset_hub_to_ethereum() {
|
||||
use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee;
|
||||
let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation {
|
||||
parents: 1,
|
||||
interior: X1(Parachain(AssetHubRococo::para_id().into())),
|
||||
});
|
||||
let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new(
|
||||
1,
|
||||
[Parachain(AssetHubRococo::para_id().into())],
|
||||
));
|
||||
|
||||
AssetHubRococo::force_default_xcm_version(Some(XCM_VERSION));
|
||||
BridgeHubRococo::force_default_xcm_version(Some(XCM_VERSION));
|
||||
AssetHubRococo::force_xcm_version(
|
||||
MultiLocation {
|
||||
parents: 2,
|
||||
interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })),
|
||||
},
|
||||
Location::new(2, [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })]),
|
||||
XCM_VERSION,
|
||||
);
|
||||
|
||||
@@ -437,27 +434,27 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
|
||||
]
|
||||
);
|
||||
let assets = vec![MultiAsset {
|
||||
id: Concrete(MultiLocation {
|
||||
parents: 2,
|
||||
interior: X2(
|
||||
let assets = vec![Asset {
|
||||
id: AssetId(Location::new(
|
||||
2,
|
||||
[
|
||||
GlobalConsensus(Ethereum { chain_id: CHAIN_ID }),
|
||||
AccountKey20 { network: None, key: WETH },
|
||||
),
|
||||
}),
|
||||
],
|
||||
)),
|
||||
fun: Fungible(WETH_AMOUNT),
|
||||
}];
|
||||
let multi_assets = VersionedMultiAssets::V3(MultiAssets::from(assets));
|
||||
let multi_assets = VersionedAssets::V4(Assets::from(assets));
|
||||
|
||||
let destination = VersionedMultiLocation::V3(MultiLocation {
|
||||
parents: 2,
|
||||
interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })),
|
||||
});
|
||||
let destination = VersionedLocation::V4(Location::new(
|
||||
2,
|
||||
[GlobalConsensus(Ethereum { chain_id: CHAIN_ID })],
|
||||
));
|
||||
|
||||
let beneficiary = VersionedMultiLocation::V3(MultiLocation {
|
||||
parents: 0,
|
||||
interior: X1(AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }),
|
||||
});
|
||||
let beneficiary = VersionedLocation::V4(Location::new(
|
||||
0,
|
||||
[AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }],
|
||||
));
|
||||
|
||||
let free_balance_before = <AssetHubRococo as AssetHubRococoPallet>::Balances::free_balance(
|
||||
AssetHubRococoReceiver::get(),
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ use bridge_hub_rococo_runtime::xcm_config::XcmConfig;
|
||||
#[test]
|
||||
fn teleport_to_other_system_parachains_works() {
|
||||
let amount = BRIDGE_HUB_ROCOCO_ED * 100;
|
||||
let native_asset: MultiAssets = (Parent, amount).into();
|
||||
let native_asset: Assets = (Parent, amount).into();
|
||||
|
||||
test_parachain_is_trusted_teleporter!(
|
||||
BridgeHubRococo, // Origin
|
||||
|
||||
Reference in New Issue
Block a user