From 0985898e458bcd15e997856d95960ea2290128ec Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 5 Jan 2023 11:19:22 +0100 Subject: [PATCH] Unit-test for Statemine - send_xcm_transact_with_remark_with_event_works --- Cargo.lock | 8 ++ .../runtimes/assets/statemine/src/lib.rs | 2 +- .../runtimes/assets/statemine/tests/tests.rs | 68 +++++++++- .../runtimes/assets/test-utils/Cargo.toml | 18 +++ .../runtimes/assets/test-utils/src/lib.rs | 121 +++++++++++++++++- .../runtimes/assets/westmint/src/lib.rs | 2 +- 6 files changed, 207 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf9e0f88e7..d012687599 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,19 +190,27 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" name = "asset-test-utils" version = "1.0.0" dependencies = [ + "cumulus-pallet-parachain-system", + "cumulus-primitives-core", + "cumulus-primitives-parachain-inherent", + "cumulus-test-relay-sproof-builder", "frame-support", "frame-system", "hex-literal", "pallet-balances", "pallet-collator-selection", "pallet-session", + "pallet-xcm", + "parachain-info", "parachains-common", + "polkadot-parachain 0.9.31", "sp-consensus-aura", "sp-core", "sp-io", "sp-runtime", "sp-std", "substrate-wasm-builder", + "xcm", ] [[package]] diff --git a/parachains/runtimes/assets/statemine/src/lib.rs b/parachains/runtimes/assets/statemine/src/lib.rs index 70b0a68a6a..080bb046a3 100644 --- a/parachains/runtimes/assets/statemine/src/lib.rs +++ b/parachains/runtimes/assets/statemine/src/lib.rs @@ -91,7 +91,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 9300, + spec_version: 9301, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 8, diff --git a/parachains/runtimes/assets/statemine/tests/tests.rs b/parachains/runtimes/assets/statemine/tests/tests.rs index ab2d2e8062..811c90d0f8 100644 --- a/parachains/runtimes/assets/statemine/tests/tests.rs +++ b/parachains/runtimes/assets/statemine/tests/tests.rs @@ -1,4 +1,4 @@ -use asset_test_utils::{ExtBuilder, RuntimeHelper}; +use asset_test_utils::{mock_open_hrmp_channel, ExtBuilder, RuntimeHelper}; use frame_support::{ assert_noop, assert_ok, traits::PalletInfo, @@ -6,10 +6,11 @@ use frame_support::{ }; use parachains_common::{AccountId, AuraId}; pub use statemine_runtime::{ - constants::fee::WeightToFee, xcm_config::XcmConfig, Balances, ExistentialDeposit, Runtime, - SessionKeys, System, TrustBackedAssets, + constants::fee::WeightToFee, xcm_config::XcmConfig, Balances, ExistentialDeposit, + ParachainSystem, PolkadotXcm, Runtime, RuntimeEvent, RuntimeOrigin, SessionKeys, System, + TrustBackedAssets, }; -use xcm::latest::prelude::*; +use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::WeightTrader; pub const ALICE: [u8; 32] = [1u8; 32]; @@ -304,3 +305,62 @@ fn test_that_buying_ed_refund_does_not_refund() { assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); }); } + +#[test] +fn test_send_xcm_transact_with_remark_with_event_works() { + let runtime_para_id = 1015; + let bridge_hub_para_id = 1013; + + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .with_tracing() + .with_safe_xcm_version(3) + .with_para_id(runtime_para_id.into()) + .build() + .execute_with(|| { + // open hrmp channel + mock_open_hrmp_channel::( + runtime_para_id.into(), + bridge_hub_para_id.into(), + ); + + // prepare xcm message with Transact + let message = Xcm(vec![ExportMessage { + network: Wococo, + destination: X1(Parachain(1000)), + xcm: Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: 1000000000, + call: vec![0, 8, 20, 104, 101, 108, 108, 111].into(), + }]), + }]); + + // simulate send export_message to bridge-hub + assert_ok!(PolkadotXcm::send( + RuntimeOrigin::signed(AccountId::from(ALICE)), + Box::new(VersionedMultiLocation::V3(MultiLocation { + parents: 1, + interior: X1(Parachain(bridge_hub_para_id)) + })), + Box::new(VersionedXcm::from(message.clone())) + )); + + // check xcm sent-like events occured + let events = System::events(); + assert!(!events.is_empty()); + + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent(..)) + ))); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) + ))); + }); +} diff --git a/parachains/runtimes/assets/test-utils/Cargo.toml b/parachains/runtimes/assets/test-utils/Cargo.toml index 52ce1d2d9a..f7e3a768de 100644 --- a/parachains/runtimes/assets/test-utils/Cargo.toml +++ b/parachains/runtimes/assets/test-utils/Cargo.toml @@ -22,6 +22,16 @@ sp-core = { git = "https://github.com/paritytech/substrate", default-features = # Cumulus pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false } parachains-common = { path = "../../../common", default-features = false } +cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false } +cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false } +cumulus-primitives-parachain-inherent = { path = "../../../../primitives/parachain-inherent", default-features = false } +cumulus-test-relay-sproof-builder = { path = "../../../../test/relay-sproof-builder", default-features = false } +parachain-info = { path = "../../../../parachains/pallets/parachain-info", default-features = false } + +# Polkadot +xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } [dev-dependencies] hex-literal = "0.3.4" @@ -32,14 +42,22 @@ substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", bran [features] default = [ "std" ] std = [ + "cumulus-pallet-parachain-system/std", + "cumulus-primitives-core/std", + "cumulus-test-relay-sproof-builder/std", + "cumulus-primitives-parachain-inherent/std", "frame-support/std", "frame-system/std", "pallet-balances/std", "pallet-collator-selection/std", "pallet-session/std", + "pallet-xcm/std", "parachains-common/std", + "parachain-info/std", + "polkadot-parachain/std", "sp-consensus-aura/std", "sp-io/std", "sp-runtime/std", "sp-std/std", + "xcm/std", ] diff --git a/parachains/runtimes/assets/test-utils/src/lib.rs b/parachains/runtimes/assets/test-utils/src/lib.rs index ee7b71131f..eaba572b14 100644 --- a/parachains/runtimes/assets/test-utils/src/lib.rs +++ b/parachains/runtimes/assets/test-utils/src/lib.rs @@ -1,11 +1,20 @@ -use frame_support::traits::GenesisBuild; +use cumulus_primitives_core::{AbridgedHrmpChannel, ParaId, PersistedValidationData}; +use cumulus_primitives_parachain_inherent::ParachainInherentData; +use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder; +use frame_support::{ + dispatch::{RawOrigin, UnfilteredDispatchable}, + inherent::{InherentData, ProvideInherent}, + traits::GenesisBuild, +}; use sp_std::marker::PhantomData; use frame_support::traits::OriginTrait; use parachains_common::AccountId; +use polkadot_parachain::primitives::{HrmpChannelId, RelayChainBlockNumber}; use sp_consensus_aura::AURA_ENGINE_ID; use sp_core::Encode; use sp_runtime::{Digest, DigestItem}; +use xcm::prelude::XcmVersion; pub type BalanceOf = ::Balance; pub type AccountIdOf = ::AccountId; @@ -22,19 +31,39 @@ pub struct ExtBuilder< collators: Vec>, // keys added to pallet session keys: Vec<(AccountIdOf, ValidatorIdOf, SessionKeysOf)>, + // safe xcm version for pallet_xcm + safe_xcm_version: Option, + // para id + para_id: Option, _runtime: PhantomData, } -impl Default - for ExtBuilder +impl< + Runtime: frame_system::Config + + pallet_balances::Config + + pallet_session::Config + + pallet_xcm::Config, + > Default for ExtBuilder { fn default() -> ExtBuilder { - ExtBuilder { balances: vec![], collators: vec![], keys: vec![], _runtime: PhantomData } + ExtBuilder { + balances: vec![], + collators: vec![], + keys: vec![], + safe_xcm_version: None, + para_id: None, + _runtime: PhantomData, + } } } -impl - ExtBuilder +impl< + Runtime: frame_system::Config + + pallet_balances::Config + + pallet_session::Config + + pallet_xcm::Config + + parachain_info::Config, + > ExtBuilder { pub fn with_balances( mut self, @@ -61,6 +90,16 @@ impl Self { + self.safe_xcm_version = Some(safe_xcm_version); + self + } + + pub fn with_para_id(mut self, para_id: ParaId) -> Self { + self.para_id = Some(para_id); + self + } + pub fn build(self) -> sp_io::TestExternalities where Runtime: @@ -69,6 +108,20 @@ impl().unwrap(); + >::assimilate_storage( + &pallet_xcm::GenesisConfig { safe_xcm_version: self.safe_xcm_version }, + &mut t, + ) + .unwrap(); + + if let Some(para_id) = self.para_id { + >::assimilate_storage( + ¶chain_info::GenesisConfig { parachain_id: para_id }, + &mut t, + ) + .unwrap(); + } + pallet_balances::GenesisConfig:: { balances: self.balances.into() } .assimilate_storage(&mut t) .unwrap(); @@ -137,3 +190,59 @@ where ::RuntimeOrigin::signed(account_id.into()) } } + +/// Helper function which emulates opening HRMP channel which is needed for XcmpQueue xcm router to pass +pub fn mock_open_hrmp_channel< + C: cumulus_pallet_parachain_system::Config, + T: ProvideInherent>, +>( + sender: ParaId, + recipient: ParaId, +) { + let n = 1_u32; + let mut sproof_builder = RelayStateSproofBuilder::default(); + sproof_builder.para_id = sender; + sproof_builder.hrmp_channels.insert( + HrmpChannelId { sender, recipient }, + AbridgedHrmpChannel { + max_capacity: 10, + max_total_size: 10_000_000_u32, + max_message_size: 10_000_000_u32, + msg_count: 10, + total_size: 10_000_000_u32, + mqc_head: None, + }, + ); + sproof_builder.hrmp_egress_channel_index = Some(vec![recipient]); + + let (relay_parent_storage_root, relay_chain_state) = sproof_builder.into_state_root_and_proof(); + let vfp = PersistedValidationData { + relay_parent_number: n as RelayChainBlockNumber, + relay_parent_storage_root, + ..Default::default() + }; + // It is insufficient to push the validation function params + // to storage; they must also be included in the inherent data. + let inherent_data = { + let mut inherent_data = InherentData::default(); + let system_inherent_data = ParachainInherentData { + validation_data: vfp.clone(), + relay_chain_state, + downward_messages: Default::default(), + horizontal_messages: Default::default(), + }; + inherent_data + .put_data( + cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER, + &system_inherent_data, + ) + .expect("failed to put VFP inherent"); + inherent_data + }; + + // execute the block + T::create_inherent(&inherent_data) + .expect("got an inherent") + .dispatch_bypass_filter(RawOrigin::None.into()) + .expect("dispatch succeeded"); +} diff --git a/parachains/runtimes/assets/westmint/src/lib.rs b/parachains/runtimes/assets/westmint/src/lib.rs index d446d4807d..8b1d174f23 100644 --- a/parachains/runtimes/assets/westmint/src/lib.rs +++ b/parachains/runtimes/assets/westmint/src/lib.rs @@ -87,7 +87,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westmint"), impl_name: create_runtime_str!("westmint"), authoring_version: 1, - spec_version: 9300, + spec_version: 9301, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 8,