From 4e84fdd5539f29b5d5e9c62c2a957df87038d20a Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Mon, 27 Mar 2023 11:10:34 +0000 Subject: [PATCH] refactor: xcm transact forbidden test --- --- a/runtime/common/tests/mod.rs +++ b/runtime/common/tests/mod.rs @@ -14,22 +14,49 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -use sp_runtime::BuildStorage; +use sp_runtime::{BuildStorage, Storage}; use sp_core::{Public, Pair}; use sp_std::vec; use up_common::types::AuraId; -use crate::{GenesisConfig, ParachainInfoConfig}; +use crate::{Runtime, GenesisConfig, ParachainInfoConfig, RuntimeEvent, System}; + +pub use sp_runtime::AccountId32 as AccountId; +pub type Balance = u128; pub mod xcm; +#[cfg(any(feature = "opal-runtime", feature = "quartz-runtime"))] +/// PARA_ID for Opal/Sapphire/Quartz +const PARA_ID: u32 = 2095; + +#[cfg(feature = "unique-runtime")] +/// PARA_ID for Unique +const PARA_ID: u32 = 2037; + fn get_from_seed(seed: &str) -> ::Public { TPublic::Pair::from_string(&format!("//{}", seed), None) .expect("static values are valid; qed") .public() } +fn last_events(n: usize) -> Vec { + System::events().into_iter().map(|e| e.event).rev().take(n).rev().collect() +} + +fn new_test_ext(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities { + let mut storage = make_basic_storage(); + + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut storage) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(storage); + ext.execute_with(|| System::set_block_number(1)); + ext +} + #[cfg(feature = "collator-selection")] -fn new_test_ext(para_id: u32) -> sp_io::TestExternalities { +fn make_basic_storage() -> Storage { use sp_core::{sr25519}; use sp_runtime::traits::{IdentifyAccount, Verify}; use crate::{AccountId, Signature, SessionKeys, CollatorSelectionConfig, SessionConfig}; @@ -66,7 +93,7 @@ collator_selection: CollatorSelectionConfig { invulnerables }, session: SessionConfig { keys }, parachain_info: ParachainInfoConfig { - parachain_id: para_id.into(), + parachain_id: PARA_ID.into(), }, ..GenesisConfig::default() }; @@ -75,7 +102,7 @@ } #[cfg(not(feature = "collator-selection"))] -fn new_test_ext(para_id: u32) -> sp_io::TestExternalities { +fn make_basic_storage() -> Storage { use crate::AuraConfig; let cfg = GenesisConfig { @@ -86,7 +113,7 @@ ], }, parachain_info: ParachainInfoConfig { - parachain_id: para_id.into(), + parachain_id: PARA_ID.into(), }, ..GenesisConfig::default() }; --- a/runtime/common/tests/xcm.rs +++ b/runtime/common/tests/xcm.rs @@ -14,149 +14,53 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -use xcm_executor::traits::ShouldExecute; -use xcm::latest::prelude::*; -use logtest::Logger; -use crate::RuntimeCall; -use super::new_test_ext; -use frame_support::pallet_prelude::Weight; - -fn catch_xcm_barrier_log(logger: &mut Logger, expected_msg: &str) -> Result<(), String> { - for record in logger { - if record.target() == "xcm::barrier" && record.args() == expected_msg { - return Ok(()); - } - } - - Err(format!( - "the expected XCM barrier log `{}` is not found", - expected_msg - )) -} - -/// WARNING: Uses log capturing -/// See https://docs.rs/logtest/latest/logtest/index.html#constraints -pub fn barrier_denies_transact(logger: &mut Logger) { - let location = MultiLocation { - parents: 0, - interior: Junctions::Here, - }; - - // We will never decode this "call", - // so it is irrelevant what we are passing to the `transact` cmd. - let fake_encoded_call = vec![0u8]; - - let transact_inst: Instruction = Transact { - origin_kind: OriginKind::Superuser, - require_weight_at_most: Weight::default(), - call: fake_encoded_call.into(), - }; - - let mut xcm_program = vec![transact_inst]; +use xcm::{ + VersionedXcm, + latest::{prelude::*, Error} +}; +use codec::Encode; +use crate::{Runtime, RuntimeCall, RuntimeOrigin, RuntimeEvent, PolkadotXcm}; +use super::{new_test_ext, last_events, AccountId}; +use frame_support::{ + pallet_prelude::Weight, +}; - let max_weight = Weight::from_parts(100_000, 100_000); - let mut weight_credit = Weight::from_parts(100_000_000, 100_000_000); +const ALICE: AccountId = AccountId::new([0u8; 32]); +const BOB: AccountId = AccountId::new([1u8; 32]); - let result = B::should_execute(&location, &mut xcm_program, max_weight, &mut weight_credit); +const INITIAL_BALANCE: u128 = 1000000000000000000_0000; // 1000 UNQ - assert!( - result.is_err(), - "the barrier should disallow the XCM transact cmd" - ); +#[test] +pub fn xcm_transact_is_forbidden() { + new_test_ext(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { + PolkadotXcm::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::from(Xcm(vec![ + Transact { + origin_kind: OriginKind::Native, + require_weight_at_most: Weight::from_parts(1000, 1000), + call: RuntimeCall::Balances( + pallet_balances::Call::::transfer { + dest: BOB.into(), + value: INITIAL_BALANCE / 2, + } + ).encode().into(), + } + ]))), + Weight::from_parts(1001000, 2000), + ).expect("XCM execute must succeed, the error should be in the `PolkadotXcm::Attempted` event"); - catch_xcm_barrier_log(logger, "transact XCM rejected").unwrap(); -} - -fn xcm_execute( - self_para_id: u32, - location: &MultiLocation, - xcm: &mut [Instruction], -) -> Result<(), ()> { - new_test_ext(self_para_id).execute_with(|| { - let max_weight = Weight::from_parts(100_000, 100_000); - let mut weight_credit = Weight::from_parts(100_000_000, 100_000_000); - - B::should_execute(&location, xcm, max_weight, &mut weight_credit) - }) -} - -fn make_multiassets(location: &MultiLocation) -> MultiAssets { - let id = AssetId::Concrete(location.clone()); - let fun = Fungibility::Fungible(42); - let multiasset = MultiAsset { id, fun }; - - multiasset.into() -} - -fn make_transfer_reserve_asset(location: &MultiLocation) -> Xcm { - let assets = make_multiassets(location); - let inst = TransferReserveAsset { - assets, - dest: location.clone(), - xcm: Xcm(vec![]), - }; - - Xcm::(vec![inst]) -} - -fn make_deposit_reserve_asset(location: &MultiLocation) -> Xcm { - let assets = make_multiassets(location); - let inst = DepositReserveAsset { - assets: assets.into(), - dest: location.clone(), - xcm: Xcm(vec![]), - }; - - Xcm::(vec![inst]) -} - -fn expect_transfer_location_denied( - logger: &mut Logger, - self_para_id: u32, - location: &MultiLocation, - xcm: &mut [Instruction], -) -> Result<(), String> { - let result = xcm_execute::(self_para_id, location, xcm); - - if result.is_ok() { - return Err("the barrier should deny the unknown location".into()); - } - - catch_xcm_barrier_log(logger, "Unexpected deposit or transfer location") -} - -/// WARNING: Uses log capturing -/// See https://docs.rs/logtest/latest/logtest/index.html#constraints -pub fn barrier_denies_transfer_from_unknown_location( - logger: &mut Logger, - self_para_id: u32, -) -> Result<(), String> -where - B: ShouldExecute, -{ - const UNKNOWN_PARACHAIN_ID: u32 = 4057; - - let unknown_location = MultiLocation { - parents: 1, - interior: X1(Parachain(UNKNOWN_PARACHAIN_ID)), - }; - - let mut transfer_reserve_asset = make_transfer_reserve_asset(&unknown_location); - let mut deposit_reserve_asset = make_deposit_reserve_asset(&unknown_location); - - expect_transfer_location_denied::( - logger, - self_para_id, - &unknown_location, - &mut transfer_reserve_asset.0, - )?; - - expect_transfer_location_denied::( - logger, - self_para_id, - &unknown_location, - &mut deposit_reserve_asset.0, - )?; - - Ok(()) + let xcm_event = &last_events(1)[0]; + match xcm_event { + RuntimeEvent::PolkadotXcm( + pallet_xcm::Event::::Attempted( + Outcome::Incomplete(_weight, Error::NoPermission) + ) + ) => { /* Pass */ }, + _ => panic!( + "Expected PolkadotXcm.Attempted(Incomplete(_weight, NoPermission)),\ + found: {xcm_event:#?}" + ) + } + }); } --- a/runtime/opal/Cargo.toml +++ b/runtime/opal/Cargo.toml @@ -307,8 +307,5 @@ impl-trait-for-tuples = { workspace = true } -[dev-dependencies] -logtest = { workspace = true } - [build-dependencies] substrate-wasm-builder = { workspace = true } --- a/runtime/opal/src/lib.rs +++ b/runtime/opal/src/lib.rs @@ -41,9 +41,6 @@ pub mod xcm_barrier; -#[cfg(test)] -mod tests; - pub use runtime_common::*; pub const RUNTIME_NAME: &str = "opal"; --- a/runtime/opal/src/tests/logcapture.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -use logtest::Logger; -use super::xcm::opal_xcm_tests; - -#[test] -fn opal_log_capture_tests() { - let mut logger = Logger::start(); - - opal_xcm_tests(&mut logger); -} --- a/runtime/opal/src/tests/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -mod logcapture; -mod xcm; --- a/runtime/opal/src/tests/xcm.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -use logtest::Logger; -use crate::{runtime_common::tests::xcm::*, xcm_barrier::Barrier}; - -const OPAL_PARA_ID: u32 = 2095; // Same as Quartz - -pub fn opal_xcm_tests(logger: &mut Logger) { - barrier_denies_transact::(logger); - - barrier_denies_transfer_from_unknown_location::(logger, OPAL_PARA_ID) - .expect_err("opal runtime allows any location"); -} --- a/runtime/quartz/Cargo.toml +++ b/runtime/quartz/Cargo.toml @@ -300,8 +300,5 @@ impl-trait-for-tuples = { workspace = true } -[dev-dependencies] -logtest = { workspace = true } - [build-dependencies] substrate-wasm-builder = { workspace = true } --- a/runtime/quartz/src/lib.rs +++ b/runtime/quartz/src/lib.rs @@ -41,9 +41,6 @@ pub mod xcm_barrier; -#[cfg(test)] -mod tests; - pub use runtime_common::*; #[cfg(feature = "become-sapphire")] --- a/runtime/quartz/src/tests/logcapture.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -use logtest::Logger; -use super::xcm::quartz_xcm_tests; - -#[test] -fn quartz_log_capture_tests() { - let mut logger = Logger::start(); - - quartz_xcm_tests(&mut logger); -} --- a/runtime/quartz/src/tests/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -mod logcapture; -mod xcm; --- a/runtime/quartz/src/tests/xcm.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -use logtest::Logger; -use crate::{runtime_common::tests::xcm::*, xcm_barrier::Barrier}; - -const QUARTZ_PARA_ID: u32 = 2095; - -pub fn quartz_xcm_tests(logger: &mut Logger) { - barrier_denies_transact::(logger); - - barrier_denies_transfer_from_unknown_location::(logger, QUARTZ_PARA_ID) - .expect("quartz runtime denies an unknown location"); -} --- a/runtime/unique/Cargo.toml +++ b/runtime/unique/Cargo.toml @@ -298,8 +298,5 @@ impl-trait-for-tuples = { workspace = true } -[dev-dependencies] -logtest = { workspace = true } - [build-dependencies] substrate-wasm-builder = { workspace = true } --- a/runtime/unique/src/lib.rs +++ b/runtime/unique/src/lib.rs @@ -41,9 +41,6 @@ pub mod xcm_barrier; -#[cfg(test)] -mod tests; - pub use runtime_common::*; pub const RUNTIME_NAME: &str = "unique"; --- a/runtime/unique/src/tests/logcapture.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -use logtest::Logger; -use super::xcm::unique_xcm_tests; - -#[test] -fn unique_log_capture_tests() { - let mut logger = Logger::start(); - - unique_xcm_tests(&mut logger); -} --- a/runtime/unique/src/tests/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -mod logcapture; -mod xcm; --- a/runtime/unique/src/tests/xcm.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -use logtest::Logger; -use crate::{runtime_common::tests::xcm::*, xcm_barrier::Barrier}; - -const UNIQUE_PARA_ID: u32 = 2037; - -pub fn unique_xcm_tests(logger: &mut Logger) { - barrier_denies_transact::(logger); - - barrier_denies_transfer_from_unknown_location::(logger, UNIQUE_PARA_ID) - .expect("unique runtime denies an unknown location"); -} -- gitstuff