mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 00:31:02 +00:00
xcm-emulator: add Rococo<>Westend bridge and add tests for assets transfers over the bridge (#2251)
- switch from Rococo<>Wococo to Rococo<>Westend bridge - add bidirectional simple tests - remove Wococo chains from xcm-emulator - added tests for assets transfers over Rococo<>Westend bridge fixes https://github.com/paritytech/parity-bridges-common/issues/2405
This commit is contained in:
+4
-2
@@ -11,7 +11,9 @@ publish = false
|
||||
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
|
||||
|
||||
# Substrate
|
||||
frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false}
|
||||
frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false }
|
||||
pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false }
|
||||
pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false }
|
||||
pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" }
|
||||
|
||||
# Polkadot
|
||||
@@ -30,4 +32,4 @@ cumulus-pallet-xcmp-queue = { path = "../../../../../../pallets/xcmp-queue", def
|
||||
cumulus-pallet-dmp-queue = { path = "../../../../../../pallets/dmp-queue", default-features = false}
|
||||
bridge-hub-rococo-runtime = { path = "../../../../../../parachains/runtimes/bridge-hubs/bridge-hub-rococo", default-features = false }
|
||||
emulated-integration-tests-common = { path = "../../../common", default-features = false}
|
||||
rococo-wococo-system-emulated-network ={ path = "../../../networks/rococo-wococo-system" }
|
||||
rococo-westend-system-emulated-network = { path = "../../../networks/rococo-westend-system" }
|
||||
|
||||
+15
-8
@@ -21,7 +21,7 @@ pub use xcm::{
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{
|
||||
Error,
|
||||
NetworkId::{Rococo as RococoId, Wococo as WococoId},
|
||||
NetworkId::{Rococo as RococoId, Westend as WestendId},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -30,6 +30,8 @@ pub use bp_messages::LaneId;
|
||||
|
||||
// Cumulus
|
||||
pub use emulated_integration_tests_common::{
|
||||
accounts::ALICE,
|
||||
impls::Inspect,
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
@@ -39,17 +41,22 @@ pub use emulated_integration_tests_common::{
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use rococo_wococo_system_emulated_network::{
|
||||
pub use rococo_westend_system_emulated_network::{
|
||||
asset_hub_rococo_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_ROCOCO_ED, AssetHubRococoParaPallet as AssetHubRococoPallet,
|
||||
},
|
||||
asset_hub_westend_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_WESTEND_ED, AssetHubWestendParaPallet as AssetHubWestendPallet,
|
||||
},
|
||||
bridge_hub_rococo_emulated_chain::{
|
||||
genesis::ED as BRIDGE_HUB_ROCOCO_ED, BridgeHubRococoParaPallet as BridgeHubRococoPallet,
|
||||
},
|
||||
rococo_emulated_chain::{genesis::ED as ROCOCO_ED, RococoRelayPallet as RococoPallet},
|
||||
rococo_emulated_chain::RococoRelayPallet as RococoPallet,
|
||||
AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver,
|
||||
AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWococoPara as AssetHubWococo,
|
||||
BridgeHubRococoPara as BridgeHubRococo, BridgeHubRococoParaReceiver as BridgeHubRococoReceiver,
|
||||
BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWococoPara as BridgeHubWococo,
|
||||
RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver,
|
||||
RococoRelaySender as RococoSender,
|
||||
AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend,
|
||||
AssetHubWestendParaReceiver as AssetHubWestendReceiver, BridgeHubRococoPara as BridgeHubRococo,
|
||||
BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWestendPara as BridgeHubWestend,
|
||||
RococoRelay as Rococo,
|
||||
};
|
||||
|
||||
pub const ASSET_ID: u32 = 1;
|
||||
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
|
||||
fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amount: u128) {
|
||||
let signed_origin =
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get().into());
|
||||
let asset_hub_westend_para_id = AssetHubWestend::para_id().into();
|
||||
let destination = MultiLocation {
|
||||
parents: 2,
|
||||
interior: X2(GlobalConsensus(NetworkId::Westend), Parachain(asset_hub_westend_para_id)),
|
||||
};
|
||||
let beneficiary_id = AssetHubWestendReceiver::get();
|
||||
let beneficiary: MultiLocation =
|
||||
AccountId32Junction { network: None, id: beneficiary_id.into() }.into();
|
||||
let assets: MultiAssets = (id, amount).into();
|
||||
let fee_asset_item = 0;
|
||||
|
||||
// fund the AHR's SA on BHR for paying bridge transport fees
|
||||
let ahr_as_seen_by_bhr = BridgeHubRococo::sibling_location_of(AssetHubRococo::para_id());
|
||||
let sov_ahr_on_bhr = BridgeHubRococo::sovereign_account_id_of(ahr_as_seen_by_bhr);
|
||||
BridgeHubRococo::fund_accounts(vec![(sov_ahr_on_bhr.into(), 10_000_000_000_000u128)]);
|
||||
|
||||
AssetHubRococo::execute_with(|| {
|
||||
assert_ok!(
|
||||
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||
signed_origin,
|
||||
bx!(destination.into()),
|
||||
bx!(beneficiary.into()),
|
||||
bx!(assets.into()),
|
||||
fee_asset_item,
|
||||
WeightLimit::Unlimited,
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
BridgeHubRococo,
|
||||
vec![
|
||||
// pay for bridge fees
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { .. }) => {},
|
||||
// message exported
|
||||
RuntimeEvent::BridgeWestendMessages(
|
||||
pallet_bridge_messages::Event::MessageAccepted { .. }
|
||||
) => {},
|
||||
// message processed successfully
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
BridgeHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubWestend as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
BridgeHubWestend,
|
||||
vec![
|
||||
// message dispatched successfully
|
||||
RuntimeEvent::XcmpQueue(
|
||||
cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[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_westend =
|
||||
MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) };
|
||||
let owner: AccountId = AssetHubWestend::account_id_of(ALICE);
|
||||
AssetHubWestend::force_create_foreign_asset(
|
||||
roc_at_asset_hub_westend,
|
||||
owner,
|
||||
true,
|
||||
ASSET_MIN_BALANCE,
|
||||
vec![],
|
||||
);
|
||||
let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
|
||||
NetworkId::Westend,
|
||||
AssetHubWestend::para_id(),
|
||||
);
|
||||
|
||||
let rocs_in_reserve_on_ahr_before =
|
||||
<AssetHubRococo as Chain>::account_data_of(sov_ahw_on_ahr.clone()).free;
|
||||
let sender_rocs_before =
|
||||
<AssetHubRococo as Chain>::account_data_of(AssetHubRococoSender::get()).free;
|
||||
let receiver_rocs_before = AssetHubWestend::execute_with(|| {
|
||||
type Assets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get())
|
||||
});
|
||||
|
||||
let amount = ASSET_HUB_ROCOCO_ED * 1_000;
|
||||
send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount);
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
// issue ROCs on AHW
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => {
|
||||
asset_id: *asset_id == roc_at_asset_hub_rococo,
|
||||
owner: *owner == AssetHubWestendReceiver::get(),
|
||||
},
|
||||
// message processed successfully
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
let sender_rocs_after =
|
||||
<AssetHubRococo as Chain>::account_data_of(AssetHubRococoSender::get()).free;
|
||||
let receiver_rocs_after = AssetHubWestend::execute_with(|| {
|
||||
type Assets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get())
|
||||
});
|
||||
let rocs_in_reserve_on_ahr_after =
|
||||
<AssetHubRococo as Chain>::account_data_of(sov_ahw_on_ahr.clone()).free;
|
||||
|
||||
// Sender's balance is reduced
|
||||
assert!(sender_rocs_before > sender_rocs_after);
|
||||
// Receiver's balance is increased
|
||||
assert!(receiver_rocs_after > receiver_rocs_before);
|
||||
// Reserve balance is reduced by sent amount
|
||||
assert_eq!(rocs_in_reserve_on_ahr_after, rocs_in_reserve_on_ahr_before + amount);
|
||||
}
|
||||
|
||||
#[test]
|
||||
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)) };
|
||||
let owner: AccountId = AssetHubWestend::account_id_of(ALICE);
|
||||
AssetHubRococo::force_create_foreign_asset(
|
||||
wnd_at_asset_hub_rococo,
|
||||
owner,
|
||||
true,
|
||||
ASSET_MIN_BALANCE,
|
||||
vec![(AssetHubRococoSender::get(), prefund_amount)],
|
||||
);
|
||||
|
||||
// fund the AHR's SA on AHW with the WND tokens held in reserve
|
||||
let sov_ahr_on_ahw = AssetHubWestend::sovereign_account_of_parachain_on_other_global_consensus(
|
||||
NetworkId::Rococo,
|
||||
AssetHubRococo::para_id(),
|
||||
);
|
||||
AssetHubWestend::fund_accounts(vec![(sov_ahr_on_ahw.clone(), prefund_amount)]);
|
||||
|
||||
let wnds_in_reserve_on_ahw_before =
|
||||
<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
|
||||
assert_eq!(wnds_in_reserve_on_ahw_before, prefund_amount);
|
||||
let sender_wnds_before = AssetHubRococo::execute_with(|| {
|
||||
type Assets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(wnd_at_asset_hub_rococo, &AssetHubRococoSender::get())
|
||||
});
|
||||
assert_eq!(sender_wnds_before, prefund_amount);
|
||||
let receiver_wnds_before =
|
||||
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendReceiver::get()).free;
|
||||
|
||||
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);
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
// WND is withdrawn from AHR's SA on AHW
|
||||
RuntimeEvent::Balances(
|
||||
pallet_balances::Event::Withdraw { who, amount }
|
||||
) => {
|
||||
who: *who == sov_ahr_on_ahw,
|
||||
amount: *amount == amount_to_send,
|
||||
},
|
||||
// WNDs deposited to beneficiary
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => {
|
||||
who: *who == AssetHubWestendReceiver::get(),
|
||||
},
|
||||
// message processed successfully
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
let sender_wnds_after = AssetHubRococo::execute_with(|| {
|
||||
type Assets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(wnd_at_asset_hub_rococo, &AssetHubRococoSender::get())
|
||||
});
|
||||
let receiver_wnds_after =
|
||||
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendReceiver::get()).free;
|
||||
let wnds_in_reserve_on_ahw_after =
|
||||
<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw).free;
|
||||
|
||||
// Sender's balance is reduced
|
||||
assert!(sender_wnds_before > sender_wnds_after);
|
||||
// Receiver's balance is increased
|
||||
assert!(receiver_wnds_after > receiver_wnds_before);
|
||||
// Reserve balance is reduced by sent amount
|
||||
assert_eq!(wnds_in_reserve_on_ahw_after, wnds_in_reserve_on_ahw_before - amount_to_send);
|
||||
}
|
||||
+2
-1
@@ -13,5 +13,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
mod example;
|
||||
mod asset_transfers;
|
||||
mod send_xcm;
|
||||
mod teleport;
|
||||
|
||||
+14
-14
@@ -16,7 +16,7 @@
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn example() {
|
||||
fn send_xcm_from_rococo_relay_to_westend_asset_hub() {
|
||||
// Init tests variables
|
||||
// XcmPallet send arguments
|
||||
let sudo_origin = <Rococo as Chain>::RuntimeOrigin::root();
|
||||
@@ -29,13 +29,13 @@ fn example() {
|
||||
let xcm = VersionedXcm::from(Xcm(vec![
|
||||
UnpaidExecution { weight_limit, check_origin },
|
||||
ExportMessage {
|
||||
network: WococoId,
|
||||
destination: X1(Parachain(AssetHubWococo::para_id().into())),
|
||||
network: WestendId,
|
||||
destination: X1(Parachain(AssetHubWestend::para_id().into())),
|
||||
xcm: remote_xcm,
|
||||
},
|
||||
]));
|
||||
|
||||
//Rococo Global Consensus
|
||||
// Rococo Global Consensus
|
||||
// Send XCM message from Relay Chain to Bridge Hub source Parachain
|
||||
Rococo::execute_with(|| {
|
||||
assert_ok!(<Rococo as RococoPallet>::XcmPallet::send(
|
||||
@@ -64,32 +64,32 @@ fn example() {
|
||||
success: true,
|
||||
..
|
||||
}) => {},
|
||||
RuntimeEvent::BridgeWococoMessages(pallet_bridge_messages::Event::MessageAccepted {
|
||||
lane_id: LaneId([0, 0, 0, 1]),
|
||||
RuntimeEvent::BridgeWestendMessages(pallet_bridge_messages::Event::MessageAccepted {
|
||||
lane_id: LaneId([0, 0, 0, 2]),
|
||||
nonce: 1,
|
||||
}) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
// Wococo GLobal Consensus
|
||||
// Westend Global Consensus
|
||||
// Receive XCM message in Bridge Hub target Parachain
|
||||
BridgeHubWococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubWococo as Chain>::RuntimeEvent;
|
||||
BridgeHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubWestend as Chain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
BridgeHubWococo,
|
||||
BridgeHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
// Receive embeded XCM message within `ExportMessage` in Parachain destination
|
||||
AssetHubWococo::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWococo as Chain>::RuntimeEvent;
|
||||
// Receive embedded XCM message within `ExportMessage` in Parachain destination
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWococo,
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed {
|
||||
..
|
||||
+4
-2
@@ -11,7 +11,9 @@ publish = false
|
||||
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
|
||||
|
||||
# Substrate
|
||||
frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false}
|
||||
frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false }
|
||||
pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false }
|
||||
pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false }
|
||||
pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" }
|
||||
|
||||
# Polkadot
|
||||
@@ -30,4 +32,4 @@ cumulus-pallet-xcmp-queue = { path = "../../../../../../pallets/xcmp-queue", def
|
||||
cumulus-pallet-dmp-queue = { path = "../../../../../../pallets/dmp-queue", default-features = false}
|
||||
bridge-hub-westend-runtime = { path = "../../../../../../parachains/runtimes/bridge-hubs/bridge-hub-westend", default-features = false }
|
||||
emulated-integration-tests-common = { path = "../../../common", default-features = false}
|
||||
westend-system-emulated-network ={ path = "../../../networks/westend-system" }
|
||||
rococo-westend-system-emulated-network = { path = "../../../networks/rococo-westend-system" }
|
||||
|
||||
+20
-9
@@ -19,7 +19,10 @@ pub use frame_support::assert_ok;
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{Error, NetworkId::Rococo as RococoId},
|
||||
v3::{
|
||||
Error,
|
||||
NetworkId::{Rococo as RococoId, Westend as WestendId},
|
||||
},
|
||||
};
|
||||
|
||||
// Bridges
|
||||
@@ -27,6 +30,8 @@ pub use bp_messages::LaneId;
|
||||
|
||||
// Cumulus
|
||||
pub use emulated_integration_tests_common::{
|
||||
accounts::ALICE,
|
||||
impls::Inspect,
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
@@ -36,16 +41,22 @@ pub use emulated_integration_tests_common::{
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use westend_system_emulated_network::{
|
||||
bridge_hub_westend_emulated_chain::{
|
||||
genesis::ED as BRIDGE_HUB_ROCOCO_ED, BridgeHubWestendParaPallet as BridgeHubWestendPallet,
|
||||
pub use rococo_westend_system_emulated_network::{
|
||||
asset_hub_rococo_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_ROCOCO_ED, AssetHubRococoParaPallet as AssetHubRococoPallet,
|
||||
},
|
||||
westend_emulated_chain::{genesis::ED as ROCOCO_ED, WestendRelayPallet as WestendPallet},
|
||||
asset_hub_westend_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_WESTEND_ED, AssetHubWestendParaPallet as AssetHubWestendPallet,
|
||||
},
|
||||
bridge_hub_westend_emulated_chain::{
|
||||
genesis::ED as BRIDGE_HUB_WESTEND_ED, BridgeHubWestendParaPallet as BridgeHubWestendPallet,
|
||||
},
|
||||
westend_emulated_chain::WestendRelayPallet as WestendPallet,
|
||||
AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver,
|
||||
AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
||||
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubWestendPara as BridgeHubWestend,
|
||||
BridgeHubWestendParaReceiver as BridgeHubWestendReceiver,
|
||||
BridgeHubWestendParaSender as BridgeHubWestendSender, WestendRelay as Westend,
|
||||
WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender,
|
||||
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo,
|
||||
BridgeHubWestendPara as BridgeHubWestend, BridgeHubWestendParaSender as BridgeHubWestendSender,
|
||||
WestendRelay as Westend,
|
||||
};
|
||||
|
||||
pub const ASSET_ID: u32 = 1;
|
||||
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use crate::*;
|
||||
|
||||
fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amount: u128) {
|
||||
let signed_origin =
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get().into());
|
||||
let asset_hub_rococo_para_id = AssetHubRococo::para_id().into();
|
||||
let destination = MultiLocation {
|
||||
parents: 2,
|
||||
interior: X2(GlobalConsensus(NetworkId::Rococo), Parachain(asset_hub_rococo_para_id)),
|
||||
};
|
||||
let beneficiary_id = AssetHubRococoReceiver::get();
|
||||
let beneficiary: MultiLocation =
|
||||
AccountId32Junction { network: None, id: beneficiary_id.into() }.into();
|
||||
let assets: MultiAssets = (id, amount).into();
|
||||
let fee_asset_item = 0;
|
||||
|
||||
// fund the AHW's SA on BHW for paying bridge transport fees
|
||||
let ahw_as_seen_by_bhw = BridgeHubWestend::sibling_location_of(AssetHubWestend::para_id());
|
||||
let sov_ahw_on_bhw = BridgeHubWestend::sovereign_account_id_of(ahw_as_seen_by_bhw);
|
||||
BridgeHubWestend::fund_accounts(vec![(sov_ahw_on_bhw.into(), 10_000_000_000_000u128)]);
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
assert_ok!(
|
||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||
signed_origin,
|
||||
bx!(destination.into()),
|
||||
bx!(beneficiary.into()),
|
||||
bx!(assets.into()),
|
||||
fee_asset_item,
|
||||
WeightLimit::Unlimited,
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
BridgeHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubWestend as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
BridgeHubWestend,
|
||||
vec![
|
||||
// pay for bridge fees
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { .. }) => {},
|
||||
// message exported
|
||||
RuntimeEvent::BridgeRococoMessages(
|
||||
pallet_bridge_messages::Event::MessageAccepted { .. }
|
||||
) => {},
|
||||
// message processed successfully
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
BridgeHubRococo,
|
||||
vec![
|
||||
// message dispatched successfully
|
||||
RuntimeEvent::XcmpQueue(
|
||||
cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[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_rococo =
|
||||
MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) };
|
||||
let owner: AccountId = AssetHubRococo::account_id_of(ALICE);
|
||||
AssetHubRococo::force_create_foreign_asset(
|
||||
wnd_at_asset_hub_rococo,
|
||||
owner,
|
||||
true,
|
||||
ASSET_MIN_BALANCE,
|
||||
vec![],
|
||||
);
|
||||
let sov_ahr_on_ahw = AssetHubWestend::sovereign_account_of_parachain_on_other_global_consensus(
|
||||
NetworkId::Rococo,
|
||||
AssetHubRococo::para_id(),
|
||||
);
|
||||
|
||||
let wnds_in_reserve_on_ahw_before =
|
||||
<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw.clone()).free;
|
||||
let sender_wnds_before =
|
||||
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendSender::get()).free;
|
||||
let receiver_wnds_before = AssetHubRococo::execute_with(|| {
|
||||
type Assets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(wnd_at_asset_hub_rococo, &AssetHubRococoReceiver::get())
|
||||
});
|
||||
|
||||
let amount = ASSET_HUB_WESTEND_ED * 1_000;
|
||||
send_asset_from_asset_hub_westend_to_asset_hub_rococo(wnd_at_asset_hub_westend, amount);
|
||||
AssetHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
// issue WNDs on AHR
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => {
|
||||
asset_id: *asset_id == wnd_at_asset_hub_rococo,
|
||||
owner: *owner == AssetHubRococoReceiver::get(),
|
||||
},
|
||||
// message processed successfully
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
let sender_wnds_after =
|
||||
<AssetHubWestend as Chain>::account_data_of(AssetHubWestendSender::get()).free;
|
||||
let receiver_wnds_after = AssetHubRococo::execute_with(|| {
|
||||
type Assets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(wnd_at_asset_hub_rococo, &AssetHubRococoReceiver::get())
|
||||
});
|
||||
let wnds_in_reserve_on_ahw_after =
|
||||
<AssetHubWestend as Chain>::account_data_of(sov_ahr_on_ahw).free;
|
||||
|
||||
// Sender's balance is reduced
|
||||
assert!(sender_wnds_before > sender_wnds_after);
|
||||
// Receiver's balance is increased
|
||||
assert!(receiver_wnds_after > receiver_wnds_before);
|
||||
// Reserve balance is increased by sent amount
|
||||
assert_eq!(wnds_in_reserve_on_ahw_after, wnds_in_reserve_on_ahw_before + amount);
|
||||
}
|
||||
|
||||
#[test]
|
||||
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)) };
|
||||
let owner: AccountId = AssetHubWestend::account_id_of(ALICE);
|
||||
AssetHubWestend::force_create_foreign_asset(
|
||||
roc_at_asset_hub_westend,
|
||||
owner,
|
||||
true,
|
||||
ASSET_MIN_BALANCE,
|
||||
vec![(AssetHubWestendSender::get(), prefund_amount)],
|
||||
);
|
||||
|
||||
// fund the AHW's SA on AHR with the ROC tokens held in reserve
|
||||
let sov_ahw_on_ahr = AssetHubRococo::sovereign_account_of_parachain_on_other_global_consensus(
|
||||
NetworkId::Westend,
|
||||
AssetHubWestend::para_id(),
|
||||
);
|
||||
AssetHubRococo::fund_accounts(vec![(sov_ahw_on_ahr.clone(), prefund_amount)]);
|
||||
|
||||
let rocs_in_reserve_on_ahr_before =
|
||||
<AssetHubRococo as Chain>::account_data_of(sov_ahw_on_ahr.clone()).free;
|
||||
assert_eq!(rocs_in_reserve_on_ahr_before, prefund_amount);
|
||||
let sender_rocs_before = AssetHubWestend::execute_with(|| {
|
||||
type Assets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(roc_at_asset_hub_westend, &AssetHubWestendSender::get())
|
||||
});
|
||||
assert_eq!(sender_rocs_before, prefund_amount);
|
||||
let receiver_rocs_before =
|
||||
<AssetHubRococo as Chain>::account_data_of(AssetHubRococoReceiver::get()).free;
|
||||
|
||||
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);
|
||||
AssetHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
// ROC is withdrawn from AHW's SA on AHR
|
||||
RuntimeEvent::Balances(
|
||||
pallet_balances::Event::Withdraw { who, amount }
|
||||
) => {
|
||||
who: *who == sov_ahw_on_ahr,
|
||||
amount: *amount == amount_to_send,
|
||||
},
|
||||
// ROCs deposited to beneficiary
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => {
|
||||
who: *who == AssetHubRococoReceiver::get(),
|
||||
},
|
||||
// message processed successfully
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
let sender_rocs_after = AssetHubWestend::execute_with(|| {
|
||||
type Assets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
<Assets as Inspect<_>>::balance(roc_at_asset_hub_westend, &AssetHubWestendSender::get())
|
||||
});
|
||||
let receiver_rocs_after =
|
||||
<AssetHubRococo as Chain>::account_data_of(AssetHubRococoReceiver::get()).free;
|
||||
let rocs_in_reserve_on_ahr_after =
|
||||
<AssetHubRococo as Chain>::account_data_of(sov_ahw_on_ahr.clone()).free;
|
||||
|
||||
// Sender's balance is reduced
|
||||
assert!(sender_rocs_before > sender_rocs_after);
|
||||
// Receiver's balance is increased
|
||||
assert!(receiver_rocs_after > receiver_rocs_before);
|
||||
// Reserve balance is reduced by sent amount
|
||||
assert_eq!(rocs_in_reserve_on_ahr_after, rocs_in_reserve_on_ahr_before - amount_to_send);
|
||||
}
|
||||
+2
-1
@@ -13,5 +13,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
mod example;
|
||||
mod asset_transfers;
|
||||
mod send_xcm;
|
||||
mod teleport;
|
||||
|
||||
+28
-2
@@ -16,7 +16,7 @@
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn example() {
|
||||
fn send_xcm_from_westend_relay_to_rococo_asset_hub() {
|
||||
// Init tests variables
|
||||
// XcmPallet send arguments
|
||||
let sudo_origin = <Westend as Chain>::RuntimeOrigin::root();
|
||||
@@ -30,7 +30,7 @@ fn example() {
|
||||
UnpaidExecution { weight_limit, check_origin },
|
||||
ExportMessage {
|
||||
network: RococoId,
|
||||
destination: X1(Parachain(AssetHubWestend::para_id().into())),
|
||||
destination: X1(Parachain(AssetHubRococo::para_id().into())),
|
||||
xcm: remote_xcm,
|
||||
},
|
||||
]));
|
||||
@@ -71,4 +71,30 @@ fn example() {
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
// Rococo Global Consensus
|
||||
// Receive XCM message in Bridge Hub target Parachain
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
BridgeHubRococo,
|
||||
vec![
|
||||
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
// Receive embedded XCM message within `ExportMessage` in Parachain destination
|
||||
AssetHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed {
|
||||
..
|
||||
}) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ use bridge_hub_westend_runtime::xcm_config::XcmConfig;
|
||||
|
||||
#[test]
|
||||
fn teleport_to_other_system_parachains_works() {
|
||||
let amount = BRIDGE_HUB_ROCOCO_ED * 100;
|
||||
let amount = BRIDGE_HUB_WESTEND_ED * 100;
|
||||
let native_asset: MultiAssets = (Parent, amount).into();
|
||||
|
||||
test_parachain_is_trusted_teleporter!(
|
||||
|
||||
Reference in New Issue
Block a user