Remove kusama and polkadot runtime crates (#1731)

This pull request is removing the Kusama and Polkadot runtime crates. As
still some crates dependent on the runtime crates, this pull request is
doing some more changes.

- It removes the `hostperfcheck` CLI command. This CLI command could
compare the current node against the standard hardware by doing some
checks. Later we added the hardware benchmark feature to Substrate. This
hardware benchmark is running on every node startup and prints a warning
if the current node is too slow. This makes this CLI command a duplicate
that was also depending on the kusama runtime.

- The pull request is removing the emulated integration tests that were
requiring the Kusama or Polkadot runtime crates.
This commit is contained in:
Bastian Köcher
2023-09-29 09:54:11 +02:00
committed by GitHub
parent 4902db2198
commit bf90cb0b73
202 changed files with 49 additions and 40336 deletions
@@ -1,53 +0,0 @@
[package]
name = "asset-hub-kusama-integration-tests"
version = "1.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
description = "Asset Hub Kusama runtime integration tests with xcm-emulator"
publish = false
[dependencies]
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
assert_matches = "1.5.0"
# Substrate
sp-runtime = { path = "../../../../../../substrate/primitives/runtime", default-features = false}
frame-support = { path = "../../../../../../substrate/frame/support", default-features = false}
frame-system = { path = "../../../../../../substrate/frame/system", default-features = false}
pallet-balances = { path = "../../../../../../substrate/frame/balances", default-features = false}
pallet-assets = { path = "../../../../../../substrate/frame/assets", default-features = false}
pallet-asset-conversion = { path = "../../../../../../substrate/frame/asset-conversion", default-features = false}
# Polkadot
polkadot-core-primitives = { path = "../../../../../../polkadot/core-primitives", default-features = false}
polkadot-parachain-primitives = { path = "../../../../../../polkadot/parachain", default-features = false}
polkadot-runtime-parachains = { path = "../../../../../../polkadot/runtime/parachains" }
polkadot-runtime = { path = "../../../../../../polkadot/runtime/polkadot" }
xcm = { package = "staging-xcm", path = "../../../../../../polkadot/xcm", default-features = false}
pallet-xcm = { path = "../../../../../../polkadot/xcm/pallet-xcm", default-features = false}
# Cumulus
parachains-common = { path = "../../../../common" }
asset-hub-kusama-runtime = { path = "../../../../runtimes/assets/asset-hub-kusama" }
# Local
xcm-emulator = { path = "../../../../../xcm/xcm-emulator", default-features = false}
integration-tests-common = { path = "../../common", default-features = false}
[features]
runtime-benchmarks = [
"asset-hub-kusama-runtime/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"integration-tests-common/runtime-benchmarks",
"pallet-asset-conversion/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
"parachains-common/runtime-benchmarks",
"polkadot-parachain-primitives/runtime-benchmarks",
"polkadot-runtime-parachains/runtime-benchmarks",
"polkadot-runtime/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
@@ -1,90 +0,0 @@
// 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.
pub use codec::Encode;
pub use frame_support::{
assert_err, assert_ok,
pallet_prelude::Weight,
sp_runtime::{AccountId32, DispatchError, DispatchResult},
traits::fungibles::Inspect,
};
pub use integration_tests_common::{
constants::{
asset_hub_kusama::ED as ASSET_HUB_KUSAMA_ED, kusama::ED as KUSAMA_ED, PROOF_SIZE_THRESHOLD,
REF_TIME_THRESHOLD, XCM_V3,
},
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
AssetHubKusama, AssetHubKusamaPallet, AssetHubKusamaReceiver, AssetHubKusamaSender, Kusama,
KusamaPallet, KusamaReceiver, KusamaSender, PenpalKusamaA, PenpalKusamaAPallet,
PenpalKusamaAReceiver, PenpalKusamaASender, PenpalKusamaB, PenpalKusamaBPallet,
};
pub use parachains_common::{AccountId, Balance};
pub use xcm::{
prelude::{AccountId32 as AccountId32Junction, *},
v3::{Error, NetworkId::Kusama as KusamaId},
};
pub use xcm_emulator::{
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
};
pub const ASSET_ID: u32 = 1;
pub const ASSET_MIN_BALANCE: u128 = 1000;
// `Assets` pallet index
pub const ASSETS_PALLET_ID: u8 = 50;
pub type RelayToSystemParaTest = Test<Kusama, AssetHubKusama>;
pub type SystemParaToRelayTest = Test<AssetHubKusama, Kusama>;
pub type SystemParaToParaTest = Test<AssetHubKusama, PenpalKusamaA>;
/// Returns a `TestArgs` instance to de used for the Relay Chain accross integraton tests
pub fn relay_test_args(amount: Balance) -> TestArgs {
TestArgs {
dest: Kusama::child_location_of(AssetHubKusama::para_id()),
beneficiary: AccountId32Junction {
network: None,
id: AssetHubKusamaReceiver::get().into(),
}
.into(),
amount,
assets: (Here, amount).into(),
asset_id: None,
fee_asset_item: 0,
weight_limit: WeightLimit::Unlimited,
}
}
/// Returns a `TestArgs` instance to de used for the System Parachain accross integraton tests
pub fn system_para_test_args(
dest: MultiLocation,
beneficiary_id: AccountId32,
amount: Balance,
assets: MultiAssets,
asset_id: Option<u32>,
) -> TestArgs {
TestArgs {
dest,
beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(),
amount,
assets,
asset_id,
fee_asset_item: 0,
weight_limit: WeightLimit::Unlimited,
}
}
#[cfg(test)]
#[cfg(not(feature = "runtime-benchmarks"))]
mod tests;
@@ -1,198 +0,0 @@
// 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::*;
const MAX_CAPACITY: u32 = 8;
const MAX_MESSAGE_SIZE: u32 = 8192;
/// Opening HRMP channels between Parachains should work
#[test]
fn open_hrmp_channel_between_paras_works() {
// Parchain A init values
let para_a_id = PenpalKusamaA::para_id();
let para_a_root_origin = <PenpalKusamaA as Chain>::RuntimeOrigin::root();
// Parachain B init values
let para_b_id = PenpalKusamaB::para_id();
let para_b_root_origin = <PenpalKusamaB as Chain>::RuntimeOrigin::root();
let fee_amount = KUSAMA_ED * 1000;
let fund_amount = KUSAMA_ED * 1000_000_000;
// Fund Parachain's Sovereign accounts to be able to reserve the deposit
let para_a_sovereign_account = Kusama::fund_para_sovereign(fund_amount, para_a_id);
let para_b_sovereign_account = Kusama::fund_para_sovereign(fund_amount, para_b_id);
let relay_destination: VersionedMultiLocation = PenpalKusamaA::parent_location().into();
// ---- Init Open channel from Parachain to System Parachain
let mut call = Kusama::init_open_channel_call(para_b_id, MAX_CAPACITY, MAX_MESSAGE_SIZE);
let origin_kind = OriginKind::Native;
let native_asset: MultiAsset = (Here, fee_amount).into();
let beneficiary = Kusama::sovereign_account_id_of_child_para(para_a_id);
let mut xcm = xcm_transact_paid_execution(call, origin_kind, native_asset.clone(), beneficiary);
PenpalKusamaA::execute_with(|| {
assert_ok!(<PenpalKusamaA as PenpalKusamaAPallet>::PolkadotXcm::send(
para_a_root_origin,
bx!(relay_destination.clone()),
bx!(xcm),
));
PenpalKusamaA::assert_xcm_pallet_sent();
});
Kusama::execute_with(|| {
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
Kusama::assert_ump_queue_processed(
true,
Some(para_a_id),
Some(Weight::from_parts(1_312_558_000, 200000)),
);
assert_expected_events!(
Kusama,
vec![
// Parachain's Sovereign account balance is withdrawn to pay XCM fees
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == para_a_sovereign_account.clone(),
amount: *amount == fee_amount,
},
// Sender deposit is reserved for Parachain's Sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Reserved { who, .. }) =>{
who: *who == para_a_sovereign_account,
},
// Open channel requested from Para A to Para B
RuntimeEvent::Hrmp(
polkadot_runtime_parachains::hrmp::Event::OpenChannelRequested {
sender,
recipient,
proposed_max_capacity: max_capacity,
proposed_max_message_size: max_message_size
}
) => {
sender: *sender == para_a_id.into(),
recipient: *recipient == para_b_id.into(),
max_capacity: *max_capacity == MAX_CAPACITY,
max_message_size: *max_message_size == MAX_MESSAGE_SIZE,
},
]
);
});
// ---- Accept Open channel from Parachain to System Parachain
call = Kusama::accept_open_channel_call(para_a_id);
let beneficiary = Kusama::sovereign_account_id_of_child_para(para_b_id);
xcm = xcm_transact_paid_execution(call, origin_kind, native_asset, beneficiary);
PenpalKusamaB::execute_with(|| {
assert_ok!(<PenpalKusamaB as PenpalKusamaBPallet>::PolkadotXcm::send(
para_b_root_origin,
bx!(relay_destination),
bx!(xcm),
));
PenpalKusamaB::assert_xcm_pallet_sent();
});
PenpalKusamaB::execute_with(|| {});
Kusama::execute_with(|| {
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
Kusama::assert_ump_queue_processed(
true,
Some(para_b_id),
Some(Weight::from_parts(1_312_558_000, 200_000)),
);
assert_expected_events!(
Kusama,
vec![
// Parachain's Sovereign account balance is withdrawn to pay XCM fees
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == para_b_sovereign_account.clone(),
amount: *amount == fee_amount,
},
// Sender deposit is reserved for Parachain's Sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Reserved { who, .. }) =>{
who: *who == para_b_sovereign_account,
},
// Open channel accepted for Para A to Para B
RuntimeEvent::Hrmp(
polkadot_runtime_parachains::hrmp::Event::OpenChannelAccepted {
sender, recipient
}
) => {
sender: *sender == para_a_id.into(),
recipient: *recipient == para_b_id.into(),
},
]
);
});
Kusama::force_process_hrmp_open(para_a_id, para_b_id);
}
/// Opening HRMP channels between System Parachains and Parachains should work
#[test]
fn force_open_hrmp_channel_for_system_para_works() {
// Relay Chain init values
let relay_root_origin = <Kusama as Chain>::RuntimeOrigin::root();
// System Para init values
let system_para_id = AssetHubKusama::para_id();
// Parachain A init values
let para_a_id = PenpalKusamaA::para_id();
Kusama::execute_with(|| {
assert_ok!(<Kusama as KusamaPallet>::Hrmp::force_open_hrmp_channel(
relay_root_origin,
system_para_id,
para_a_id,
MAX_CAPACITY,
MAX_MESSAGE_SIZE
));
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
assert_expected_events!(
Kusama,
vec![
// HRMP channel forced opened
RuntimeEvent::Hrmp(
polkadot_runtime_parachains::hrmp::Event::HrmpChannelForceOpened{
sender,
recipient,
proposed_max_capacity: max_capacity,
proposed_max_message_size: max_message_size
}
) => {
sender: *sender == system_para_id.into(),
recipient: *recipient == para_a_id.into(),
max_capacity: *max_capacity == MAX_CAPACITY,
max_message_size: *max_message_size == MAX_MESSAGE_SIZE,
},
]
);
});
Kusama::force_process_hrmp_open(system_para_id, para_a_id);
}
@@ -1,21 +0,0 @@
// 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.
mod hrmp_channels;
mod reserve_transfer;
mod send;
mod set_xcm_versions;
mod swap;
mod teleport;
@@ -1,414 +0,0 @@
// 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 relay_origin_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
Kusama::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(630_092_000, 6_196)));
assert_expected_events!(
Kusama,
vec![
// Amount to reserve transfer is transferred to System Parachain's Sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Transfer { from, to, amount }) => {
from: *from == t.sender.account_id,
to: *to == Kusama::sovereign_account_id_of(
t.args.dest
),
amount: *amount == t.args.amount,
},
]
);
}
fn system_para_dest_assertions_incomplete(_t: RelayToSystemParaTest) {
AssetHubKusama::assert_dmp_queue_incomplete(
Some(Weight::from_parts(1_000_000_000, 0)),
Some(Error::UntrustedReserveLocation),
);
}
fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) {
AssetHubKusama::assert_xcm_pallet_attempted_error(Some(XcmError::Barrier))
}
fn system_para_to_para_assertions(t: SystemParaToParaTest) {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
630_092_000,
6_196,
)));
assert_expected_events!(
AssetHubKusama,
vec![
// Amount to reserve transfer is transferred to Parachain's Sovereing account
RuntimeEvent::Balances(
pallet_balances::Event::Transfer { from, to, amount }
) => {
from: *from == t.sender.account_id,
to: *to == AssetHubKusama::sovereign_account_id_of(
t.args.dest
),
amount: *amount == t.args.amount,
},
]
);
}
fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
676_119_000,
6196,
)));
assert_expected_events!(
AssetHubKusama,
vec![
// Amount to reserve transfer is transferred to Parachain's Sovereing account
RuntimeEvent::Assets(
pallet_assets::Event::Transferred { asset_id, from, to, amount }
) => {
asset_id: *asset_id == ASSET_ID,
from: *from == t.sender.account_id,
to: *to == AssetHubKusama::sovereign_account_id_of(
t.args.dest
),
amount: *amount == t.args.amount,
},
]
);
}
fn relay_limited_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Kusama as KusamaPallet>::XcmPallet::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn relay_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Kusama as KusamaPallet>::XcmPallet::reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
fn system_para_limited_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn system_para_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
<AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
<AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
/// Limited Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't
/// work
#[test]
fn limited_reserve_transfer_native_asset_from_relay_to_system_para_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = KUSAMA_ED * 1000;
let test_args = TestContext {
sender: KusamaSender::get(),
receiver: AssetHubKusamaReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Kusama>(relay_origin_assertions);
test.set_assertion::<AssetHubKusama>(system_para_dest_assertions_incomplete);
test.set_dispatchable::<Kusama>(relay_limited_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Limited Reserve Transfers of native asset from System Parachain to Relay Chain shoudln't work
#[test]
fn limited_reserve_transfer_native_asset_from_system_para_to_relay_fails() {
// Init values for System Parachain
let destination = AssetHubKusama::parent_location();
let beneficiary_id = KusamaReceiver::get();
let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: KusamaReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubKusama>(system_para_to_relay_assertions);
test.set_dispatchable::<AssetHubKusama>(system_para_limited_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
#[test]
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = KUSAMA_ED * 1000;
let test_args = TestContext {
sender: KusamaSender::get(),
receiver: AssetHubKusamaReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Kusama>(relay_origin_assertions);
test.set_assertion::<AssetHubKusama>(system_para_dest_assertions_incomplete);
test.set_dispatchable::<Kusama>(relay_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Reserve Transfers of native asset from System Parachain to Relay Chain shouldn't work
#[test]
fn reserve_transfer_native_asset_from_system_para_to_relay_fails() {
// Init values for System Parachain
let destination = AssetHubKusama::parent_location();
let beneficiary_id = KusamaReceiver::get();
let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: KusamaReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubKusama>(system_para_to_relay_assertions);
test.set_dispatchable::<AssetHubKusama>(system_para_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Limited Reserve Transfers of native asset from System Parachain to Parachain should work
#[test]
fn limited_reserve_transfer_native_asset_from_system_para_to_para() {
// Init values for System Parachain
let destination = AssetHubKusama::sibling_location_of(PenpalKusamaA::para_id());
let beneficiary_id = PenpalKusamaAReceiver::get();
let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: PenpalKusamaAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
test.set_assertion::<AssetHubKusama>(system_para_to_para_assertions);
// TODO: Add assertion for Penpal runtime. Right now message is failing with
// `UntrustedReserveLocation`
test.set_dispatchable::<AssetHubKusama>(system_para_to_para_limited_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
// transfers
}
/// Reserve Transfers of native asset from System Parachain to Parachain should work
#[test]
fn reserve_transfer_native_asset_from_system_para_to_para() {
// Init values for System Parachain
let destination = AssetHubKusama::sibling_location_of(PenpalKusamaA::para_id());
let beneficiary_id = PenpalKusamaAReceiver::get();
let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: PenpalKusamaAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
test.set_assertion::<AssetHubKusama>(system_para_to_para_assertions);
// TODO: Add assertion for Penpal runtime. Right now message is failing with
// `UntrustedReserveLocation`
test.set_dispatchable::<AssetHubKusama>(system_para_to_para_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
// transfers
}
/// Limited Reserve Transfers of a local asset from System Parachain to Parachain should work
#[test]
fn limited_reserve_transfer_asset_from_system_para_to_para() {
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
AssetHubKusama::force_create_and_mint_asset(
ASSET_ID,
ASSET_MIN_BALANCE,
true,
AssetHubKusamaSender::get(),
ASSET_MIN_BALANCE * 1000000,
);
// Init values for System Parachain
let destination = AssetHubKusama::sibling_location_of(PenpalKusamaA::para_id());
let beneficiary_id = PenpalKusamaAReceiver::get();
let amount_to_send = ASSET_MIN_BALANCE * 1000;
let assets =
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
.into();
let system_para_test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: PenpalKusamaAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
system_para_test.set_assertion::<AssetHubKusama>(system_para_to_para_assets_assertions);
// TODO: Add assertions when Penpal is able to manage assets
system_para_test
.set_dispatchable::<AssetHubKusama>(system_para_to_para_limited_reserve_transfer_assets);
system_para_test.assert();
}
/// Reserve Transfers of a local asset from System Parachain to Parachain should work
#[test]
fn reserve_transfer_asset_from_system_para_to_para() {
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
AssetHubKusama::force_create_and_mint_asset(
ASSET_ID,
ASSET_MIN_BALANCE,
true,
AssetHubKusamaSender::get(),
ASSET_MIN_BALANCE * 1000000,
);
// Init values for System Parachain
let destination = AssetHubKusama::sibling_location_of(PenpalKusamaA::para_id());
let beneficiary_id = PenpalKusamaAReceiver::get();
let amount_to_send = ASSET_MIN_BALANCE * 1000;
let assets =
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
.into();
let system_para_test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: PenpalKusamaAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
system_para_test.set_assertion::<AssetHubKusama>(system_para_to_para_assets_assertions);
// TODO: Add assertions when Penpal is able to manage assets
system_para_test
.set_dispatchable::<AssetHubKusama>(system_para_to_para_reserve_transfer_assets);
system_para_test.assert();
}
@@ -1,195 +0,0 @@
// 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::*;
/// Relay Chain should be able to execute `Transact` instructions in System Parachain
/// when `OriginKind::Superuser` and signer is `sudo`
#[test]
fn send_transact_sudo_from_relay_to_system_para_works() {
// Init tests variables
let root_origin = <Kusama as Chain>::RuntimeOrigin::root();
let system_para_destination = Kusama::child_location_of(AssetHubKusama::para_id()).into();
let asset_owner: AccountId = AssetHubKusamaSender::get().into();
let xcm = AssetHubKusama::force_create_asset_xcm(
OriginKind::Superuser,
ASSET_ID,
asset_owner.clone(),
true,
1000,
);
// Send XCM message from Relay Chain
Kusama::execute_with(|| {
assert_ok!(<Kusama as KusamaPallet>::XcmPallet::send(
root_origin,
bx!(system_para_destination),
bx!(xcm),
));
Kusama::assert_xcm_pallet_sent();
});
// Receive XCM message in Assets Parachain
AssetHubKusama::execute_with(|| {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_dmp_queue_complete(Some(Weight::from_parts(1_019_445_000, 200_000)));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::Assets(pallet_assets::Event::ForceCreated { asset_id, owner }) => {
asset_id: *asset_id == ASSET_ID,
owner: *owner == asset_owner,
},
]
);
assert!(<AssetHubKusama as AssetHubKusamaPallet>::Assets::asset_exists(ASSET_ID));
});
}
/// Relay Chain shouldn't be able to execute `Transact` instructions in System Parachain
/// when `OriginKind::Native`
#[test]
fn send_transact_native_from_relay_to_system_para_fails() {
// Init tests variables
let signed_origin = <Kusama as Chain>::RuntimeOrigin::signed(KusamaSender::get().into());
let system_para_destination = Kusama::child_location_of(AssetHubKusama::para_id()).into();
let asset_owner = AssetHubKusamaSender::get().into();
let xcm = AssetHubKusama::force_create_asset_xcm(
OriginKind::Native,
ASSET_ID,
asset_owner,
true,
1000,
);
// Send XCM message from Relay Chain
Kusama::execute_with(|| {
assert_err!(
<Kusama as KusamaPallet>::XcmPallet::send(
signed_origin,
bx!(system_para_destination),
bx!(xcm)
),
DispatchError::BadOrigin
);
});
}
/// System Parachain shouldn't be able to execute `Transact` instructions in Relay Chain
/// when `OriginKind::Native`
#[test]
fn send_transact_native_from_system_para_to_relay_fails() {
// Init tests variables
let signed_origin =
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get().into());
let relay_destination = AssetHubKusama::parent_location().into();
let call = <Kusama as Chain>::RuntimeCall::System(frame_system::Call::<
<Kusama as Chain>::Runtime,
>::remark_with_event {
remark: vec![0, 1, 2, 3],
})
.encode()
.into();
let origin_kind = OriginKind::Native;
let xcm = xcm_transact_unpaid_execution(call, origin_kind);
// Send XCM message from Relay Chain
AssetHubKusama::execute_with(|| {
assert_err!(
<AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::send(
signed_origin,
bx!(relay_destination),
bx!(xcm)
),
DispatchError::BadOrigin
);
});
}
/// Parachain should be able to send XCM paying its fee with sufficient asset
/// in the System Parachain
#[test]
fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
let para_sovereign_account = AssetHubKusama::sovereign_account_id_of(
AssetHubKusama::sibling_location_of(PenpalKusamaA::para_id()),
);
// Force create and mint assets for Parachain's sovereign account
AssetHubKusama::force_create_and_mint_asset(
ASSET_ID,
ASSET_MIN_BALANCE,
true,
para_sovereign_account.clone(),
ASSET_MIN_BALANCE * 1000000000,
);
// We just need a call that can pass the `SafeCallFilter`
// Call values are not relevant
let call = AssetHubKusama::force_create_asset_call(
ASSET_ID,
para_sovereign_account.clone(),
true,
ASSET_MIN_BALANCE,
);
let origin_kind = OriginKind::SovereignAccount;
let fee_amount = ASSET_MIN_BALANCE * 1000000;
let native_asset =
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount).into();
let root_origin = <PenpalKusamaA as Chain>::RuntimeOrigin::root();
let system_para_destination =
PenpalKusamaA::sibling_location_of(AssetHubKusama::para_id()).into();
let xcm = xcm_transact_paid_execution(
call,
origin_kind,
native_asset,
para_sovereign_account.clone(),
);
PenpalKusamaA::execute_with(|| {
assert_ok!(<PenpalKusamaA as PenpalKusamaAPallet>::PolkadotXcm::send(
root_origin,
bx!(system_para_destination),
bx!(xcm),
));
PenpalKusamaA::assert_xcm_pallet_sent();
});
AssetHubKusama::execute_with(|| {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_xcmp_queue_success(Some(Weight::from_parts(2_176_414_000, 203_593)));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
asset_id: *asset_id == ASSET_ID,
owner: *owner == para_sovereign_account,
balance: *balance == fee_amount,
},
RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => {
asset_id: *asset_id == ASSET_ID,
},
]
);
});
}
@@ -1,93 +0,0 @@
// 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::*;
#[test]
fn relay_sets_system_para_xcm_supported_version() {
// Init tests variables
let sudo_origin = <Kusama as Chain>::RuntimeOrigin::root();
let system_para_destination: MultiLocation =
Kusama::child_location_of(AssetHubKusama::para_id());
// Relay Chain sets supported version for Asset Parachain
Kusama::execute_with(|| {
assert_ok!(<Kusama as KusamaPallet>::XcmPallet::force_xcm_version(
sudo_origin,
bx!(system_para_destination),
XCM_V3
));
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
assert_expected_events!(
Kusama,
vec![
RuntimeEvent::XcmPallet(pallet_xcm::Event::SupportedVersionChanged {
location,
version: XCM_V3
}) => { location: *location == system_para_destination, },
]
);
});
}
#[test]
fn system_para_sets_relay_xcm_supported_version() {
// Init test variables
let sudo_origin = <Kusama as Chain>::RuntimeOrigin::root();
let parent_location = AssetHubKusama::parent_location();
let system_para_destination: VersionedMultiLocation =
Kusama::child_location_of(AssetHubKusama::para_id()).into();
let call = <AssetHubKusama as Chain>::RuntimeCall::PolkadotXcm(pallet_xcm::Call::<
<AssetHubKusama as Chain>::Runtime,
>::force_xcm_version {
location: bx!(parent_location),
version: XCM_V3,
})
.encode()
.into();
let origin_kind = OriginKind::Superuser;
let xcm = xcm_transact_unpaid_execution(call, origin_kind);
// System Parachain sets supported version for Relay Chain throught it
Kusama::execute_with(|| {
assert_ok!(<Kusama as KusamaPallet>::XcmPallet::send(
sudo_origin,
bx!(system_para_destination),
bx!(xcm),
));
Kusama::assert_xcm_pallet_sent();
});
// System Parachain receive the XCM message
AssetHubKusama::execute_with(|| {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_dmp_queue_complete(Some(Weight::from_parts(1_019_210_000, 200_000)));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::PolkadotXcm(pallet_xcm::Event::SupportedVersionChanged {
location,
version: XCM_V3
}) => { location: *location == parent_location, },
]
);
});
}
@@ -1,364 +0,0 @@
// 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::*;
use frame_support::{instances::Instance2, BoundedVec};
use parachains_common::kusama::currency::EXISTENTIAL_DEPOSIT;
use sp_runtime::{DispatchError, ModuleError};
#[test]
fn swap_locally_on_chain_using_local_assets() {
let asset_native = Box::new(asset_hub_kusama_runtime::xcm_config::KsmLocation::get());
let asset_one = Box::new(MultiLocation {
parents: 0,
interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())),
});
AssetHubKusama::execute_with(|| {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::Assets::create(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
ASSET_ID.into(),
AssetHubKusamaSender::get().into(),
1000,
));
assert!(<AssetHubKusama as AssetHubKusamaPallet>::Assets::asset_exists(ASSET_ID));
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::Assets::mint(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
ASSET_ID.into(),
AssetHubKusamaSender::get().into(),
100_000_000_000_000,
));
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::Balances::force_set_balance(
<AssetHubKusama as Chain>::RuntimeOrigin::root(),
AssetHubKusamaSender::get().into(),
100_000_000_000_000,
));
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::create_pool(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
asset_native.clone(),
asset_one.clone(),
));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {},
]
);
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::add_liquidity(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
asset_native.clone(),
asset_one.clone(),
1_000_000_000_000,
2_000_000_000_000,
0,
0,
AssetHubKusamaSender::get().into()
));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, },
]
);
let path = BoundedVec::<_, _>::truncate_from(vec![asset_native.clone(), asset_one.clone()]);
assert_ok!(
<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::swap_exact_tokens_for_tokens(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
path,
100,
1,
AssetHubKusamaSender::get().into(),
true
)
);
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. }) => {
amount_in: *amount_in == 100,
amount_out: *amount_out == 199,
},
]
);
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::remove_liquidity(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
asset_native,
asset_one,
1414213562273 - EXISTENTIAL_DEPOSIT * 2, // all but the 2 EDs can't be retrieved.
0,
0,
AssetHubKusamaSender::get().into(),
));
});
}
#[test]
fn swap_locally_on_chain_using_foreign_assets() {
use frame_support::weights::WeightToFee;
let asset_native = Box::new(asset_hub_kusama_runtime::xcm_config::KsmLocation::get());
let foreign_asset1_at_asset_hub_kusama = Box::new(MultiLocation {
parents: 1,
interior: X3(
Parachain(PenpalKusamaA::para_id().into()),
PalletInstance(ASSETS_PALLET_ID),
GeneralIndex(ASSET_ID.into()),
),
});
let assets_para_destination: VersionedMultiLocation =
MultiLocation { parents: 1, interior: X1(Parachain(AssetHubKusama::para_id().into())) }
.into();
let penpal_location =
MultiLocation { parents: 1, interior: X1(Parachain(PenpalKusamaA::para_id().into())) };
// 1. Create asset on penpal:
PenpalKusamaA::execute_with(|| {
assert_ok!(<PenpalKusamaA as PenpalKusamaAPallet>::Assets::create(
<PenpalKusamaA as Chain>::RuntimeOrigin::signed(PenpalKusamaASender::get()),
ASSET_ID.into(),
PenpalKusamaASender::get().into(),
1000,
));
assert!(<PenpalKusamaA as PenpalKusamaAPallet>::Assets::asset_exists(ASSET_ID));
});
// 2. Create foreign asset on asset_hub_kusama:
let require_weight_at_most = Weight::from_parts(1_100_000_000_000, 30_000);
let origin_kind = OriginKind::Xcm;
let sov_penpal_on_asset_hub_kusama = AssetHubKusama::sovereign_account_id_of(penpal_location);
AssetHubKusama::fund_accounts(vec![
(AssetHubKusamaSender::get().into(), 5_000_000 * KUSAMA_ED), /* An account to swap dot
* for something else. */
(sov_penpal_on_asset_hub_kusama.clone().into(), 1000_000_000_000_000_000 * KUSAMA_ED),
]);
let sov_penpal_on_asset_hub_kusama_as_location: MultiLocation = MultiLocation {
parents: 0,
interior: X1(AccountId32Junction {
network: None,
id: sov_penpal_on_asset_hub_kusama.clone().into(),
}),
};
let call_foreign_assets_create =
<AssetHubKusama as Chain>::RuntimeCall::ForeignAssets(pallet_assets::Call::<
<AssetHubKusama as Chain>::Runtime,
Instance2,
>::create {
id: *foreign_asset1_at_asset_hub_kusama,
min_balance: 1000,
admin: sov_penpal_on_asset_hub_kusama.clone().into(),
})
.encode()
.into();
let buy_execution_fee_amount = parachains_common::kusama::fee::WeightToFee::weight_to_fee(
&Weight::from_parts(10_100_000_000_000, 300_000),
);
let buy_execution_fee = MultiAsset {
id: Concrete(MultiLocation { parents: 1, interior: Here }),
fun: Fungible(buy_execution_fee_amount),
};
let xcm = VersionedXcm::from(Xcm(vec![
WithdrawAsset { 0: vec![buy_execution_fee.clone()].into() },
BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited },
Transact { require_weight_at_most, origin_kind, call: call_foreign_assets_create },
RefundSurplus,
DepositAsset {
assets: All.into(),
beneficiary: sov_penpal_on_asset_hub_kusama_as_location,
},
]));
// Send XCM message from penpal => asset_hub_kusama
let sudo_penpal_origin = <PenpalKusamaA as Chain>::RuntimeOrigin::root();
PenpalKusamaA::execute_with(|| {
assert_ok!(<PenpalKusamaA as PenpalKusamaAPallet>::PolkadotXcm::send(
sudo_penpal_origin.clone(),
bx!(assets_para_destination.clone()),
bx!(xcm),
));
type RuntimeEvent = <PenpalKusamaA as Chain>::RuntimeEvent;
assert_expected_events!(
PenpalKusamaA,
vec![
RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {},
]
);
});
// Receive XCM message in Assets Parachain
AssetHubKusama::execute_with(|| {
assert!(<AssetHubKusama as AssetHubKusamaPallet>::ForeignAssets::asset_exists(
*foreign_asset1_at_asset_hub_kusama
));
// 3: Mint foreign asset on asset_hub_kusama:
//
// (While it might be nice to use batch,
// currently that's disabled due to safe call filters.)
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
// 3. Mint foreign asset (in reality this should be a teleport or some such)
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::ForeignAssets::mint(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(
sov_penpal_on_asset_hub_kusama.clone().into()
),
*foreign_asset1_at_asset_hub_kusama,
sov_penpal_on_asset_hub_kusama.clone().into(),
3_000_000_000_000,
));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
]
);
// 4. Create pool:
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::create_pool(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
asset_native.clone(),
foreign_asset1_at_asset_hub_kusama.clone(),
));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {},
]
);
// 5. Add liquidity:
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::add_liquidity(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(
sov_penpal_on_asset_hub_kusama.clone()
),
asset_native.clone(),
foreign_asset1_at_asset_hub_kusama.clone(),
1_000_000_000_000,
2_000_000_000_000,
0,
0,
sov_penpal_on_asset_hub_kusama.clone().into()
));
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => {
lp_token_minted: *lp_token_minted == 1414213562273,
},
]
);
// 6. Swap!
let path = BoundedVec::<_, _>::truncate_from(vec![
asset_native.clone(),
foreign_asset1_at_asset_hub_kusama.clone(),
]);
assert_ok!(
<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::swap_exact_tokens_for_tokens(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
path,
100000,
1000,
AssetHubKusamaSender::get().into(),
true
)
);
assert_expected_events!(
AssetHubKusama,
vec![
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. },) => {
amount_in: *amount_in == 100000,
amount_out: *amount_out == 199399,
},
]
);
// 7. Remove liquidity
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::remove_liquidity(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(
sov_penpal_on_asset_hub_kusama.clone()
),
asset_native,
foreign_asset1_at_asset_hub_kusama,
1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved.
0,
0,
sov_penpal_on_asset_hub_kusama.clone().into(),
));
});
}
#[test]
fn cannot_create_pool_from_pool_assets() {
let asset_native = Box::new(asset_hub_kusama_runtime::xcm_config::KsmLocation::get());
let mut asset_one = asset_hub_kusama_runtime::xcm_config::PoolAssetsPalletLocation::get();
asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets");
AssetHubKusama::execute_with(|| {
let pool_owner_account_id = asset_hub_kusama_runtime::AssetConversionOrigin::get();
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::PoolAssets::create(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(pool_owner_account_id.clone()),
ASSET_ID.into(),
pool_owner_account_id.clone().into(),
1000,
));
assert!(<AssetHubKusama as AssetHubKusamaPallet>::PoolAssets::asset_exists(ASSET_ID));
assert_ok!(<AssetHubKusama as AssetHubKusamaPallet>::PoolAssets::mint(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(pool_owner_account_id),
ASSET_ID.into(),
AssetHubKusamaSender::get().into(),
3_000_000_000_000,
));
assert_matches::assert_matches!(
<AssetHubKusama as AssetHubKusamaPallet>::AssetConversion::create_pool(
<AssetHubKusama as Chain>::RuntimeOrigin::signed(AssetHubKusamaSender::get()),
asset_native.clone(),
Box::new(asset_one),
),
Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("UnsupportedAsset"))
);
});
}
@@ -1,363 +0,0 @@
// 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.
#![allow(dead_code)] // <https://github.com/paritytech/cumulus/issues/3027>
use crate::*;
fn relay_origin_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
Kusama::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(631_531_000, 7_186)));
assert_expected_events!(
Kusama,
vec![
// Amount to teleport is withdrawn from Sender
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == t.sender.account_id,
amount: *amount == t.args.amount,
},
// Amount to teleport is deposited in Relay's `CheckAccount`
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, amount }) => {
who: *who == <Kusama as KusamaPallet>::XcmPallet::check_account(),
amount: *amount == t.args.amount,
},
]
);
}
fn relay_dest_assertions(t: SystemParaToRelayTest) {
type RuntimeEvent = <Kusama as Chain>::RuntimeEvent;
Kusama::assert_ump_queue_processed(
true,
Some(AssetHubKusama::para_id()),
Some(Weight::from_parts(307_225_000, 7_186)),
);
assert_expected_events!(
Kusama,
vec![
// Amount is witdrawn from Relay Chain's `CheckAccount`
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == <Kusama as KusamaPallet>::XcmPallet::check_account(),
amount: *amount == t.args.amount,
},
// Amount minus fees are deposited in Receiver's account
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => {
who: *who == t.receiver.account_id,
},
]
);
}
fn relay_dest_assertions_fail(_t: SystemParaToRelayTest) {
Kusama::assert_ump_queue_processed(
false,
Some(AssetHubKusama::para_id()),
Some(Weight::from_parts(148_433_000, 3_593)),
);
}
fn para_origin_assertions(t: SystemParaToRelayTest) {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
534_872_000,
7_133,
)));
AssetHubKusama::assert_parachain_system_ump_sent();
assert_expected_events!(
AssetHubKusama,
vec![
// Amount is withdrawn from Sender's account
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == t.sender.account_id,
amount: *amount == t.args.amount,
},
]
);
}
fn para_dest_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <AssetHubKusama as Chain>::RuntimeEvent;
AssetHubKusama::assert_dmp_queue_complete(Some(Weight::from_parts(165_592_000, 0)));
assert_expected_events!(
AssetHubKusama,
vec![
// Amount minus fees are deposited in Receiver's account
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => {
who: *who == t.receiver.account_id,
},
]
);
}
fn relay_limited_teleport_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Kusama as KusamaPallet>::XcmPallet::limited_teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn relay_teleport_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Kusama as KusamaPallet>::XcmPallet::teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
fn system_para_limited_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::limited_teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
// TODO: Uncomment when https://github.com/paritytech/polkadot/pull/7424 is merged
// fn system_para_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
// <AssetHubKusama as AssetHubKusamaPallet>::PolkadotXcm::teleport_assets(
// t.signed_origin,
// bx!(t.args.dest),
// bx!(t.args.beneficiary),
// bx!(t.args.assets),
// t.args.fee_asset_item,
// )
// }
/// Limited Teleport of native asset from Relay Chain to the System Parachain should work
#[test]
fn limited_teleport_native_assets_from_relay_to_system_para_works() {
// Init values for Relay Chain
let amount_to_send: Balance = KUSAMA_ED * 1000;
let test_args = TestContext {
sender: KusamaSender::get(),
receiver: AssetHubKusamaReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Kusama>(relay_origin_assertions);
test.set_assertion::<AssetHubKusama>(para_dest_assertions);
test.set_dispatchable::<Kusama>(relay_limited_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}
/// Limited Teleport of native asset from System Parachain to Relay Chain
/// should work when there is enough balance in Relay Chain's `CheckAccount`
#[test]
fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
// Dependency - Relay Chain's `CheckAccount` should have enough balance
limited_teleport_native_assets_from_relay_to_system_para_works();
// Init values for Relay Chain
let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
let destination = AssetHubKusama::parent_location();
let beneficiary_id = KusamaReceiver::get();
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: KusamaReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubKusama>(para_origin_assertions);
test.set_assertion::<Kusama>(relay_dest_assertions);
test.set_dispatchable::<AssetHubKusama>(system_para_limited_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}
/// Limited Teleport of native asset from System Parachain to Relay Chain
/// should't work when there is not enough balance in Relay Chain's `CheckAccount`
#[test]
fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
let destination = AssetHubKusama::parent_location().into();
let beneficiary_id = KusamaReceiver::get().into();
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubKusamaSender::get(),
receiver: KusamaReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubKusama>(para_origin_assertions);
test.set_assertion::<Kusama>(relay_dest_assertions_fail);
test.set_dispatchable::<AssetHubKusama>(system_para_limited_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance does not change
assert_eq!(receiver_balance_after, receiver_balance_before);
}
/// Teleport of native asset from Relay Chain to the System Parachain should work
#[test]
fn teleport_native_assets_from_relay_to_system_para_works() {
// Init values for Relay Chain
let amount_to_send: Balance = KUSAMA_ED * 1000;
let test_args = TestContext {
sender: KusamaSender::get(),
receiver: AssetHubKusamaReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Kusama>(relay_origin_assertions);
test.set_assertion::<AssetHubKusama>(para_dest_assertions);
test.set_dispatchable::<Kusama>(relay_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}
// TODO: Uncomment when https://github.com/paritytech/polkadot/pull/7424 is merged
// Right now it is failing in the Relay Chain with a
// `messageQueue.ProcessingFailed` event `error: Unsupported`.
// The reason is the `Weigher` in `pallet_xcm` is not properly calculating the `remote_weight`
// and it cause an `Overweight` error in `AllowTopLevelPaidExecutionFrom` barrier
// /// Teleport of native asset from System Parachains to the Relay Chain
// /// should work when there is enough balance in Relay Chain's `CheckAccount`
// #[test]
// fn teleport_native_assets_back_from_system_para_to_relay_works() {
// // Dependency - Relay Chain's `CheckAccount` should have enough balance
// teleport_native_assets_from_relay_to_system_para_works();
// // Init values for Relay Chain
// let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
// let test_args = TestContext {
// sender: AssetHubKusamaSender::get(),
// receiver: KusamaReceiver::get(),
// args: get_para_dispatch_args(amount_to_send),
// };
// let mut test = SystemParaToRelayTest::new(test_args);
// let sender_balance_before = test.sender.balance;
// let receiver_balance_before = test.receiver.balance;
// test.set_assertion::<AssetHubKusama>(para_origin_assertions);
// test.set_assertion::<Kusama>(relay_dest_assertions);
// test.set_dispatchable::<AssetHubKusama>(system_para_teleport_assets);
// test.assert();
// let sender_balance_after = test.sender.balance;
// let receiver_balance_after = test.receiver.balance;
// // Sender's balance is reduced
// assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// // Receiver's balance is increased
// assert!(receiver_balance_after > receiver_balance_before);
// }
// /// Teleport of native asset from System Parachain to Relay Chain
// /// shouldn't work when there is not enough balance in Relay Chain's `CheckAccount`
// #[test]
// fn teleport_native_assets_from_system_para_to_relay_fails() {
// // Init values for Relay Chain
// let amount_to_send: Balance = ASSET_HUB_KUSAMA_ED * 1000;
// let assets = (Parent, amount_to_send).into();
//
// let test_args = TestContext {
// sender: AssetHubKusamaSender::get(),
// receiver: KusamaReceiver::get(),
// args: system_para_test_args(amount_to_send),
// assets,
// None
// };
// let mut test = SystemParaToRelayTest::new(test_args);
// let sender_balance_before = test.sender.balance;
// let receiver_balance_before = test.receiver.balance;
// test.set_assertion::<AssetHubKusama>(para_origin_assertions);
// test.set_assertion::<Kusama>(relay_dest_assertions);
// test.set_dispatchable::<AssetHubKusama>(system_para_teleport_assets);
// test.assert();
// let sender_balance_after = test.sender.balance;
// let receiver_balance_after = test.receiver.balance;
// // Sender's balance is reduced
// assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// // Receiver's balance does not change
// assert_eq!(receiver_balance_after, receiver_balance_before);
// }
@@ -1,52 +0,0 @@
[package]
name = "asset-hub-polkadot-integration-tests"
version = "1.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
description = "Asset Hub Polkadot runtime integration tests with xcm-emulator"
publish = false
[dependencies]
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
# Substrate
sp-runtime = { path = "../../../../../../substrate/primitives/runtime", default-features = false}
frame-support = { path = "../../../../../../substrate/frame/support", default-features = false}
frame-system = { path = "../../../../../../substrate/frame/system", default-features = false}
pallet-balances = { path = "../../../../../../substrate/frame/balances", default-features = false}
pallet-assets = { path = "../../../../../../substrate/frame/assets", default-features = false}
pallet-asset-conversion = { path = "../../../../../../substrate/frame/asset-conversion", default-features = false}
# Polkadot
polkadot-core-primitives = { path = "../../../../../../polkadot/core-primitives", default-features = false}
polkadot-parachain-primitives = { path = "../../../../../../polkadot/parachain", default-features = false}
polkadot-runtime-parachains = { path = "../../../../../../polkadot/runtime/parachains" }
polkadot-runtime = { path = "../../../../../../polkadot/runtime/polkadot" }
xcm = { package = "staging-xcm", path = "../../../../../../polkadot/xcm", default-features = false}
pallet-xcm = { path = "../../../../../../polkadot/xcm/pallet-xcm", default-features = false}
# Cumulus
parachains-common = { path = "../../../../common" }
asset-hub-kusama-runtime = { path = "../../../../runtimes/assets/asset-hub-kusama" }
# Local
xcm-emulator = { path = "../../../../../xcm/xcm-emulator", default-features = false}
integration-tests-common = { path = "../../common", default-features = false}
[features]
runtime-benchmarks = [
"asset-hub-kusama-runtime/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"integration-tests-common/runtime-benchmarks",
"pallet-asset-conversion/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
"parachains-common/runtime-benchmarks",
"polkadot-parachain-primitives/runtime-benchmarks",
"polkadot-runtime-parachains/runtime-benchmarks",
"polkadot-runtime/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
@@ -1,90 +0,0 @@
// 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.
pub use codec::Encode;
pub use frame_support::{
assert_err, assert_ok,
pallet_prelude::Weight,
sp_runtime::{AccountId32, DispatchError, DispatchResult},
traits::fungibles::Inspect,
};
pub use integration_tests_common::{
constants::{
asset_hub_polkadot::ED as ASSET_HUB_POLKADOT_ED, polkadot::ED as POLKADOT_ED,
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
},
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
AssetHubPolkadot, AssetHubPolkadotPallet, AssetHubPolkadotReceiver, AssetHubPolkadotSender,
PenpalPolkadotA, PenpalPolkadotAPallet, PenpalPolkadotAReceiver, PenpalPolkadotB,
PenpalPolkadotBPallet, Polkadot, PolkadotPallet, PolkadotReceiver, PolkadotSender,
};
pub use parachains_common::{AccountId, Balance};
pub use xcm::{
prelude::{AccountId32 as AccountId32Junction, *},
v3::{Error, NetworkId::Polkadot as PolkadotId},
};
pub use xcm_emulator::{
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
};
pub const ASSET_ID: u32 = 1;
pub const ASSET_MIN_BALANCE: u128 = 1000;
// `Assets` pallet index
pub const ASSETS_PALLET_ID: u8 = 50;
pub type RelayToSystemParaTest = Test<Polkadot, AssetHubPolkadot>;
pub type SystemParaToRelayTest = Test<AssetHubPolkadot, Polkadot>;
pub type SystemParaToParaTest = Test<AssetHubPolkadot, PenpalPolkadotA>;
/// Returns a `TestArgs` instance to de used for the Relay Chain accross integraton tests
pub fn relay_test_args(amount: Balance) -> TestArgs {
TestArgs {
dest: Polkadot::child_location_of(AssetHubPolkadot::para_id()),
beneficiary: AccountId32Junction {
network: None,
id: AssetHubPolkadotReceiver::get().into(),
}
.into(),
amount,
assets: (Here, amount).into(),
asset_id: None,
fee_asset_item: 0,
weight_limit: WeightLimit::Unlimited,
}
}
/// Returns a `TestArgs` instance to de used for the System Parachain accross integraton tests
pub fn system_para_test_args(
dest: MultiLocation,
beneficiary_id: AccountId32,
amount: Balance,
assets: MultiAssets,
asset_id: Option<u32>,
) -> TestArgs {
TestArgs {
dest,
beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(),
amount,
assets,
asset_id,
fee_asset_item: 0,
weight_limit: WeightLimit::Unlimited,
}
}
#[cfg(test)]
#[cfg(not(feature = "runtime-benchmarks"))]
mod tests;
@@ -1,192 +0,0 @@
// 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::*;
const MAX_CAPACITY: u32 = 8;
const MAX_MESSAGE_SIZE: u32 = 8192;
/// Opening HRMP channels between Parachains should work
#[test]
fn open_hrmp_channel_between_paras_works() {
// Parchain A init values
let para_a_id = PenpalPolkadotA::para_id();
let para_a_root_origin = <PenpalPolkadotA as Chain>::RuntimeOrigin::root();
// Parachain B init values
let para_b_id = PenpalPolkadotB::para_id();
let para_b_root_origin = <PenpalPolkadotB as Chain>::RuntimeOrigin::root();
let fee_amount = POLKADOT_ED * 1000;
let fund_amount = POLKADOT_ED * 1000_000_000;
// Fund Parachain's Sovereign accounts to be able to reserve the deposit
let para_a_sovereign_account = Polkadot::fund_para_sovereign(fund_amount, para_a_id);
let para_b_sovereign_account = Polkadot::fund_para_sovereign(fund_amount, para_b_id);
let relay_destination: VersionedMultiLocation = PenpalPolkadotA::parent_location().into();
// ---- Init Open channel from Parachain to System Parachain
let mut call = Polkadot::init_open_channel_call(para_b_id, MAX_CAPACITY, MAX_MESSAGE_SIZE);
let origin_kind = OriginKind::Native;
let native_asset: MultiAsset = (Here, fee_amount).into();
let beneficiary = Polkadot::sovereign_account_id_of_child_para(para_a_id);
let mut xcm = xcm_transact_paid_execution(call, origin_kind, native_asset.clone(), beneficiary);
PenpalPolkadotA::execute_with(|| {
assert_ok!(<PenpalPolkadotA as PenpalPolkadotAPallet>::PolkadotXcm::send(
para_a_root_origin,
bx!(relay_destination.clone()),
bx!(xcm),
));
PenpalPolkadotA::assert_xcm_pallet_sent();
});
Polkadot::execute_with(|| {
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
Polkadot::assert_ump_queue_processed(
true,
Some(para_a_id),
Some(Weight::from_parts(1_282_426_000, 207_186)),
);
assert_expected_events!(
Polkadot,
vec![
// Parachain's Sovereign account balance is withdrawn to pay XCM fees
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == para_a_sovereign_account.clone(),
amount: *amount == fee_amount,
},
// Sender deposit is reserved for Parachain's Sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Reserved { who, .. }) =>{
who: *who == para_a_sovereign_account,
},
// Open channel requested from Para A to Para B
RuntimeEvent::Hrmp(
polkadot_runtime_parachains::hrmp::Event::OpenChannelRequested {
sender, recipient, proposed_max_capacity: max_capacity, proposed_max_message_size: max_message_size
}
) => {
sender: *sender == para_a_id.into(),
recipient: *recipient == para_b_id.into(),
max_capacity: *max_capacity == MAX_CAPACITY,
max_message_size: *max_message_size == MAX_MESSAGE_SIZE,
},
]
);
});
// ---- Accept Open channel from Parachain to System Parachain
call = Polkadot::accept_open_channel_call(para_a_id);
let beneficiary = Polkadot::sovereign_account_id_of_child_para(para_b_id);
xcm = xcm_transact_paid_execution(call, origin_kind, native_asset, beneficiary);
PenpalPolkadotB::execute_with(|| {
assert_ok!(<PenpalPolkadotB as PenpalPolkadotBPallet>::PolkadotXcm::send(
para_b_root_origin,
bx!(relay_destination),
bx!(xcm),
));
PenpalPolkadotB::assert_xcm_pallet_sent();
});
PenpalPolkadotB::execute_with(|| {});
Polkadot::execute_with(|| {
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
Polkadot::assert_ump_queue_processed(
true,
Some(para_b_id),
Some(Weight::from_parts(1_282_426_000, 207_186)),
);
assert_expected_events!(
Polkadot,
vec![
// Parachain's Sovereign account balance is withdrawn to pay XCM fees
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == para_b_sovereign_account.clone(),
amount: *amount == fee_amount,
},
// Sender deposit is reserved for Parachain's Sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Reserved { who, .. }) =>{
who: *who == para_b_sovereign_account,
},
// Open channel accepted for Para A to Para B
RuntimeEvent::Hrmp(
polkadot_runtime_parachains::hrmp::Event::OpenChannelAccepted {
sender, recipient
}
) => {
sender: *sender == para_a_id.into(),
recipient: *recipient == para_b_id.into(),
},
]
);
});
Polkadot::force_process_hrmp_open(para_a_id, para_b_id);
}
/// Opening HRMP channels between System Parachains and Parachains should work
#[test]
fn force_open_hrmp_channel_for_system_para_works() {
// Relay Chain init values
let relay_root_origin = <Polkadot as Chain>::RuntimeOrigin::root();
// System Para init values
let system_para_id = AssetHubPolkadot::para_id();
// Parachain A init values
let para_a_id = PenpalPolkadotA::para_id();
Polkadot::execute_with(|| {
assert_ok!(<Polkadot as PolkadotPallet>::Hrmp::force_open_hrmp_channel(
relay_root_origin,
system_para_id,
para_a_id,
MAX_CAPACITY,
MAX_MESSAGE_SIZE
));
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
assert_expected_events!(
Polkadot,
vec![
// HRMP channel forced opened
RuntimeEvent::Hrmp(
polkadot_runtime_parachains::hrmp::Event::HrmpChannelForceOpened{
sender, recipient, proposed_max_capacity: max_capacity, proposed_max_message_size: max_message_size
}
) => {
sender: *sender == system_para_id.into(),
recipient: *recipient == para_a_id.into(),
max_capacity: *max_capacity == MAX_CAPACITY,
max_message_size: *max_message_size == MAX_MESSAGE_SIZE,
},
]
);
});
Polkadot::force_process_hrmp_open(system_para_id, para_a_id);
}
@@ -1,20 +0,0 @@
// 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.
mod hrmp_channels;
mod reserve_transfer;
mod send;
mod set_xcm_versions;
mod teleport;
@@ -1,414 +0,0 @@
// 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 relay_origin_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
Polkadot::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(629_384_000, 6_196)));
assert_expected_events!(
Polkadot,
vec![
// Amount to reserve transfer is transferred to System Parachain's Sovereign account
RuntimeEvent::Balances(pallet_balances::Event::Transfer { from, to, amount }) => {
from: *from == t.sender.account_id,
to: *to == Polkadot::sovereign_account_id_of(
t.args.dest
),
amount: *amount == t.args.amount,
},
]
);
}
fn system_para_dest_assertions_incomplete(_t: RelayToSystemParaTest) {
AssetHubPolkadot::assert_dmp_queue_incomplete(
Some(Weight::from_parts(1_000_000_000, 0)),
Some(Error::UntrustedReserveLocation),
);
}
fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) {
AssetHubPolkadot::assert_xcm_pallet_attempted_error(Some(XcmError::Barrier))
}
fn system_para_to_para_assertions(t: SystemParaToParaTest) {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
676_119_000,
6196,
)));
assert_expected_events!(
AssetHubPolkadot,
vec![
// Amount to reserve transfer is transferred to Parachain's Sovereing account
RuntimeEvent::Balances(
pallet_balances::Event::Transfer { from, to, amount }
) => {
from: *from == t.sender.account_id,
to: *to == AssetHubPolkadot::sovereign_account_id_of(
t.args.dest
),
amount: *amount == t.args.amount,
},
]
);
}
fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
676_119_000,
6196,
)));
assert_expected_events!(
AssetHubPolkadot,
vec![
// Amount to reserve transfer is transferred to Parachain's Sovereing account
RuntimeEvent::Assets(
pallet_assets::Event::Transferred { asset_id, from, to, amount }
) => {
asset_id: *asset_id == ASSET_ID,
from: *from == t.sender.account_id,
to: *to == AssetHubPolkadot::sovereign_account_id_of(
t.args.dest
),
amount: *amount == t.args.amount,
},
]
);
}
fn relay_limited_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Polkadot as PolkadotPallet>::XcmPallet::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn relay_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Polkadot as PolkadotPallet>::XcmPallet::reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
fn system_para_limited_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn system_para_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
<AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::limited_reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
<AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::reserve_transfer_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
/// Limited Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't
/// work
#[test]
fn limited_reserve_transfer_native_asset_from_relay_to_system_para_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = POLKADOT_ED * 1000;
let test_args = TestContext {
sender: PolkadotSender::get(),
receiver: AssetHubPolkadotReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Polkadot>(relay_origin_assertions);
test.set_assertion::<AssetHubPolkadot>(system_para_dest_assertions_incomplete);
test.set_dispatchable::<Polkadot>(relay_limited_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Limited Reserve Transfers of native asset from System Parachain to Relay Chain shoudln't work
#[test]
fn limited_reserve_transfer_native_asset_from_system_para_to_relay_fails() {
// Init values for System Parachain
let destination = AssetHubPolkadot::parent_location();
let beneficiary_id = PolkadotReceiver::get();
let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PolkadotReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubPolkadot>(system_para_to_relay_assertions);
test.set_dispatchable::<AssetHubPolkadot>(system_para_limited_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
#[test]
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = POLKADOT_ED * 1000;
let test_args = TestContext {
sender: PolkadotSender::get(),
receiver: AssetHubPolkadotReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Polkadot>(relay_origin_assertions);
test.set_assertion::<AssetHubPolkadot>(system_para_dest_assertions_incomplete);
test.set_dispatchable::<Polkadot>(relay_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Reserve Transfers of native asset from System Parachain to Relay Chain shouldn't work
#[test]
fn reserve_transfer_native_asset_from_system_para_to_relay_fails() {
// Init values for System Parachain
let destination = AssetHubPolkadot::parent_location();
let beneficiary_id = PolkadotReceiver::get();
let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PolkadotReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubPolkadot>(system_para_to_relay_assertions);
test.set_dispatchable::<AssetHubPolkadot>(system_para_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
assert_eq!(sender_balance_before, sender_balance_after);
assert_eq!(receiver_balance_before, receiver_balance_after);
}
/// Limited Reserve Transfers of native asset from System Parachain to Parachain should work
#[test]
fn limited_reserve_transfer_native_asset_from_system_para_to_para() {
// Init values for System Parachain
let destination = AssetHubPolkadot::sibling_location_of(PenpalPolkadotA::para_id());
let beneficiary_id = PenpalPolkadotAReceiver::get();
let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PenpalPolkadotAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
test.set_assertion::<AssetHubPolkadot>(system_para_to_para_assertions);
// TODO: Add assertion for Penpal runtime. Right now message is failing with
// `UntrustedReserveLocation`
test.set_dispatchable::<AssetHubPolkadot>(system_para_to_para_limited_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
// transfers
}
/// Reserve Transfers of native asset from System Parachain to Parachain should work
#[test]
fn reserve_transfer_native_asset_from_system_para_to_para() {
// Init values for System Parachain
let destination = AssetHubPolkadot::sibling_location_of(PenpalPolkadotA::para_id());
let beneficiary_id = PenpalPolkadotAReceiver::get();
let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PenpalPolkadotAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
test.set_assertion::<AssetHubPolkadot>(system_para_to_para_assertions);
// TODO: Add assertion for Penpal runtime. Right now message is failing with
// `UntrustedReserveLocation`
test.set_dispatchable::<AssetHubPolkadot>(system_para_to_para_reserve_transfer_assets);
test.assert();
let sender_balance_after = test.sender.balance;
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
// transfers
}
/// Limited Reserve Transfers of a local asset from System Parachain to Parachain should work
#[test]
fn limited_reserve_transfer_asset_from_system_para_to_para() {
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
AssetHubPolkadot::force_create_and_mint_asset(
ASSET_ID,
ASSET_MIN_BALANCE,
true,
AssetHubPolkadotSender::get(),
ASSET_MIN_BALANCE * 1000000,
);
// Init values for System Parachain
let destination = AssetHubPolkadot::sibling_location_of(PenpalPolkadotA::para_id());
let beneficiary_id = PenpalPolkadotAReceiver::get();
let amount_to_send = ASSET_MIN_BALANCE * 1000;
let assets =
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
.into();
let system_para_test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PenpalPolkadotAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
system_para_test.set_assertion::<AssetHubPolkadot>(system_para_to_para_assets_assertions);
// TODO: Add assertions when Penpal is able to manage assets
system_para_test
.set_dispatchable::<AssetHubPolkadot>(system_para_to_para_limited_reserve_transfer_assets);
system_para_test.assert();
}
/// Reserve Transfers of a local asset from System Parachain to Parachain should work
#[test]
fn reserve_transfer_asset_from_system_para_to_para() {
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
AssetHubPolkadot::force_create_and_mint_asset(
ASSET_ID,
ASSET_MIN_BALANCE,
true,
AssetHubPolkadotSender::get(),
ASSET_MIN_BALANCE * 1000000,
);
// Init values for System Parachain
let destination = AssetHubPolkadot::sibling_location_of(PenpalPolkadotA::para_id());
let beneficiary_id = PenpalPolkadotAReceiver::get();
let amount_to_send = ASSET_MIN_BALANCE * 1000;
let assets =
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
.into();
let system_para_test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PenpalPolkadotAReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
system_para_test.set_assertion::<AssetHubPolkadot>(system_para_to_para_assets_assertions);
// TODO: Add assertions when Penpal is able to manage assets
system_para_test
.set_dispatchable::<AssetHubPolkadot>(system_para_to_para_reserve_transfer_assets);
system_para_test.assert();
}
@@ -1,201 +0,0 @@
// 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::*;
/// Relay Chain should be able to execute `Transact` instructions in System Parachain
/// when `OriginKind::Superuser` and signer is `sudo`
#[test]
fn send_transact_sudo_from_relay_to_system_para_works() {
// Init tests variables
let root_origin = <Polkadot as Chain>::RuntimeOrigin::root();
let system_para_destination = Polkadot::child_location_of(AssetHubPolkadot::para_id()).into();
let asset_owner: AccountId = AssetHubPolkadotSender::get().into();
let xcm = AssetHubPolkadot::force_create_asset_xcm(
OriginKind::Superuser,
ASSET_ID,
asset_owner.clone(),
true,
1000,
);
// Send XCM message from Relay Chain
Polkadot::execute_with(|| {
assert_ok!(<Polkadot as PolkadotPallet>::XcmPallet::send(
root_origin,
bx!(system_para_destination),
bx!(xcm),
));
Polkadot::assert_xcm_pallet_sent();
});
// Receive XCM message in Assets Parachain
AssetHubPolkadot::execute_with(|| {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_dmp_queue_complete(Some(Weight::from_parts(
1_019_445_000,
200_000,
)));
assert_expected_events!(
AssetHubPolkadot,
vec![
RuntimeEvent::Assets(pallet_assets::Event::ForceCreated { asset_id, owner }) => {
asset_id: *asset_id == ASSET_ID,
owner: *owner == asset_owner,
},
]
);
assert!(<AssetHubPolkadot as AssetHubPolkadotPallet>::Assets::asset_exists(ASSET_ID));
});
}
/// Relay Chain shouldn't be able to execute `Transact` instructions in System Parachain
/// when `OriginKind::Native`
#[test]
fn send_transact_native_from_relay_to_system_para_fails() {
// Init tests variables
let signed_origin = <Polkadot as Chain>::RuntimeOrigin::signed(PolkadotSender::get().into());
let system_para_destination = Polkadot::child_location_of(AssetHubPolkadot::para_id()).into();
let asset_owner = AssetHubPolkadotSender::get().into();
let xcm = AssetHubPolkadot::force_create_asset_xcm(
OriginKind::Native,
ASSET_ID,
asset_owner,
true,
1000,
);
// Send XCM message from Relay Chain
Polkadot::execute_with(|| {
assert_err!(
<Polkadot as PolkadotPallet>::XcmPallet::send(
signed_origin,
bx!(system_para_destination),
bx!(xcm)
),
DispatchError::BadOrigin
);
});
}
/// System Parachain shouldn't be able to execute `Transact` instructions in Relay Chain
/// when `OriginKind::Native`
#[test]
fn send_transact_native_from_system_para_to_relay_fails() {
// Init tests variables
let signed_origin =
<AssetHubPolkadot as Chain>::RuntimeOrigin::signed(AssetHubPolkadotSender::get().into());
let relay_destination = AssetHubPolkadot::parent_location().into();
let call = <Polkadot as Chain>::RuntimeCall::System(frame_system::Call::<
<Polkadot as Chain>::Runtime,
>::remark_with_event {
remark: vec![0, 1, 2, 3],
})
.encode()
.into();
let origin_kind = OriginKind::Native;
let xcm = xcm_transact_unpaid_execution(call, origin_kind);
// Send XCM message from Relay Chain
AssetHubPolkadot::execute_with(|| {
assert_err!(
<AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::send(
signed_origin,
bx!(relay_destination),
bx!(xcm)
),
DispatchError::BadOrigin
);
});
}
/// Parachain should be able to send XCM paying its fee with sufficient asset
/// in the System Parachain
#[test]
fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
let para_sovereign_account = AssetHubPolkadot::sovereign_account_id_of(
AssetHubPolkadot::sibling_location_of(PenpalPolkadotA::para_id()),
);
// Force create and mint assets for Parachain's sovereign account
AssetHubPolkadot::force_create_and_mint_asset(
ASSET_ID,
ASSET_MIN_BALANCE,
true,
para_sovereign_account.clone(),
ASSET_MIN_BALANCE * 1000000000,
);
// We just need a call that can pass the `SafeCallFilter`
// Call values are not relevant
let call = AssetHubPolkadot::force_create_asset_call(
ASSET_ID,
para_sovereign_account.clone(),
true,
ASSET_MIN_BALANCE,
);
let origin_kind = OriginKind::SovereignAccount;
let fee_amount = ASSET_MIN_BALANCE * 1000000;
let native_asset =
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount).into();
let root_origin = <PenpalPolkadotA as Chain>::RuntimeOrigin::root();
let system_para_destination =
PenpalPolkadotA::sibling_location_of(AssetHubPolkadot::para_id()).into();
let xcm = xcm_transact_paid_execution(
call,
origin_kind,
native_asset,
para_sovereign_account.clone(),
);
PenpalPolkadotA::execute_with(|| {
assert_ok!(<PenpalPolkadotA as PenpalPolkadotAPallet>::PolkadotXcm::send(
root_origin,
bx!(system_para_destination),
bx!(xcm),
));
PenpalPolkadotA::assert_xcm_pallet_sent();
});
AssetHubPolkadot::execute_with(|| {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_xcmp_queue_success(Some(Weight::from_parts(
2_176_414_000,
203_593,
)));
assert_expected_events!(
AssetHubPolkadot,
vec![
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
asset_id: *asset_id == ASSET_ID,
owner: *owner == para_sovereign_account,
balance: *balance == fee_amount,
},
RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => {
asset_id: *asset_id == ASSET_ID,
},
]
);
});
}
@@ -1,96 +0,0 @@
// 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::*;
#[test]
fn relay_sets_system_para_xcm_supported_version() {
// Init tests variables
let sudo_origin = <Polkadot as Chain>::RuntimeOrigin::root();
let system_para_destination: MultiLocation =
Polkadot::child_location_of(AssetHubPolkadot::para_id());
// Relay Chain sets supported version for Asset Parachain
Polkadot::execute_with(|| {
assert_ok!(<Polkadot as PolkadotPallet>::XcmPallet::force_xcm_version(
sudo_origin,
bx!(system_para_destination),
XCM_V3
));
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
assert_expected_events!(
Polkadot,
vec![
RuntimeEvent::XcmPallet(pallet_xcm::Event::SupportedVersionChanged {
location,
version: XCM_V3
}) => { location: *location == system_para_destination, },
]
);
});
}
#[test]
fn system_para_sets_relay_xcm_supported_version() {
// Init test variables
let sudo_origin = <Polkadot as Chain>::RuntimeOrigin::root();
let parent_location = AssetHubPolkadot::parent_location();
let system_para_destination: VersionedMultiLocation =
Polkadot::child_location_of(AssetHubPolkadot::para_id()).into();
let call = <AssetHubPolkadot as Chain>::RuntimeCall::PolkadotXcm(pallet_xcm::Call::<
<AssetHubPolkadot as Chain>::Runtime,
>::force_xcm_version {
location: bx!(parent_location),
version: XCM_V3,
})
.encode()
.into();
let origin_kind = OriginKind::Superuser;
let xcm = xcm_transact_unpaid_execution(call, origin_kind);
// System Parachain sets supported version for Relay Chain throught it
Polkadot::execute_with(|| {
assert_ok!(<Polkadot as PolkadotPallet>::XcmPallet::send(
sudo_origin,
bx!(system_para_destination),
bx!(xcm),
));
Polkadot::assert_xcm_pallet_sent();
});
// System Parachain receive the XCM message
AssetHubPolkadot::execute_with(|| {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_dmp_queue_complete(Some(Weight::from_parts(
1_019_210_000,
200_000,
)));
assert_expected_events!(
AssetHubPolkadot,
vec![
RuntimeEvent::PolkadotXcm(pallet_xcm::Event::SupportedVersionChanged {
location,
version: XCM_V3
}) => { location: *location == parent_location, },
]
);
});
}
@@ -1,363 +0,0 @@
// 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.
#![allow(dead_code)] // <https://github.com/paritytech/cumulus/issues/3027>
use crate::*;
fn relay_origin_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
Polkadot::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(632_207_000, 7_186)));
assert_expected_events!(
Polkadot,
vec![
// Amount to teleport is withdrawn from Sender
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == t.sender.account_id,
amount: *amount == t.args.amount,
},
// Amount to teleport is deposited in Relay's `CheckAccount`
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, amount }) => {
who: *who == <Polkadot as PolkadotPallet>::XcmPallet::check_account(),
amount: *amount == t.args.amount,
},
]
);
}
fn relay_dest_assertions(t: SystemParaToRelayTest) {
type RuntimeEvent = <Polkadot as Chain>::RuntimeEvent;
Polkadot::assert_ump_queue_processed(
true,
Some(AssetHubPolkadot::para_id()),
Some(Weight::from_parts(368_931_000, 7_186)),
);
assert_expected_events!(
Polkadot,
vec![
// Amount is witdrawn from Relay Chain's `CheckAccount`
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == <Polkadot as PolkadotPallet>::XcmPallet::check_account(),
amount: *amount == t.args.amount,
},
// Amount minus fees are deposited in Receiver's account
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => {
who: *who == t.receiver.account_id,
},
]
);
}
fn relay_dest_assertions_fail(_t: SystemParaToRelayTest) {
Polkadot::assert_ump_queue_processed(
false,
Some(AssetHubPolkadot::para_id()),
Some(Weight::from_parts(232_982_000, 3_593)),
);
}
fn para_origin_assertions(t: SystemParaToRelayTest) {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
632_207_000,
7_186,
)));
AssetHubPolkadot::assert_parachain_system_ump_sent();
assert_expected_events!(
AssetHubPolkadot,
vec![
// Amount is withdrawn from Sender's account
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
who: *who == t.sender.account_id,
amount: *amount == t.args.amount,
},
]
);
}
fn para_dest_assertions(t: RelayToSystemParaTest) {
type RuntimeEvent = <AssetHubPolkadot as Chain>::RuntimeEvent;
AssetHubPolkadot::assert_dmp_queue_complete(Some(Weight::from_parts(161_196_000, 0)));
assert_expected_events!(
AssetHubPolkadot,
vec![
// Amount minus fees are deposited in Receiver's account
RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => {
who: *who == t.receiver.account_id,
},
]
);
}
fn relay_limited_teleport_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Polkadot as PolkadotPallet>::XcmPallet::limited_teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
fn relay_teleport_assets(t: RelayToSystemParaTest) -> DispatchResult {
<Polkadot as PolkadotPallet>::XcmPallet::teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
)
}
fn system_para_limited_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
<AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::limited_teleport_assets(
t.signed_origin,
bx!(t.args.dest.into()),
bx!(t.args.beneficiary.into()),
bx!(t.args.assets.into()),
t.args.fee_asset_item,
t.args.weight_limit,
)
}
// TODO: Uncomment when https://github.com/paritytech/polkadot/pull/7424 is merged
// fn system_para_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
// <AssetHubPolkadot as AssetHubPolkadotPallet>::PolkadotXcm::teleport_assets(
// t.signed_origin,
// bx!(t.args.dest),
// bx!(t.args.beneficiary),
// bx!(t.args.assets),
// t.args.fee_asset_item,
// )
// }
/// Limited Teleport of native asset from Relay Chain to the System Parachain should work
#[test]
fn limited_teleport_native_assets_from_relay_to_system_para_works() {
// Init values for Relay Chain
let amount_to_send: Balance = POLKADOT_ED * 1000;
let test_args = TestContext {
sender: PolkadotSender::get(),
receiver: AssetHubPolkadotReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Polkadot>(relay_origin_assertions);
test.set_assertion::<AssetHubPolkadot>(para_dest_assertions);
test.set_dispatchable::<Polkadot>(relay_limited_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}
/// Limited Teleport of native asset from System Parachain to Relay Chain
/// should work when there is enough balance in Relay Chain's `CheckAccount`
#[test]
fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
// Dependency - Relay Chain's `CheckAccount` should have enough balance
limited_teleport_native_assets_from_relay_to_system_para_works();
// Init values for Relay Chain
let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
let destination = AssetHubPolkadot::parent_location();
let beneficiary_id = PolkadotReceiver::get();
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PolkadotReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubPolkadot>(para_origin_assertions);
test.set_assertion::<Polkadot>(relay_dest_assertions);
test.set_dispatchable::<AssetHubPolkadot>(system_para_limited_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}
/// Limited Teleport of native asset from System Parachain to Relay Chain
/// should't work when there is not enough balance in Relay Chain's `CheckAccount`
#[test]
fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
// Init values for Relay Chain
let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
let destination = AssetHubPolkadot::parent_location().into();
let beneficiary_id = PolkadotReceiver::get().into();
let assets = (Parent, amount_to_send).into();
let test_args = TestContext {
sender: AssetHubPolkadotSender::get(),
receiver: PolkadotReceiver::get(),
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
};
let mut test = SystemParaToRelayTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<AssetHubPolkadot>(para_origin_assertions);
test.set_assertion::<Polkadot>(relay_dest_assertions_fail);
test.set_dispatchable::<AssetHubPolkadot>(system_para_limited_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance does not change
assert_eq!(receiver_balance_after, receiver_balance_before);
}
/// Teleport of native asset from Relay Chain to the System Parachain should work
#[test]
fn teleport_native_assets_from_relay_to_system_para_works() {
// Init values for Relay Chain
let amount_to_send: Balance = POLKADOT_ED * 1000;
let test_args = TestContext {
sender: PolkadotSender::get(),
receiver: AssetHubPolkadotReceiver::get(),
args: relay_test_args(amount_to_send),
};
let mut test = RelayToSystemParaTest::new(test_args);
let sender_balance_before = test.sender.balance;
let receiver_balance_before = test.receiver.balance;
test.set_assertion::<Polkadot>(relay_origin_assertions);
test.set_assertion::<AssetHubPolkadot>(para_dest_assertions);
test.set_dispatchable::<Polkadot>(relay_teleport_assets);
test.assert();
let sender_balance_after = test.sender.balance;
let receiver_balance_after = test.receiver.balance;
// Sender's balance is reduced
assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// Receiver's balance is increased
assert!(receiver_balance_after > receiver_balance_before);
}
// TODO: Uncomment when https://github.com/paritytech/polkadot/pull/7424 is merged
// Right now it is failing in the Relay Chain with a
// `messageQueue.ProcessingFailed` event `error: Unsupported`.
// The reason is the `Weigher` in `pallet_xcm` is not properly calculating the `remote_weight`
// and it cause an `Overweight` error in `AllowTopLevelPaidExecutionFrom` barrier
// /// Teleport of native asset from System Parachains to the Relay Chain
// /// should work when there is enough balance in Relay Chain's `CheckAccount`
// #[test]
// fn teleport_native_assets_back_from_system_para_to_relay_works() {
// // Dependency - Relay Chain's `CheckAccount` should have enough balance
// teleport_native_assets_from_relay_to_system_para_works();
// // Init values for Relay Chain
// let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
// let test_args = TestContext {
// sender: AssetHubPolkadotSender::get(),
// receiver: PolkadotReceiver::get(),
// args: get_para_dispatch_args(amount_to_send),
// };
// let mut test = SystemParaToRelayTest::new(test_args);
// let sender_balance_before = test.sender.balance;
// let receiver_balance_before = test.receiver.balance;
// test.set_assertion::<AssetHubPolkadot>(para_origin_assertions);
// test.set_assertion::<Polkadot>(relay_dest_assertions);
// test.set_dispatchable::<AssetHubPolkadot>(system_para_teleport_assets);
// test.assert();
// let sender_balance_after = test.sender.balance;
// let receiver_balance_after = test.receiver.balance;
// // Sender's balance is reduced
// assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// // Receiver's balance is increased
// assert!(receiver_balance_after > receiver_balance_before);
// }
// /// Teleport of native asset from System Parachain to Relay Chain
// /// shouldn't work when there is not enough balance in Relay Chain's `CheckAccount`
// #[test]
// fn teleport_native_assets_from_system_para_to_relay_fails() {
// // Init values for Relay Chain
// let amount_to_send: Balance = ASSET_HUB_POLKADOT_ED * 1000;
// let assets = (Parent, amount_to_send).into();
//
// let test_args = TestContext {
// sender: AssetHubPolkadotSender::get(),
// receiver: PolkadotReceiver::get(),
// args: system_para_test_args(amount_to_send),
// assets,
// None
// };
// let mut test = SystemParaToRelayTest::new(test_args);
// let sender_balance_before = test.sender.balance;
// let receiver_balance_before = test.receiver.balance;
// test.set_assertion::<AssetHubPolkadot>(para_origin_assertions);
// test.set_assertion::<Polkadot>(relay_dest_assertions);
// test.set_dispatchable::<AssetHubPolkadot>(system_para_teleport_assets);
// test.assert();
// let sender_balance_after = test.sender.balance;
// let receiver_balance_after = test.receiver.balance;
// // Sender's balance is reduced
// assert_eq!(sender_balance_before - amount_to_send, sender_balance_after);
// // Receiver's balance does not change
// assert_eq!(receiver_balance_after, receiver_balance_before);
// }
@@ -23,7 +23,6 @@ pallet-asset-conversion = { path = "../../../../../../substrate/frame/asset-conv
polkadot-core-primitives = { path = "../../../../../../polkadot/core-primitives", default-features = false}
polkadot-parachain-primitives = { path = "../../../../../../polkadot/parachain", default-features = false}
polkadot-runtime-parachains = { path = "../../../../../../polkadot/runtime/parachains" }
polkadot-runtime = { path = "../../../../../../polkadot/runtime/polkadot" }
xcm = { package = "staging-xcm", path = "../../../../../../polkadot/xcm", default-features = false}
pallet-xcm = { path = "../../../../../../polkadot/xcm/pallet-xcm", default-features = false}
@@ -48,6 +47,5 @@ runtime-benchmarks = [
"parachains-common/runtime-benchmarks",
"polkadot-parachain-primitives/runtime-benchmarks",
"polkadot-runtime-parachains/runtime-benchmarks",
"polkadot-runtime/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]