From 46dcafcee64fe4d8c722d071a4a0ca983fcc2f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20R=2E=20Bald=C3=A9?= Date: Fri, 13 Dec 2024 03:57:54 +0000 Subject: [PATCH 1/2] Add more integrations tests to People chains (#499) https://github.com/open-web3-stack/polkadot-ecosystem-tests relies on chopsticks to create E2E tests using periodically (roughly daily) obtained runtimes from production relay chains/system parachains. In particular, https://github.com/open-web3-stack/polkadot-ecosystem-tests/pull/63 does this for the People chains. In writing those tests, I was unable to use XCM to test `pallet_identity::{kill_identity/add_username_authority/remove_username_authority}`. I wrote this PR to replicate those tests at this layer, whose passing status falsify the hypothesis that there may have been an issue with the runtimes, and confirm that it was a problem with the way I wrote those tests. - [x] Does not require a CHANGELOG entry --- Cargo.lock | 2 + .../people/people-kusama/Cargo.toml | 3 + .../people/people-kusama/src/genesis.rs | 9 +- .../people/people-polkadot/Cargo.toml | 3 + .../people/people-polkadot/src/genesis.rs | 9 +- .../people-kusama/src/tests/governance.rs | 463 +++++++++++++++++- .../people-polkadot/src/tests/governance.rs | 461 ++++++++++++++++- 7 files changed, 946 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3117086cc..02c6d0e8ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9586,6 +9586,7 @@ dependencies = [ "emulated-integration-tests-common", "frame-support", "kusama-emulated-chain", + "kusama-runtime-constants", "parachains-common", "people-kusama-runtime", "sp-core 34.0.0", @@ -9696,6 +9697,7 @@ dependencies = [ "parachains-common", "people-polkadot-runtime", "polkadot-emulated-chain", + "polkadot-runtime-constants", "sp-core 34.0.0", ] diff --git a/integration-tests/emulated/chains/parachains/people/people-kusama/Cargo.toml b/integration-tests/emulated/chains/parachains/people/people-kusama/Cargo.toml index a72f24e626..f6bb6403ee 100644 --- a/integration-tests/emulated/chains/parachains/people/people-kusama/Cargo.toml +++ b/integration-tests/emulated/chains/parachains/people/people-kusama/Cargo.toml @@ -18,6 +18,9 @@ parachains-common = { workspace = true, default-features = true } cumulus-primitives-core = { workspace = true, default-features = true } emulated-integration-tests-common = { workspace = true } +# Runtimes +kusama-runtime-constants = { workspace = true, default-features = true } + # Local people-kusama-runtime = { workspace = true } kusama-emulated-chain = { workspace = true } diff --git a/integration-tests/emulated/chains/parachains/people/people-kusama/src/genesis.rs b/integration-tests/emulated/chains/parachains/people/people-kusama/src/genesis.rs index 6e034d6ebf..cca03c7d8e 100644 --- a/integration-tests/emulated/chains/parachains/people/people-kusama/src/genesis.rs +++ b/integration-tests/emulated/chains/parachains/people/people-kusama/src/genesis.rs @@ -18,14 +18,21 @@ use sp_core::storage::Storage; // Cumulus use cumulus_primitives_core::ParaId; -use emulated_integration_tests_common::{build_genesis_storage, collators, SAFE_XCM_VERSION}; +use emulated_integration_tests_common::{ + accounts, build_genesis_storage, collators, SAFE_XCM_VERSION, +}; +use kusama_runtime_constants::currency::UNITS as KSM; use parachains_common::Balance; +const ENDOWMENT: u128 = 1_000 * KSM; pub const PARA_ID: u32 = 1004; pub const ED: Balance = people_kusama_runtime::ExistentialDeposit::get(); pub fn genesis() -> Storage { let genesis_config = people_kusama_runtime::RuntimeGenesisConfig { + balances: people_kusama_runtime::BalancesConfig { + balances: accounts::init_balances().iter().cloned().map(|k| (k, ENDOWMENT)).collect(), + }, system: people_kusama_runtime::SystemConfig::default(), parachain_info: people_kusama_runtime::ParachainInfoConfig { parachain_id: ParaId::from(PARA_ID), diff --git a/integration-tests/emulated/chains/parachains/people/people-polkadot/Cargo.toml b/integration-tests/emulated/chains/parachains/people/people-polkadot/Cargo.toml index 8649747813..6414084696 100644 --- a/integration-tests/emulated/chains/parachains/people/people-polkadot/Cargo.toml +++ b/integration-tests/emulated/chains/parachains/people/people-polkadot/Cargo.toml @@ -18,6 +18,9 @@ parachains-common = { workspace = true, default-features = true } cumulus-primitives-core = { workspace = true, default-features = true } emulated-integration-tests-common = { workspace = true } +# Runtimes +polkadot-runtime-constants = { workspace = true, default-features = true } + # Local people-polkadot-runtime = { workspace = true } polkadot-emulated-chain = { workspace = true } diff --git a/integration-tests/emulated/chains/parachains/people/people-polkadot/src/genesis.rs b/integration-tests/emulated/chains/parachains/people/people-polkadot/src/genesis.rs index 93c6788ebb..177eaa64e2 100644 --- a/integration-tests/emulated/chains/parachains/people/people-polkadot/src/genesis.rs +++ b/integration-tests/emulated/chains/parachains/people/people-polkadot/src/genesis.rs @@ -18,14 +18,21 @@ use sp_core::storage::Storage; // Cumulus use cumulus_primitives_core::ParaId; -use emulated_integration_tests_common::{build_genesis_storage, collators, SAFE_XCM_VERSION}; +use emulated_integration_tests_common::{ + accounts, build_genesis_storage, collators, SAFE_XCM_VERSION, +}; use parachains_common::Balance; +use polkadot_runtime_constants::currency::UNITS as DOT; +const ENDOWMENT: u128 = 1_000 * DOT; pub const PARA_ID: u32 = 1004; pub const ED: Balance = people_polkadot_runtime::ExistentialDeposit::get(); pub fn genesis() -> Storage { let genesis_config = people_polkadot_runtime::RuntimeGenesisConfig { + balances: people_polkadot_runtime::BalancesConfig { + balances: accounts::init_balances().iter().cloned().map(|k| (k, ENDOWMENT)).collect(), + }, system: people_polkadot_runtime::SystemConfig::default(), parachain_info: people_polkadot_runtime::ParachainInfoConfig { parachain_id: ParaId::from(PARA_ID), diff --git a/integration-tests/emulated/tests/people/people-kusama/src/tests/governance.rs b/integration-tests/emulated/tests/people/people-kusama/src/tests/governance.rs index 8d06089947..be3b18acf9 100644 --- a/integration-tests/emulated/tests/people/people-kusama/src/tests/governance.rs +++ b/integration-tests/emulated/tests/people/people-kusama/src/tests/governance.rs @@ -14,8 +14,13 @@ // limitations under the License. use crate::*; -use frame_support::sp_runtime::traits::Dispatchable; +use emulated_integration_tests_common::accounts::{ALICE, BOB}; + +use frame_support::{sp_runtime::traits::Dispatchable, traits::ProcessMessageError}; use kusama_runtime::governance::pallet_custom_origins::Origin::GeneralAdmin as GeneralAdminOrigin; +use people_kusama_runtime::people::IdentityInfo; + +use pallet_identity::Data; #[test] fn relay_commands_add_registrar() { @@ -43,6 +48,9 @@ fn relay_commands_add_registrar() { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind, + // TODO: + // This and the below weight data in the XCM can be removed once XCMv5 is + // used. require_weight_at_most: Weight::from_parts(5_000_000_000, 500_000), call: add_registrar_call.encode().into(), } @@ -72,3 +80,456 @@ fn relay_commands_add_registrar() { }); } } + +#[test] +fn relay_commands_add_registrar_wrong_origin() { + let people_kusama_alice = PeopleKusama::account_id_of(ALICE); + + let (origin_kind, origin) = ( + OriginKind::SovereignAccount, + ::RuntimeOrigin::signed(people_kusama_alice), + ); + + let registrar: AccountId = [1; 32].into(); + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let add_registrar_call = + PeopleCall::Identity(pallet_identity::Call::::add_registrar { + account: registrar.into(), + }); + + let xcm_message = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(5_000_000_000, 500_000), + call: add_registrar_call.encode().into(), + } + ]))), + }); + + assert_ok!(xcm_message.dispatch(origin)); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); +} + +#[test] +fn relay_commands_kill_identity() { + // To kill an identity, first one must be set + PeopleKusama::execute_with(|| { + type PeopleRuntime = ::Runtime; + type PeopleRuntimeEvent = ::RuntimeEvent; + + let people_kusama_alice = + ::RuntimeOrigin::signed(PeopleKusama::account_id_of(ALICE)); + + let identity_info = IdentityInfo { + email: Data::Raw(b"test@test.io".to_vec().try_into().unwrap()), + ..Default::default() + }; + let identity: Box<::IdentityInformation> = + Box::new(identity_info); + + assert_ok!(::Identity::set_identity( + people_kusama_alice, + identity + )); + + assert_expected_events!( + PeopleKusama, + vec![ + PeopleRuntimeEvent::Identity(pallet_identity::Event::IdentitySet { .. }) => {}, + ] + ); + }); + + let (origin_kind, origin) = (OriginKind::Superuser, ::RuntimeOrigin::root()); + + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type PeopleCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleRuntime = ::Runtime; + + let kill_identity_call = + PeopleCall::Identity(pallet_identity::Call::::kill_identity { + target: people_kusama_runtime::MultiAddress::Id(PeopleKusama::account_id_of(ALICE)), + }); + + let xcm_message = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + // Making the weight's ref time any lower will prevent the XCM from triggering + // execution of the intended extrinsic on the People chain - beware of spurious + // test failure due to this. + require_weight_at_most: Weight::from_parts(11_000_000_000, 500_000), + call: kill_identity_call.encode().into(), + } + ]))), + }); + + assert_ok!(xcm_message.dispatch(origin)); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::Identity(pallet_identity::Event::IdentityKilled { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + }); +} + +#[test] +fn relay_commands_kill_identity_wrong_origin() { + let people_kusama_alice = PeopleKusama::account_id_of(BOB); + + let (origin_kind, origin) = ( + OriginKind::SovereignAccount, + ::RuntimeOrigin::signed(people_kusama_alice), + ); + + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type PeopleCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleRuntime = ::Runtime; + + let kill_identity_call = + PeopleCall::Identity(pallet_identity::Call::::kill_identity { + target: people_kusama_runtime::MultiAddress::Id(PeopleKusama::account_id_of(ALICE)), + }); + + let xcm_message = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(11_000_000_000, 500_000), + call: kill_identity_call.encode().into(), + } + ]))), + }); + + assert_ok!(xcm_message.dispatch(origin)); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); +} + +#[test] +fn relay_commands_add_remove_username_authority() { + let people_kusama_alice = PeopleKusama::account_id_of(ALICE); + let people_kusama_bob = PeopleKusama::account_id_of(BOB); + + let origins = vec![ + (OriginKind::Xcm, GeneralAdminOrigin.into(), "generaladmin"), + (OriginKind::Superuser, ::RuntimeOrigin::root(), "rootusername"), + ]; + for (origin_kind, origin, usr) in origins { + // First, add a username authority. + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let add_username_authority = PeopleCall::Identity(pallet_identity::Call::< + PeopleRuntime, + >::add_username_authority { + authority: people_kusama_runtime::MultiAddress::Id(people_kusama_alice.clone()), + suffix: b"suffix1".into(), + allocation: 10, + }); + + let add_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: add_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(add_authority_xcm_msg.dispatch(origin.clone())); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Check events system-parachain-side + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::Identity(pallet_identity::Event::AuthorityAdded { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + }); + + // Now, use the previously added username authority to concede a username to an account. + PeopleKusama::execute_with(|| { + type PeopleRuntimeEvent = ::RuntimeEvent; + + assert_ok!(::Identity::set_username_for( + ::RuntimeOrigin::signed(people_kusama_alice.clone()), + people_kusama_runtime::MultiAddress::Id(people_kusama_bob.clone()), + usr.to_owned().into_bytes(), + None, + )); + + assert_expected_events!( + PeopleKusama, + vec![ + PeopleRuntimeEvent::Identity(pallet_identity::Event::UsernameQueued { .. }) => {}, + ] + ); + }); + + // Accept the given username + PeopleKusama::execute_with(|| { + type PeopleRuntimeEvent = ::RuntimeEvent; + let full_username = [usr.to_owned(), ".suffix1".to_owned()].concat().into_bytes(); + + assert_ok!(::Identity::accept_username( + ::RuntimeOrigin::signed(people_kusama_bob.clone()), + full_username.try_into().unwrap(), + )); + + assert_expected_events!( + PeopleKusama, + vec![ + PeopleRuntimeEvent::Identity(pallet_identity::Event::UsernameSet { .. }) => {}, + ] + ); + }); + + // Now, remove the username authority with another privileged XCM call. + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let remove_username_authority = PeopleCall::Identity(pallet_identity::Call::< + PeopleRuntime, + >::remove_username_authority { + authority: people_kusama_runtime::MultiAddress::Id(people_kusama_alice.clone()), + }); + + let remove_authority_xcm_msg = + RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + // TODO: + // this and all other references to `require_weight_at_most` can be + // removed once XCMv5 is in use. + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: remove_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(remove_authority_xcm_msg.dispatch(origin)); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Final event check. + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::Identity(pallet_identity::Event::AuthorityRemoved { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + }); + } +} + +#[test] +fn relay_commands_add_remove_username_authority_wrong_origin() { + let people_kusama_alice = PeopleKusama::account_id_of(ALICE); + + let (origin_kind, origin) = ( + OriginKind::SovereignAccount, + ::RuntimeOrigin::signed(people_kusama_alice.clone()), + ); + + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let add_username_authority = + PeopleCall::Identity(pallet_identity::Call::::add_username_authority { + authority: people_kusama_runtime::MultiAddress::Id(people_kusama_alice.clone()), + suffix: b"suffix1".into(), + allocation: 10, + }); + + let add_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: add_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(add_authority_xcm_msg.dispatch(origin)); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Check events system-parachain-side + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); + + // Since the origin check is the very first instruction in `remove_username_authority`, an + // authority need not exist to test the safety of the origin check. + Kusama::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let remove_username_authority = PeopleCall::Identity(pallet_identity::Call::< + PeopleRuntime, + >::remove_username_authority { + authority: people_kusama_runtime::MultiAddress::Id(people_kusama_alice.clone()), + }); + + let remove_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: remove_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(remove_authority_xcm_msg + .dispatch(::RuntimeOrigin::signed(people_kusama_alice))); + + assert_expected_events!( + Kusama, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeopleKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeopleKusama, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); +} diff --git a/integration-tests/emulated/tests/people/people-polkadot/src/tests/governance.rs b/integration-tests/emulated/tests/people/people-polkadot/src/tests/governance.rs index 11ebf954a3..4c3ac649a9 100644 --- a/integration-tests/emulated/tests/people/people-polkadot/src/tests/governance.rs +++ b/integration-tests/emulated/tests/people/people-polkadot/src/tests/governance.rs @@ -14,9 +14,14 @@ // limitations under the License. use crate::*; -use frame_support::sp_runtime::traits::Dispatchable; +use emulated_integration_tests_common::accounts::{ALICE, BOB}; + +use frame_support::{sp_runtime::traits::Dispatchable, traits::ProcessMessageError}; +use people_polkadot_runtime::people::IdentityInfo; use polkadot_runtime::governance::pallet_custom_origins::Origin::GeneralAdmin as GeneralAdminOrigin; +use pallet_identity::Data; + #[test] fn relay_commands_add_registrar() { let origins = vec![ @@ -72,3 +77,457 @@ fn relay_commands_add_registrar() { }); } } + +#[test] +fn relay_commands_add_registrar_wrong_origin() { + let people_polkadot_alice = PeoplePolkadot::account_id_of(ALICE); + + let (origin_kind, origin) = ( + OriginKind::SovereignAccount, + ::RuntimeOrigin::signed(people_polkadot_alice), + ); + + let registrar: AccountId = [1; 32].into(); + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let add_registrar_call = + PeopleCall::Identity(pallet_identity::Call::::add_registrar { + account: registrar.into(), + }); + + let xcm_message = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(5_000_000_000, 500_000), + call: add_registrar_call.encode().into(), + } + ]))), + }); + + assert_ok!(xcm_message.dispatch(origin)); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); +} + +#[test] +fn relay_commands_kill_identity() { + // To kill an identity, first one must be set + PeoplePolkadot::execute_with(|| { + type PeopleRuntime = ::Runtime; + type PeopleRuntimeEvent = ::RuntimeEvent; + + let people_polkadot_alice = + ::RuntimeOrigin::signed(PeoplePolkadot::account_id_of(ALICE)); + + let identity_info = IdentityInfo { + email: Data::Raw(b"test@test.io".to_vec().try_into().unwrap()), + ..Default::default() + }; + let identity: Box<::IdentityInformation> = + Box::new(identity_info); + + assert_ok!(::Identity::set_identity( + people_polkadot_alice, + identity + )); + + assert_expected_events!( + PeoplePolkadot, + vec![ + PeopleRuntimeEvent::Identity(pallet_identity::Event::IdentitySet { .. }) => {}, + ] + ); + }); + + let (origin_kind, origin) = (OriginKind::Superuser, ::RuntimeOrigin::root()); + + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type PeopleCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleRuntime = ::Runtime; + + let kill_identity_call = + PeopleCall::Identity(pallet_identity::Call::::kill_identity { + target: people_polkadot_runtime::MultiAddress::Id(PeoplePolkadot::account_id_of( + ALICE, + )), + }); + + let xcm_message = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + // Making the weight's ref time any lower will prevent the XCM from triggering + // execution of the intended extrinsic on the People chain - beware of spurious + // test failure due to this. + require_weight_at_most: Weight::from_parts(11_000_000_000, 500_000), + call: kill_identity_call.encode().into(), + } + ]))), + }); + + assert_ok!(xcm_message.dispatch(origin)); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::Identity(pallet_identity::Event::IdentityKilled { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + }); +} + +#[test] +fn relay_commands_kill_identity_wrong_origin() { + let people_polkadot_alice = PeoplePolkadot::account_id_of(BOB); + + let (origin_kind, origin) = ( + OriginKind::SovereignAccount, + ::RuntimeOrigin::signed(people_polkadot_alice), + ); + + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type PeopleCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleRuntime = ::Runtime; + + let kill_identity_call = + PeopleCall::Identity(pallet_identity::Call::::kill_identity { + target: people_polkadot_runtime::MultiAddress::Id(PeoplePolkadot::account_id_of( + ALICE, + )), + }); + + let xcm_message = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(11_000_000_000, 500_000), + call: kill_identity_call.encode().into(), + } + ]))), + }); + + assert_ok!(xcm_message.dispatch(origin)); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); +} + +#[test] +fn relay_commands_add_remove_username_authority() { + let people_polkadot_alice = PeoplePolkadot::account_id_of(ALICE); + let people_polkadot_bob = PeoplePolkadot::account_id_of(BOB); + + let origins = vec![ + (OriginKind::Xcm, GeneralAdminOrigin.into(), "generaladmin"), + (OriginKind::Superuser, ::RuntimeOrigin::root(), "rootusername"), + ]; + for (origin_kind, origin, usr) in origins { + // First, add a username authority. + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let add_username_authority = PeopleCall::Identity(pallet_identity::Call::< + PeopleRuntime, + >::add_username_authority { + authority: people_polkadot_runtime::MultiAddress::Id(people_polkadot_alice.clone()), + suffix: b"suffix1".into(), + allocation: 10, + }); + + let add_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: add_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(add_authority_xcm_msg.dispatch(origin.clone())); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Check events system-parachain-side + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::Identity(pallet_identity::Event::AuthorityAdded { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + }); + + // Now, use the previously added username authority to concede a username to an account. + PeoplePolkadot::execute_with(|| { + type PeopleRuntimeEvent = ::RuntimeEvent; + + assert_ok!(::Identity::set_username_for( + ::RuntimeOrigin::signed(people_polkadot_alice.clone()), + people_polkadot_runtime::MultiAddress::Id(people_polkadot_bob.clone()), + usr.to_owned().into_bytes(), + None, + )); + + assert_expected_events!( + PeoplePolkadot, + vec![ + PeopleRuntimeEvent::Identity(pallet_identity::Event::UsernameQueued { .. }) => {}, + ] + ); + }); + + // Accept the given username + PeoplePolkadot::execute_with(|| { + type PeopleRuntimeEvent = ::RuntimeEvent; + let full_username = [usr.to_owned(), ".suffix1".to_owned()].concat().into_bytes(); + + assert_ok!(::Identity::accept_username( + ::RuntimeOrigin::signed(people_polkadot_bob.clone()), + full_username.try_into().unwrap(), + )); + + assert_expected_events!( + PeoplePolkadot, + vec![ + PeopleRuntimeEvent::Identity(pallet_identity::Event::UsernameSet { .. }) => {}, + ] + ); + }); + + // Now, remove the username authority with another privileged XCM call. + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let remove_username_authority = PeopleCall::Identity(pallet_identity::Call::< + PeopleRuntime, + >::remove_username_authority { + authority: people_polkadot_runtime::MultiAddress::Id(people_polkadot_alice.clone()), + }); + + let remove_authority_xcm_msg = + RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: remove_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(remove_authority_xcm_msg.dispatch(origin)); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Final event check. + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::Identity(pallet_identity::Event::AuthorityRemoved { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + }); + } +} + +#[test] +fn relay_commands_add_remove_username_authority_wrong_origin() { + let people_polkadot_alice = PeoplePolkadot::account_id_of(ALICE); + + let (origin_kind, origin) = ( + OriginKind::SovereignAccount, + ::RuntimeOrigin::signed(people_polkadot_alice.clone()), + ); + + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let add_username_authority = + PeopleCall::Identity(pallet_identity::Call::::add_username_authority { + authority: people_polkadot_runtime::MultiAddress::Id(people_polkadot_alice.clone()), + suffix: b"suffix1".into(), + allocation: 10, + }); + + let add_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: add_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(add_authority_xcm_msg.dispatch(origin)); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Check events system-parachain-side + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); + + // Since the origin check is the very first instruction in `remove_username_authority`, + // an authority need not exist to test the safety of the origin check. + Polkadot::execute_with(|| { + type Runtime = ::Runtime; + type RuntimeCall = ::RuntimeCall; + type RuntimeEvent = ::RuntimeEvent; + type PeopleCall = ::RuntimeCall; + type PeopleRuntime = ::Runtime; + + let remove_username_authority = PeopleCall::Identity(pallet_identity::Call::< + PeopleRuntime, + >::remove_username_authority { + authority: people_polkadot_runtime::MultiAddress::Id(people_polkadot_alice.clone()), + }); + + let remove_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { + dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), + message: bx!(VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(500_000_000, 500_000), + call: remove_username_authority.encode().into(), + } + ]))), + }); + + assert_ok!(remove_authority_xcm_msg + .dispatch(::RuntimeOrigin::signed(people_polkadot_alice))); + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeoplePolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PeoplePolkadot, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::ProcessingFailed { error: ProcessMessageError::Unsupported, .. }) => {}, + ] + ); + }); +} From c05f20fc97da9e8e2a0a56086900ff7f2d94ff84 Mon Sep 17 00:00:00 2001 From: Muharem Date: Mon, 16 Dec 2024 12:30:29 +0100 Subject: [PATCH 2/2] Kusama Treasury: remove funding to the Kappa Sigma Mu Society and disable burn (#507) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/polkadot-fellows/runtimes/issues/500 --------- Co-authored-by: Bastian Köcher --- CHANGELOG.md | 8 ++++++-- relay/kusama/src/lib.rs | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e970df2b..0eff501227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,18 @@ # Changelog +Changelog for the runtimes governed by the Polkadot Fellowship. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + ## [Unreleased] ### Added - Location conversion tests for relays and parachains ([polkadot-fellows/runtimes#487](https://github.com/polkadot-fellows/runtimes/pull/487)) -Changelog for the runtimes governed by the Polkadot Fellowship. +### Changed -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +- Kusama Treasury: remove funding to the Kappa Sigma Mu Society and disable burn ([polkadot-fellows/runtimes#507](https://github.com/polkadot-fellows/runtimes/pull/507)) #### From [#490](https://github.com/polkadot-fellows/runtimes/pull/490) diff --git a/relay/kusama/src/lib.rs b/relay/kusama/src/lib.rs index 98cf79f691..7649d2df0f 100644 --- a/relay/kusama/src/lib.rs +++ b/relay/kusama/src/lib.rs @@ -828,7 +828,7 @@ parameter_types! { pub const ProposalBondMinimum: Balance = 2000 * CENTS; pub const ProposalBondMaximum: Balance = GRAND; pub const SpendPeriod: BlockNumber = 6 * DAYS; - pub const Burn: Permill = Permill::from_perthousand(2); + pub const Burn: Permill = Permill::zero(); pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury @@ -852,7 +852,7 @@ impl pallet_treasury::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SpendPeriod = SpendPeriod; type Burn = Burn; - type BurnDestination = Society; + type BurnDestination = (); type MaxApprovals = MaxApprovals; type WeightInfo = weights::pallet_treasury::WeightInfo; type SpendFunds = Bounties;