From 568231a9a85d94954c002532a0f4351a3bb59e83 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Date: Mon, 6 Jan 2025 14:52:07 +0100 Subject: [PATCH] [core-fellowship] Add permissionless import_member (#7030) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Add call `import_member` to the core-fellowship pallet. - Move common logic between `import` and `import_member` into `do_import`. ## `import_member` Can be used to induct an arbitrary collective member and is callable by any signed origin. Pays no fees upon success. This is useful in the case that members did not induct themselves and are idling on their rank. --------- Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: command-bot <> --- .../pallet_core_fellowship_ambassador_core.rs | 160 +++++++++------ .../pallet_core_fellowship_fellowship_core.rs | 183 +++++++++++------- prdoc/pr_7030.prdoc | 24 +++ .../frame/core-fellowship/src/benchmarking.rs | 18 ++ substrate/frame/core-fellowship/src/lib.rs | 67 +++++-- .../core-fellowship/src/tests/integration.rs | 38 +++- .../frame/core-fellowship/src/tests/unit.rs | 62 ++++++ .../frame/core-fellowship/src/weights.rs | 71 ++++--- 8 files changed, 448 insertions(+), 175 deletions(-) create mode 100644 prdoc/pr_7030.prdoc diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs index 6bedfcc7e01..4d092ec8031 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs @@ -1,4 +1,4 @@ -// Copyright Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // This file is part of Cumulus. // Cumulus is free software: you can redistribute it and/or modify @@ -16,25 +16,29 @@ //! Autogenerated weights for `pallet_core_fellowship` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-11, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `cob`, CPU: `<UNKNOWN>` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-polkadot-dev")`, DB CACHE: 1024 +//! HOSTNAME: `623e9e4b814e`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// frame-omni-bencher +// v1 // benchmark // pallet -// --chain=collectives-polkadot-dev -// --wasm-execution=compiled -// --pallet=pallet_core_fellowship // --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./file_header.txt -// --output=./parachains/runtimes/collectives/collectives-polkadot/src/weights/ +// --runtime=target/production/wbuild/collectives-westend-runtime/collectives_westend_runtime.wasm +// --pallet=pallet_core_fellowship +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --no-storage-info +// --no-min-squares +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -48,25 +52,26 @@ use core::marker::PhantomData; pub struct WeightInfo<T>(PhantomData<T>); impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo<T> { /// Storage: `AmbassadorCore::Params` (r:0 w:1) - /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) fn set_params() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(11_000_000, 0) + // Minimum execution time: 9_131_000 picoseconds. + Weight::from_parts(9_371_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `AmbassadorCore::Params` (r:0 w:1) - /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCore::Params` (r:1 w:1) + /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) fn set_partial_params() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(11_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `471` + // Estimated: `1853` + // Minimum execution time: 18_375_000 picoseconds. + Weight::from_parts(18_872_000, 0) + .saturating_add(Weight::from_parts(0, 1853)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `AmbassadorCore::Member` (r:1 w:1) @@ -74,44 +79,48 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Storage: `AmbassadorCollective::Members` (r:1 w:1) /// Proof: `AmbassadorCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCore::Params` (r:1 w:0) - /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCollective::MemberCount` (r:1 w:1) /// Proof: `AmbassadorCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `AmbassadorCollective::IdToIndex` (r:1 w:0) + /// Storage: `AmbassadorCollective::IdToIndex` (r:1 w:1) /// Proof: `AmbassadorCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCore::MemberEvidence` (r:1 w:1) /// Proof: `AmbassadorCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCollective::IndexToId` (r:0 w:1) + /// Proof: `AmbassadorCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `66011` + // Measured: `66402` // Estimated: `69046` - // Minimum execution time: 96_000_000 picoseconds. - Weight::from_parts(111_000_000, 0) + // Minimum execution time: 156_752_000 picoseconds. + Weight::from_parts(164_242_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `AmbassadorCore::Member` (r:1 w:1) /// Proof: `AmbassadorCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCollective::Members` (r:1 w:1) /// Proof: `AmbassadorCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCore::Params` (r:1 w:0) - /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCollective::MemberCount` (r:1 w:1) /// Proof: `AmbassadorCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `AmbassadorCollective::IdToIndex` (r:1 w:0) + /// Storage: `AmbassadorCollective::IdToIndex` (r:1 w:1) /// Proof: `AmbassadorCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCore::MemberEvidence` (r:1 w:1) /// Proof: `AmbassadorCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCollective::IndexToId` (r:0 w:1) + /// Proof: `AmbassadorCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_demote() -> Weight { // Proof Size summary in bytes: - // Measured: `66121` + // Measured: `66512` // Estimated: `69046` - // Minimum execution time: 99_000_000 picoseconds. - Weight::from_parts(116_000_000, 0) + // Minimum execution time: 158_877_000 picoseconds. + Weight::from_parts(165_228_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `AmbassadorCollective::Members` (r:1 w:0) /// Proof: `AmbassadorCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) @@ -121,8 +130,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `360` // Estimated: `3514` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 25_056_000 picoseconds. + Weight::from_parts(26_028_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -141,8 +150,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `118` // Estimated: `3514` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(36_000_000, 0) + // Minimum execution time: 34_784_000 picoseconds. + Weight::from_parts(35_970_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(5)) @@ -152,7 +161,7 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Storage: `AmbassadorCore::Member` (r:1 w:1) /// Proof: `AmbassadorCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCore::Params` (r:1 w:0) - /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCollective::MemberCount` (r:1 w:1) /// Proof: `AmbassadorCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) /// Storage: `AmbassadorCore::MemberEvidence` (r:1 w:1) @@ -163,25 +172,40 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Proof: `AmbassadorCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn promote() -> Weight { // Proof Size summary in bytes: - // Measured: `65989` + // Measured: `66055` // Estimated: `69046` - // Minimum execution time: 95_000_000 picoseconds. - Weight::from_parts(110_000_000, 0) + // Minimum execution time: 147_616_000 picoseconds. + Weight::from_parts(154_534_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(6)) } + /// Storage: `AmbassadorCollective::Members` (r:1 w:1) + /// Proof: `AmbassadorCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCore::Member` (r:1 w:1) + /// Proof: `AmbassadorCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCollective::MemberCount` (r:9 w:9) + /// Proof: `AmbassadorCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCore::MemberEvidence` (r:1 w:1) + /// Proof: `AmbassadorCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCollective::IndexToId` (r:0 w:9) + /// Proof: `AmbassadorCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCollective::IdToIndex` (r:0 w:9) + /// Proof: `AmbassadorCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// The range of component `r` is `[1, 9]`. + /// The range of component `r` is `[1, 9]`. fn promote_fast(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `16844` - // Estimated: `19894 + r * (2489 ±0)` - // Minimum execution time: 45_065_000 picoseconds. - Weight::from_parts(34_090_392, 19894) - // Standard Error: 18_620 - .saturating_add(Weight::from_parts(13_578_046, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Measured: `65968` + // Estimated: `69046 + r * (2489 ±0)` + // Minimum execution time: 138_323_000 picoseconds. + Weight::from_parts(125_497_264, 0) + .saturating_add(Weight::from_parts(0, 69046)) + // Standard Error: 56_050 + .saturating_add(Weight::from_parts(19_863_853, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2489).saturating_mul(r.into())) } @@ -193,10 +217,10 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Proof: `AmbassadorCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) fn offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `331` + // Measured: `265` // Estimated: `3514` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 26_903_000 picoseconds. + Weight::from_parts(27_645_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -209,8 +233,22 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `285` // Estimated: `3514` - // Minimum execution time: 20_000_000 picoseconds. - Weight::from_parts(21_000_000, 0) + // Minimum execution time: 23_286_000 picoseconds. + Weight::from_parts(23_848_000, 0) + .saturating_add(Weight::from_parts(0, 3514)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `AmbassadorCore::Member` (r:1 w:1) + /// Proof: `AmbassadorCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `AmbassadorCollective::Members` (r:1 w:0) + /// Proof: `AmbassadorCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + fn import_member() -> Weight { + // Proof Size summary in bytes: + // Measured: `285` + // Estimated: `3514` + // Minimum execution time: 23_239_000 picoseconds. + Weight::from_parts(23_684_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -225,8 +263,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `65967` // Estimated: `69046` - // Minimum execution time: 78_000_000 picoseconds. - Weight::from_parts(104_000_000, 0) + // Minimum execution time: 125_987_000 picoseconds. + Weight::from_parts(130_625_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -239,8 +277,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `151` // Estimated: `69046` - // Minimum execution time: 43_000_000 picoseconds. - Weight::from_parts(44_000_000, 0) + // Minimum execution time: 104_431_000 picoseconds. + Weight::from_parts(106_646_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs index 05014e273f0..acb1f82985d 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs @@ -1,39 +1,44 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 +// This file is part of Cumulus. -// 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. +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>. //! Autogenerated weights for `pallet_core_fellowship` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-11, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `cob`, CPU: `<UNKNOWN>` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-polkadot-dev")`, DB CACHE: 1024 +//! HOSTNAME: `623e9e4b814e`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// frame-omni-bencher +// v1 // benchmark // pallet -// --chain=collectives-polkadot-dev -// --wasm-execution=compiled -// --pallet=pallet_core_fellowship // --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./file_header.txt -// --output=./parachains/runtimes/collectives/collectives-polkadot/src/weights/ +// --runtime=target/production/wbuild/collectives-westend-runtime/collectives_westend_runtime.wasm +// --pallet=pallet_core_fellowship +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --no-storage-info +// --no-min-squares +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,25 +52,26 @@ use core::marker::PhantomData; pub struct WeightInfo<T>(PhantomData<T>); impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo<T> { /// Storage: `FellowshipCore::Params` (r:0 w:1) - /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) fn set_params() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 9_115_000 picoseconds. + Weight::from_parts(9_523_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `FellowshipCore::Params` (r:0 w:1) - /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCore::Params` (r:1 w:1) + /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) fn set_partial_params() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `504` + // Estimated: `1853` + // Minimum execution time: 18_294_000 picoseconds. + Weight::from_parts(18_942_000, 0) + .saturating_add(Weight::from_parts(0, 1853)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `FellowshipCore::Member` (r:1 w:1) @@ -73,44 +79,48 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Storage: `FellowshipCollective::Members` (r:1 w:1) /// Proof: `FellowshipCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `FellowshipCore::Params` (r:1 w:0) - /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) /// Storage: `FellowshipCollective::MemberCount` (r:1 w:1) /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `FellowshipCollective::IdToIndex` (r:1 w:0) + /// Storage: `FellowshipCollective::IdToIndex` (r:1 w:1) /// Proof: `FellowshipCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// Storage: `FellowshipCore::MemberEvidence` (r:1 w:1) /// Proof: `FellowshipCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCollective::IndexToId` (r:0 w:1) + /// Proof: `FellowshipCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `66144` + // Measured: `66535` // Estimated: `69046` - // Minimum execution time: 109_000_000 picoseconds. - Weight::from_parts(125_000_000, 0) + // Minimum execution time: 152_823_000 picoseconds. + Weight::from_parts(158_737_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `FellowshipCore::Member` (r:1 w:1) /// Proof: `FellowshipCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) /// Storage: `FellowshipCollective::Members` (r:1 w:1) /// Proof: `FellowshipCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `FellowshipCore::Params` (r:1 w:0) - /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) /// Storage: `FellowshipCollective::MemberCount` (r:1 w:1) /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `FellowshipCollective::IdToIndex` (r:1 w:0) + /// Storage: `FellowshipCollective::IdToIndex` (r:1 w:1) /// Proof: `FellowshipCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// Storage: `FellowshipCore::MemberEvidence` (r:1 w:1) /// Proof: `FellowshipCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCollective::IndexToId` (r:0 w:1) + /// Proof: `FellowshipCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_demote() -> Weight { // Proof Size summary in bytes: - // Measured: `66254` + // Measured: `66645` // Estimated: `69046` - // Minimum execution time: 112_000_000 picoseconds. - Weight::from_parts(114_000_000, 0) + // Minimum execution time: 157_605_000 picoseconds. + Weight::from_parts(162_341_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `FellowshipCollective::Members` (r:1 w:0) /// Proof: `FellowshipCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) @@ -120,8 +130,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `493` // Estimated: `3514` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(27_000_000, 0) + // Minimum execution time: 25_194_000 picoseconds. + Weight::from_parts(26_262_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -140,8 +150,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `251` // Estimated: `3514` - // Minimum execution time: 35_000_000 picoseconds. - Weight::from_parts(36_000_000, 0) + // Minimum execution time: 35_479_000 picoseconds. + Weight::from_parts(36_360_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(5)) @@ -151,7 +161,7 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Storage: `FellowshipCore::Member` (r:1 w:1) /// Proof: `FellowshipCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) /// Storage: `FellowshipCore::Params` (r:1 w:0) - /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) /// Storage: `FellowshipCollective::MemberCount` (r:1 w:1) /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) /// Storage: `FellowshipCore::MemberEvidence` (r:1 w:1) @@ -162,25 +172,40 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Proof: `FellowshipCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn promote() -> Weight { // Proof Size summary in bytes: - // Measured: `66122` + // Measured: `66188` // Estimated: `69046` - // Minimum execution time: 97_000_000 picoseconds. - Weight::from_parts(129_000_000, 0) + // Minimum execution time: 147_993_000 picoseconds. + Weight::from_parts(153_943_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(6)) } + /// Storage: `FellowshipCollective::Members` (r:1 w:1) + /// Proof: `FellowshipCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCore::Member` (r:1 w:1) + /// Proof: `FellowshipCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCollective::MemberCount` (r:9 w:9) + /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCore::MemberEvidence` (r:1 w:1) + /// Proof: `FellowshipCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCollective::IndexToId` (r:0 w:9) + /// Proof: `FellowshipCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCollective::IdToIndex` (r:0 w:9) + /// Proof: `FellowshipCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// The range of component `r` is `[1, 9]`. + /// The range of component `r` is `[1, 9]`. fn promote_fast(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `16844` - // Estimated: `19894 + r * (2489 ±0)` - // Minimum execution time: 45_065_000 picoseconds. - Weight::from_parts(34_090_392, 19894) - // Standard Error: 18_620 - .saturating_add(Weight::from_parts(13_578_046, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Measured: `66101` + // Estimated: `69046 + r * (2489 ±0)` + // Minimum execution time: 138_444_000 picoseconds. + Weight::from_parts(125_440_035, 0) + .saturating_add(Weight::from_parts(0, 69046)) + // Standard Error: 55_452 + .saturating_add(Weight::from_parts(19_946_954, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2489).saturating_mul(r.into())) } @@ -192,10 +217,10 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< /// Proof: `FellowshipCore::MemberEvidence` (`max_values`: None, `max_size`: Some(65581), added: 68056, mode: `MaxEncodedLen`) fn offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `464` + // Measured: `398` // Estimated: `3514` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 27_392_000 picoseconds. + Weight::from_parts(28_134_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -208,8 +233,22 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `418` // Estimated: `3514` - // Minimum execution time: 20_000_000 picoseconds. - Weight::from_parts(24_000_000, 0) + // Minimum execution time: 23_523_000 picoseconds. + Weight::from_parts(24_046_000, 0) + .saturating_add(Weight::from_parts(0, 3514)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `FellowshipCore::Member` (r:1 w:1) + /// Proof: `FellowshipCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `FellowshipCollective::Members` (r:1 w:0) + /// Proof: `FellowshipCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + fn import_member() -> Weight { + // Proof Size summary in bytes: + // Measured: `418` + // Estimated: `3514` + // Minimum execution time: 23_369_000 picoseconds. + Weight::from_parts(24_088_000, 0) .saturating_add(Weight::from_parts(0, 3514)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -224,8 +263,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `66100` // Estimated: `69046` - // Minimum execution time: 89_000_000 picoseconds. - Weight::from_parts(119_000_000, 0) + // Minimum execution time: 127_137_000 picoseconds. + Weight::from_parts(131_638_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -238,8 +277,8 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `184` // Estimated: `69046` - // Minimum execution time: 43_000_000 picoseconds. - Weight::from_parts(52_000_000, 0) + // Minimum execution time: 103_212_000 picoseconds. + Weight::from_parts(105_488_000, 0) .saturating_add(Weight::from_parts(0, 69046)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/prdoc/pr_7030.prdoc b/prdoc/pr_7030.prdoc new file mode 100644 index 00000000000..3b1f7be558d --- /dev/null +++ b/prdoc/pr_7030.prdoc @@ -0,0 +1,24 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "[core-fellowship] Add permissionless import_member" + +doc: + - audience: [Runtime Dev, Runtime User] + description: | + Changes: + - Add call `import_member` to the core-fellowship pallet. + - Move common logic between `import` and `import_member` into `do_import`. + + This is a minor change as to not impact UI and downstream integration. + + ## `import_member` + + Can be used to induct an arbitrary collective member and is callable by any signed origin. Pays no fees upon success. + This is useful in the case that members did not induct themselves and are idling on their rank. + +crates: +- name: pallet-core-fellowship + bump: major +- name: collectives-westend-runtime + bump: patch diff --git a/substrate/frame/core-fellowship/src/benchmarking.rs b/substrate/frame/core-fellowship/src/benchmarking.rs index adb8a4a091b..ac0d489953c 100644 --- a/substrate/frame/core-fellowship/src/benchmarking.rs +++ b/substrate/frame/core-fellowship/src/benchmarking.rs @@ -50,6 +50,7 @@ mod benchmarks { for _ in 0..rank { T::Members::promote(&member)?; } + #[allow(deprecated)] CoreFellowship::<T, I>::import(RawOrigin::Signed(member.clone()).into())?; Ok(member) } @@ -260,6 +261,23 @@ mod benchmarks { Ok(()) } + #[benchmark] + fn import_member() -> Result<(), BenchmarkError> { + let member = account("member", 0, SEED); + let sender = account("sender", 0, SEED); + + T::Members::induct(&member)?; + T::Members::promote(&member)?; + + assert!(!Member::<T, I>::contains_key(&member)); + + #[extrinsic_call] + _(RawOrigin::Signed(sender), member.clone()); + + assert!(Member::<T, I>::contains_key(&member)); + Ok(()) + } + #[benchmark] fn approve() -> Result<(), BenchmarkError> { let member = make_member::<T, I>(1)?; diff --git a/substrate/frame/core-fellowship/src/lib.rs b/substrate/frame/core-fellowship/src/lib.rs index c61447e3628..22ba63b2616 100644 --- a/substrate/frame/core-fellowship/src/lib.rs +++ b/substrate/frame/core-fellowship/src/lib.rs @@ -21,6 +21,7 @@ //! This only handles members of non-zero rank. //! //! # Process Flow +//! //! - Begin with a call to `induct`, where some privileged origin (perhaps a pre-existing member of //! `rank > 1`) is able to make a candidate from an account and introduce it to be tracked in this //! pallet in order to allow evidence to be submitted and promotion voted on. @@ -36,8 +37,9 @@ //! `bump` to demote the candidate by one rank. //! - If a candidate fails to be promoted to a member within the `offboard_timeout` period, then //! anyone may call `bump` to remove the account's candidacy. -//! - Pre-existing members may call `import` to have their rank recognised and be inducted into this -//! pallet (to gain a salary and allow for eventual promotion). +//! - Pre-existing members may call `import_member` on themselves (formerly `import`) to have their +//! rank recognised and be inducted into this pallet (to gain a salary and allow for eventual +//! promotion). //! - If, externally to this pallet, a member or candidate has their rank removed completely, then //! `offboard` may be called to remove them entirely from this pallet. //! @@ -585,28 +587,44 @@ pub mod pallet { Ok(if replaced { Pays::Yes } else { Pays::No }.into()) } - /// Introduce an already-ranked individual of the collective into this pallet. The rank may - /// still be zero. + /// Introduce an already-ranked individual of the collective into this pallet. /// - /// This resets `last_proof` to the current block and `last_promotion` will be set to zero, - /// thereby delaying any automatic demotion but allowing immediate promotion. + /// The rank may still be zero. This resets `last_proof` to the current block and + /// `last_promotion` will be set to zero, thereby delaying any automatic demotion but + /// allowing immediate promotion. /// /// - `origin`: A signed origin of a ranked, but not tracked, account. #[pallet::weight(T::WeightInfo::import())] #[pallet::call_index(8)] + #[deprecated = "Use `import_member` instead"] + #[allow(deprecated)] // Otherwise FRAME will complain about using something deprecated. pub fn import(origin: OriginFor<T>) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - ensure!(!Member::<T, I>::contains_key(&who), Error::<T, I>::AlreadyInducted); - let rank = T::Members::rank_of(&who).ok_or(Error::<T, I>::Unranked)?; + Self::do_import(who)?; - let now = frame_system::Pallet::<T>::block_number(); - Member::<T, I>::insert( - &who, - MemberStatus { is_active: true, last_promotion: 0u32.into(), last_proof: now }, - ); - Self::deposit_event(Event::<T, I>::Imported { who, rank }); + Ok(Pays::No.into()) // Successful imports are free + } - Ok(Pays::No.into()) + /// Introduce an already-ranked individual of the collective into this pallet. + /// + /// The rank may still be zero. Can be called by anyone on any collective member - including + /// the sender. + /// + /// This resets `last_proof` to the current block and `last_promotion` will be set to zero, + /// thereby delaying any automatic demotion but allowing immediate promotion. + /// + /// - `origin`: A signed origin of a ranked, but not tracked, account. + /// - `who`: The account ID of the collective member to be inducted. + #[pallet::weight(T::WeightInfo::set_partial_params())] + #[pallet::call_index(11)] + pub fn import_member( + origin: OriginFor<T>, + who: T::AccountId, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + Self::do_import(who)?; + + Ok(Pays::No.into()) // Successful imports are free } /// Set the parameters partially. @@ -661,6 +679,24 @@ pub mod pallet { } } } + + /// Import `who` into the core-fellowship pallet. + /// + /// `who` must be a member of the collective but *not* already imported. + pub(crate) fn do_import(who: T::AccountId) -> DispatchResult { + ensure!(!Member::<T, I>::contains_key(&who), Error::<T, I>::AlreadyInducted); + let rank = T::Members::rank_of(&who).ok_or(Error::<T, I>::Unranked)?; + + let now = frame_system::Pallet::<T>::block_number(); + Member::<T, I>::insert( + &who, + MemberStatus { is_active: true, last_promotion: 0u32.into(), last_proof: now }, + ); + Self::deposit_event(Event::<T, I>::Imported { who, rank }); + + Ok(()) + } + /// Convert a rank into a `0..RANK_COUNT` index suitable for the arrays in Params. /// /// Rank 1 becomes index 0, rank `RANK_COUNT` becomes index `RANK_COUNT - 1`. Any rank not @@ -766,6 +802,7 @@ impl<T: Config<I>, I: 'static> pallet_ranked_collective::BenchmarkSetup<<T as frame_system::Config>::AccountId> for Pallet<T, I> { fn ensure_member(who: &<T as frame_system::Config>::AccountId) { + #[allow(deprecated)] Self::import(frame_system::RawOrigin::Signed(who.clone()).into()).unwrap(); } } diff --git a/substrate/frame/core-fellowship/src/tests/integration.rs b/substrate/frame/core-fellowship/src/tests/integration.rs index 7a48ed9783e..b2149336547 100644 --- a/substrate/frame/core-fellowship/src/tests/integration.rs +++ b/substrate/frame/core-fellowship/src/tests/integration.rs @@ -17,8 +17,10 @@ //! Integration test together with the ranked-collective pallet. +#![allow(deprecated)] + use frame_support::{ - assert_noop, assert_ok, derive_impl, hypothetically, ord_parameter_types, + assert_noop, assert_ok, derive_impl, hypothetically, hypothetically_ok, ord_parameter_types, pallet_prelude::Weight, parameter_types, traits::{ConstU16, EitherOf, IsInVec, MapSuccess, NoOpPoll, TryMapSuccess}, @@ -170,6 +172,37 @@ fn evidence(e: u32) -> Evidence<Test, ()> { .expect("Static length matches") } +#[test] +fn import_simple_works() { + new_test_ext().execute_with(|| { + for i in 0u16..9 { + let acc = i as u64; + + // Does not work yet + assert_noop!(CoreFellowship::import(signed(acc)), Error::<Test>::Unranked); + assert_noop!( + CoreFellowship::import_member(signed(acc + 1), acc), + Error::<Test>::Unranked + ); + + assert_ok!(Club::add_member(RuntimeOrigin::root(), acc)); + promote_n_times(acc, i); + + hypothetically_ok!(CoreFellowship::import(signed(acc))); + hypothetically_ok!(CoreFellowship::import_member(signed(acc), acc)); + // Works from other accounts + assert_ok!(CoreFellowship::import_member(signed(acc + 1), acc)); + + // Does not work again + assert_noop!(CoreFellowship::import(signed(acc)), Error::<Test>::AlreadyInducted); + assert_noop!( + CoreFellowship::import_member(signed(acc + 1), acc), + Error::<Test>::AlreadyInducted + ); + } + }); +} + #[test] fn swap_simple_works() { new_test_ext().execute_with(|| { @@ -178,7 +211,8 @@ fn swap_simple_works() { assert_ok!(Club::add_member(RuntimeOrigin::root(), acc)); promote_n_times(acc, i); - assert_ok!(CoreFellowship::import(signed(acc))); + hypothetically_ok!(CoreFellowship::import(signed(acc))); + assert_ok!(CoreFellowship::import_member(signed(acc), acc)); // Swapping normally works: assert_ok!(Club::exchange_member(RuntimeOrigin::root(), acc, acc + 10)); diff --git a/substrate/frame/core-fellowship/src/tests/unit.rs b/substrate/frame/core-fellowship/src/tests/unit.rs index 11d1ea9fe5b..f4418ed439d 100644 --- a/substrate/frame/core-fellowship/src/tests/unit.rs +++ b/substrate/frame/core-fellowship/src/tests/unit.rs @@ -17,6 +17,8 @@ //! The crate's tests. +#![allow(deprecated)] + use std::collections::BTreeMap; use core::cell::RefCell; @@ -222,6 +224,66 @@ fn set_partial_params_works() { }); } +#[test] +fn import_member_works() { + new_test_ext().execute_with(|| { + assert_noop!(CoreFellowship::import_member(signed(0), 0), Error::<Test>::Unranked); + assert_noop!(CoreFellowship::import(signed(0)), Error::<Test>::Unranked); + + // Make induction work: + set_rank(0, 1); + assert!(!Member::<Test>::contains_key(0), "not yet imported"); + + // `import_member` can be used to induct ourselves: + hypothetically!({ + assert_ok!(CoreFellowship::import_member(signed(0), 0)); + assert!(Member::<Test>::contains_key(0), "got imported"); + + // Twice does not work: + assert_noop!( + CoreFellowship::import_member(signed(0), 0), + Error::<Test>::AlreadyInducted + ); + assert_noop!(CoreFellowship::import(signed(0)), Error::<Test>::AlreadyInducted); + }); + + // But we could have also used `import`: + hypothetically!({ + assert_ok!(CoreFellowship::import(signed(0))); + assert!(Member::<Test>::contains_key(0), "got imported"); + + // Twice does not work: + assert_noop!( + CoreFellowship::import_member(signed(0), 0), + Error::<Test>::AlreadyInducted + ); + assert_noop!(CoreFellowship::import(signed(0)), Error::<Test>::AlreadyInducted); + }); + }); +} + +#[test] +fn import_member_same_as_import() { + new_test_ext().execute_with(|| { + for rank in 0..=9 { + set_rank(0, rank); + + let import_root = hypothetically!({ + assert_ok!(CoreFellowship::import(signed(0))); + sp_io::storage::root(sp_runtime::StateVersion::V1) + }); + + let import_member_root = hypothetically!({ + assert_ok!(CoreFellowship::import_member(signed(1), 0)); + sp_io::storage::root(sp_runtime::StateVersion::V1) + }); + + // `import` and `import_member` do exactly the same thing. + assert_eq!(import_root, import_member_root); + } + }); +} + #[test] fn induct_works() { new_test_ext().execute_with(|| { diff --git a/substrate/frame/core-fellowship/src/weights.rs b/substrate/frame/core-fellowship/src/weights.rs index 9bca8cb5609..e6381c854d3 100644 --- a/substrate/frame/core-fellowship/src/weights.rs +++ b/substrate/frame/core-fellowship/src/weights.rs @@ -61,6 +61,7 @@ pub trait WeightInfo { fn promote_fast(r: u32, ) -> Weight; fn offboard() -> Weight; fn import() -> Weight; + fn import_member() -> Weight; fn approve() -> Weight; fn submit_evidence() -> Weight; } @@ -76,7 +77,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `0` // Minimum execution time: 6_652_000 picoseconds. Weight::from_parts(7_082_000, 0) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `CoreFellowship::Params` (r:1 w:1) /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(368), added: 863, mode: `MaxEncodedLen`) @@ -86,8 +87,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `1853` // Minimum execution time: 12_485_000 picoseconds. Weight::from_parts(12_784_000, 1853) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `CoreFellowship::Member` (r:1 w:1) /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) @@ -109,8 +110,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `19894` // Minimum execution time: 61_243_000 picoseconds. Weight::from_parts(63_033_000, 19894) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `CoreFellowship::Member` (r:1 w:1) /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) @@ -132,8 +133,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `19894` // Minimum execution time: 65_063_000 picoseconds. Weight::from_parts(67_047_000, 19894) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `RankedCollective::Members` (r:1 w:0) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) @@ -145,8 +146,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `3514` // Minimum execution time: 21_924_000 picoseconds. Weight::from_parts(22_691_000, 3514) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `CoreFellowship::Member` (r:1 w:1) /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) @@ -164,8 +165,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `3514` // Minimum execution time: 24_720_000 picoseconds. Weight::from_parts(25_580_000, 3514) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } /// Storage: `RankedCollective::Members` (r:1 w:1) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) @@ -187,8 +188,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `19894` // Minimum execution time: 58_481_000 picoseconds. Weight::from_parts(59_510_000, 19894) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `RankedCollective::Members` (r:1 w:1) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) @@ -211,10 +212,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { Weight::from_parts(42_220_685, 19894) // Standard Error: 18_061 .saturating_add(Weight::from_parts(13_858_309, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(3_u64)) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2489).saturating_mul(r.into())) } /// Storage: `RankedCollective::Members` (r:1 w:0) @@ -229,8 +230,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `3514` // Minimum execution time: 17_492_000 picoseconds. Weight::from_parts(18_324_000, 3514) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `CoreFellowship::Member` (r:1 w:1) /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) @@ -242,8 +243,18 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `3514` // Minimum execution time: 16_534_000 picoseconds. Weight::from_parts(17_046_000, 3514) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + fn import_member() -> Weight { + // Proof Size summary in bytes: + // Measured: `285` + // Estimated: `3514` + // Minimum execution time: 23_239_000 picoseconds. + Weight::from_parts(23_684_000, 0) + .saturating_add(Weight::from_parts(0, 3514)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `RankedCollective::Members` (r:1 w:0) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) @@ -257,8 +268,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `19894` // Minimum execution time: 42_264_000 picoseconds. Weight::from_parts(43_281_000, 19894) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `CoreFellowship::Member` (r:1 w:0) /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) @@ -270,8 +281,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Estimated: `19894` // Minimum execution time: 25_461_000 picoseconds. Weight::from_parts(26_014_000, 19894) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } @@ -454,6 +465,16 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + fn import_member() -> Weight { + // Proof Size summary in bytes: + // Measured: `285` + // Estimated: `3514` + // Minimum execution time: 23_239_000 picoseconds. + Weight::from_parts(23_684_000, 0) + .saturating_add(Weight::from_parts(0, 3514)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } /// Storage: `RankedCollective::Members` (r:1 w:0) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `CoreFellowship::Member` (r:1 w:1) -- GitLab