diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_ambassador_collective.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_ambassador_collective.rs index 8f6aa583a41c..2882f15a8ebc 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_ambassador_collective.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_ambassador_collective.rs @@ -177,4 +177,7 @@ impl pallet_ranked_collective::WeightInfo for WeightInf fn exchange_member() -> Weight { todo!() } + fn add_member_to_rank(_r: u32, ) -> Weight { + todo!() + } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_fellowship_collective.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_fellowship_collective.rs index 6dfe9b88ff63..79b1039c917d 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_fellowship_collective.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_ranked_collective_fellowship_collective.rs @@ -176,4 +176,7 @@ impl pallet_ranked_collective::WeightInfo for WeightInf fn exchange_member() -> Weight { todo!() } + fn add_member_to_rank(_r: u32, ) -> Weight { + todo!() + } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs index ce9d5fcc0c71..8df8c863691d 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs @@ -189,4 +189,10 @@ impl pallet_ranked_collective::WeightInfo for WeightInf .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(10)) } + fn add_member_to_rank(r: u32, ) -> Weight { + Weight::from_parts(15_000_000, 3507) + // Standard Error: 1_000 + .saturating_add((Weight::from_parts(251_000, 0)).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } } diff --git a/prdoc/pr_4778.prdoc b/prdoc/pr_4778.prdoc new file mode 100644 index 000000000000..840dba46c456 --- /dev/null +++ b/prdoc/pr_4778.prdoc @@ -0,0 +1,13 @@ +# 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: Expose `add_memmber_to_rank` + +doc: + - audience: Runtime Dev + description: | + Fixes https://github.com/paritytech/polkadot-sdk/issues/262 + +crates: + - name: pallet-ranked-collective + bump: patch diff --git a/substrate/frame/ranked-collective/src/benchmarking.rs b/substrate/frame/ranked-collective/src/benchmarking.rs index 462f55a238d2..0ce2fa6ec32c 100644 --- a/substrate/frame/ranked-collective/src/benchmarking.rs +++ b/substrate/frame/ranked-collective/src/benchmarking.rs @@ -16,7 +16,6 @@ // limitations under the License. //! Staking pallet benchmarking. - use super::*; #[allow(unused_imports)] use crate::Pallet as RankedCollective; @@ -25,8 +24,8 @@ use frame_benchmarking::v1::{ account, benchmarks_instance_pallet, whitelisted_caller, BenchmarkError, }; use frame_support::{assert_ok, traits::UnfilteredDispatchable}; -use frame_system::RawOrigin as SystemOrigin; +use frame_system::RawOrigin as SystemOrigin; const SEED: u32 = 0; fn assert_last_event, I: 'static>(generic_event: >::RuntimeEvent) { @@ -181,5 +180,20 @@ benchmarks_instance_pallet! { assert_has_event::(Event::MemberExchanged { who, new_who }.into()); } + add_member_to_rank { + let r in 0 .. 10; + let rank = r as u16; + let who = account::("member-without-rank", 0, SEED); + let who_lookup = T::Lookup::unlookup(who.clone()); + let origin = + T::AddOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let call = Call::::add_member_to_rank { who: who_lookup, rank }; + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert_eq!(Members::::get(&who).unwrap().rank, rank); + assert_eq!(MemberCount::::get(0),1); + assert_eq!(MemberCount::::get(rank),1); + } + impl_benchmark_test_suite!(RankedCollective, crate::tests::ExtBuilder::default().build(), crate::tests::Test); } diff --git a/substrate/frame/ranked-collective/src/lib.rs b/substrate/frame/ranked-collective/src/lib.rs index ceaf03de2110..c1f4e5dcadde 100644 --- a/substrate/frame/ranked-collective/src/lib.rs +++ b/substrate/frame/ranked-collective/src/lib.rs @@ -713,6 +713,18 @@ pub mod pallet { Ok(()) } + + #[pallet::call_index(7)] + #[pallet::weight(T::WeightInfo::add_member_to_rank(*rank as u32))] + pub fn add_member_to_rank( + origin: OriginFor, + who: AccountIdLookupOf, + rank: Rank, + ) -> DispatchResult { + T::AddOrigin::ensure_origin(origin)?; + let who = T::Lookup::lookup(who)?; + Self::do_add_member_to_rank(who, rank, true) + } } #[pallet::hooks] diff --git a/substrate/frame/ranked-collective/src/tests.rs b/substrate/frame/ranked-collective/src/tests.rs index ad8b7d2a8018..aad04c96fa06 100644 --- a/substrate/frame/ranked-collective/src/tests.rs +++ b/substrate/frame/ranked-collective/src/tests.rs @@ -645,3 +645,20 @@ fn exchange_member_same_noops() { ); }); } + +#[test] +pub fn add_member_to_rank_work() { + ExtBuilder::default().build_and_execute(|| { + let max_rank = 4u16; + assert_ok!(Club::add_member_to_rank(RuntimeOrigin::root(), 2, max_rank)); + for i in 0..=max_rank { + assert_eq!(member_count(i), 1); + } + + //-- Should fail ---------------------------------------- + assert_noop!( + Club::add_member_to_rank(RuntimeOrigin::signed(1), 2, 1), + DispatchError::BadOrigin + ); + }) +} diff --git a/substrate/frame/ranked-collective/src/weights.rs b/substrate/frame/ranked-collective/src/weights.rs index e728635f2e72..29da15dd2269 100644 --- a/substrate/frame/ranked-collective/src/weights.rs +++ b/substrate/frame/ranked-collective/src/weights.rs @@ -58,6 +58,8 @@ pub trait WeightInfo { fn vote() -> Weight; fn cleanup_poll(n: u32, ) -> Weight; fn exchange_member() -> Weight; + fn add_member_to_rank(r: u32, ) -> Weight; + } /// Weights for `pallet_ranked_collective` using the Substrate node and recommended hardware. @@ -205,6 +207,30 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(14_u64)) } + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:11 w:11) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:11) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:11) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// The range of component `r` is `[0, 10]`. + fn add_member_to_rank(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `3507 + r * (2489 ±0)` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(10_242_965, 0) + .saturating_add(Weight::from_parts(0, 3507)) + // Standard Error: 8_506 + .saturating_add(Weight::from_parts(7_883_857, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2489).saturating_mul(r.into())) + } } // For backwards compatibility and tests. @@ -351,4 +377,28 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(14_u64)) } + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:11 w:11) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:11) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:11) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// The range of component `r` is `[0, 10]`. + fn add_member_to_rank(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `3507 + r * (2489 ±0)` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(10_242_965, 0) + .saturating_add(Weight::from_parts(0, 3507)) + // Standard Error: 8_506 + .saturating_add(Weight::from_parts(7_883_857, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes(4)) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 2489).saturating_mul(r.into())) + } }