From 79d36eef0abe89b8d3fb48ce5485ebd2d9144c6d Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 30 Jul 2025 11:48:03 +0200 Subject: [PATCH 01/18] backport offence benchmark fix --- substrate/frame/offences/benchmarking/src/inner.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index cb8e3cf56d02..91c30061957d 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -191,9 +191,9 @@ where ::RuntimeEvent: TryInto, ::RuntimeEvent: TryInto>, { - // make sure that all slashes have been applied + // make sure that all slashes have been applied and TotalIssuance adjusted(BurnedDebt). // deposit to reporter + reporter account endowed. - assert_eq!(System::::read_events_for_pallet::>().len(), 2); + assert_eq!(System::::read_events_for_pallet::>().len(), 3); // (n nominators + one validator) * slashed + Slash Reported + Slash Computed assert_eq!( System::::read_events_for_pallet::>().len(), From 145a8164ec70c73cf45f833101eb00793a65c01e Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 1 Aug 2025 11:43:49 +0100 Subject: [PATCH 02/18] small try-runtime related fixes --- substrate/frame/nomination-pools/src/lib.rs | 18 +++++++++----- .../frame/staking-async/src/pallet/impls.rs | 24 ++++++++++++++++--- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 2bb2e0a32538..3119626eb92a 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -3955,12 +3955,18 @@ impl Pallet { ); let depositor = PoolMembers::::get(&bonded_pool.roles.depositor).unwrap(); - ensure!( - bonded_pool.is_destroying_and_only_depositor(depositor.active_points()) || - depositor.active_points() >= MinCreateBond::::get(), - "depositor must always have MinCreateBond stake in the pool, except for when the \ - pool is being destroyed and the depositor is the last member", - ); + let depositor_has_enough_stake = bonded_pool + .is_destroying_and_only_depositor(depositor.active_points()) || + depositor.active_points() >= MinCreateBond::::get(); + if !depositor_has_enough_stake { + log::warn!( + "pool {:?} has depositor {:?} with insufficient stake {:?}, minimum required is {:?}", + id, + bonded_pool.roles.depositor, + depositor.active_points(), + MinCreateBond::::get() + ); + } ensure!( bonded_pool.points >= bonded_pool.points_to_balance(bonded_pool.points), diff --git a/substrate/frame/staking-async/src/pallet/impls.rs b/substrate/frame/staking-async/src/pallet/impls.rs index f76a1feab3ab..2ecfbb2c3d38 100644 --- a/substrate/frame/staking-async/src/pallet/impls.rs +++ b/substrate/frame/staking-async/src/pallet/impls.rs @@ -2087,20 +2087,38 @@ impl Pallet { match (is_nominator, is_validator) { (false, false) => { if ledger.active < Self::min_chilled_bond() { - log!(warn, "Chilled stash {:?} has less than minimum bond", stash); + log!( + warn, + "Chilled stash {:?} has less stake ({:?}) than minimum role bond ({:?})", + stash, + ledger.active, + Self::min_chilled_bond() + ); } // is chilled }, (true, false) => { // Nominators must have a minimum bond. if ledger.active < Self::min_nominator_bond() { - log!(warn, "Nominator {:?} has less than minimum bond", stash); + log!( + warn, + "Nominator {:?} has less stake ({:?}) than minimum role bond ({:?})", + stash, + ledger.active, + Self::min_nominator_bond() + ); } }, (false, true) => { // Validators must have a minimum bond. if ledger.active < Self::min_validator_bond() { - log!(warn, "Validator {:?} has less than minimum bond", stash); + log!( + warn, + "Validator {:?} has less stake ({:?}) than minimum role bond ({:?})", + stash, + ledger.active, + Self::min_validator_bond() + ); } }, (true, true) => { From 49b9908d88359a94cf779597dc18eb00c707090f Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 1 Aug 2025 12:38:33 +0100 Subject: [PATCH 03/18] fix min bonds --- .../frame/staking-async/src/pallet/impls.rs | 23 +++++++------------ .../frame/staking-async/src/tests/bonding.rs | 10 ++++---- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/substrate/frame/staking-async/src/pallet/impls.rs b/substrate/frame/staking-async/src/pallet/impls.rs index 2ecfbb2c3d38..b4e678c55f71 100644 --- a/substrate/frame/staking-async/src/pallet/impls.rs +++ b/substrate/frame/staking-async/src/pallet/impls.rs @@ -73,26 +73,18 @@ use sp_runtime::TryRuntimeError; const NPOS_MAX_ITERATIONS_COEFFICIENT: u32 = 2; impl Pallet { - /// Returns the minimum required bond for participation, considering nominators, - /// and the chain’s existential deposit. - /// - /// This function computes the smallest allowed bond among `MinValidatorBond` and - /// `MinNominatorBond`, but ensures it is not below the existential deposit required to keep an - /// account alive. + /// Returns the minimum required bond for participation in staking as a chilled account. pub(crate) fn min_chilled_bond() -> BalanceOf { - MinValidatorBond::::get() - .min(MinNominatorBond::::get()) - .max(asset::existential_deposit::()) + // Note: in the future we might add a configurable `MinChilledBond`, else ED is good. + asset::existential_deposit::() } - /// Returns the minimum required bond for validators, defaulting to `MinNominatorBond` if not - /// set or less than `MinNominatorBond`. + /// Returns the minimum required bond for participation in staking as a validator account. pub(crate) fn min_validator_bond() -> BalanceOf { - MinValidatorBond::::get().max(Self::min_nominator_bond()) + MinValidatorBond::::get().max(asset::existential_deposit::()) } - /// Returns the minimum required bond for nominators, considering the chain’s existential - /// deposit. + /// Returns the minimum required bond for participation in staking as a nominator account. pub(crate) fn min_nominator_bond() -> BalanceOf { MinNominatorBond::::get().max(asset::existential_deposit::()) } @@ -2086,7 +2078,8 @@ impl Pallet { match (is_nominator, is_validator) { (false, false) => { - if ledger.active < Self::min_chilled_bond() { + if ledger.active < Self::min_chilled_bond() || ledger.active.is_zero() { + // chilled accounts allow to go to zero and fully unbond ^^^^^^^^^ log!( warn, "Chilled stash {:?} has less stake ({:?}) than minimum role bond ({:?})", diff --git a/substrate/frame/staking-async/src/tests/bonding.rs b/substrate/frame/staking-async/src/tests/bonding.rs index 3f8b66ff3f77..5da3e7d45fea 100644 --- a/substrate/frame/staking-async/src/tests/bonding.rs +++ b/substrate/frame/staking-async/src/tests/bonding.rs @@ -1387,8 +1387,6 @@ mod reap { Error::::FundedTarget ); - // Note: Even though the stash is a validator, the threshold to reap is min of - // nominator and validator bond // no easy way to cause an account to go below ED, we tweak their staking ledger // instead. @@ -1401,8 +1399,8 @@ mod reap { Error::::FundedTarget ); - // WHEN: set ledger to below min nominator bond. - Ledger::::insert(11, StakingLedger::::new(11, 999)); + // WHEN: set ledger to below ED + Ledger::::insert(11, StakingLedger::::new(11, 9)); // THEN: reap-able assert_ok!(Staking::reap_stash(RuntimeOrigin::signed(20), 11, 0)); @@ -1551,9 +1549,9 @@ mod staking_bounds_chill_other { .min_nominator_bond(1_000) .min_validator_bond(1_500) .build_and_execute(|| { - // 500 is not enough for any role + // 50 is not enough for any role (less than ED) assert_noop!( - Staking::bond(RuntimeOrigin::signed(3), 500, RewardDestination::Stash), + Staking::bond(RuntimeOrigin::signed(3), 50, RewardDestination::Stash), Error::::InsufficientBond ); // 1000 is enough for nominator but not for validator. From 571377fff34f37d6a57d00abb76c658105621795 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 1 Aug 2025 13:19:24 +0100 Subject: [PATCH 04/18] fix --- substrate/frame/staking-async/src/pallet/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/staking-async/src/pallet/impls.rs b/substrate/frame/staking-async/src/pallet/impls.rs index b4e678c55f71..9cf03048e67f 100644 --- a/substrate/frame/staking-async/src/pallet/impls.rs +++ b/substrate/frame/staking-async/src/pallet/impls.rs @@ -2078,7 +2078,7 @@ impl Pallet { match (is_nominator, is_validator) { (false, false) => { - if ledger.active < Self::min_chilled_bond() || ledger.active.is_zero() { + if ledger.active < Self::min_chilled_bond() && !ledger.active.is_zero() { // chilled accounts allow to go to zero and fully unbond ^^^^^^^^^ log!( warn, From 58f80ad03cbe2860d3959b779aebfe8cf7628028 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 1 Aug 2025 13:21:55 +0100 Subject: [PATCH 05/18] correct logging method --- substrate/frame/nomination-pools/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 3119626eb92a..ce60c2de6255 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -3930,7 +3930,8 @@ impl Pallet { // If this happens, this is most likely due to an old bug and not a recent code change. // We warn about this in try-runtime checks but do not panic. if !pending_rewards_lt_leftover_bal { - log::warn!( + log!( + warn, "pool {:?}, sum pending rewards = {:?}, remaining balance = {:?}", id, pools_members_pending_rewards.get(&id), @@ -3959,7 +3960,8 @@ impl Pallet { .is_destroying_and_only_depositor(depositor.active_points()) || depositor.active_points() >= MinCreateBond::::get(); if !depositor_has_enough_stake { - log::warn!( + log!( + warn, "pool {:?} has depositor {:?} with insufficient stake {:?}, minimum required is {:?}", id, bonded_pool.roles.depositor, @@ -4049,7 +4051,8 @@ impl Pallet { let expected_frozen_balance = T::Currency::minimum_balance(); if frozen_balance != expected_frozen_balance { failed += 1; - log::warn!( + log!( + warn, "pool {:?} has incorrect ED frozen that can result from change in ED. Expected = {:?}, Actual = {:?}", id, expected_frozen_balance, From 20afcbaa1347f1f22856a8d36dac926a6b0cdee7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 1 Aug 2025 13:49:40 +0100 Subject: [PATCH 06/18] chill one more pools test --- substrate/frame/nomination-pools/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index ce60c2de6255..36d225536796 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -4042,7 +4042,6 @@ impl Pallet { debug_assertions ))] pub fn check_ed_imbalance() -> Result<(), DispatchError> { - let mut failed: u32 = 0; BondedPools::::iter_keys().for_each(|id| { let reward_acc = Self::generate_reward_account(id); let frozen_balance = @@ -4050,7 +4049,6 @@ impl Pallet { let expected_frozen_balance = T::Currency::minimum_balance(); if frozen_balance != expected_frozen_balance { - failed += 1; log!( warn, "pool {:?} has incorrect ED frozen that can result from change in ED. Expected = {:?}, Actual = {:?}", @@ -4061,7 +4059,6 @@ impl Pallet { } }); - ensure!(failed == 0, "Some pools do not have correct ED frozen"); Ok(()) } /// Fully unbond the shares of `member`, when executed from `origin`. From 9dd0a96e17576e074b4621febe5e219569572d59 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Fri, 1 Aug 2025 16:57:23 +0200 Subject: [PATCH 07/18] Bounties and scheduler: make more stuff public Signed-off-by: Oliver Tale-Yazdi --- substrate/frame/bounties/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/bounties/src/lib.rs b/substrate/frame/bounties/src/lib.rs index 42b52d062d7a..e0955c03f07a 100644 --- a/substrate/frame/bounties/src/lib.rs +++ b/substrate/frame/bounties/src/lib.rs @@ -148,9 +148,9 @@ pub struct Bounty { /// The deposit of curator. pub curator_deposit: Balance, /// The amount held on deposit (reserved) for making this proposal. - bond: Balance, + pub bond: Balance, /// The status of this bounty. - status: BountyStatus, + pub status: BountyStatus, } impl From e310b97a278502c0f2ff63f49bee0bc024cccb09 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 8 Aug 2025 10:25:18 +0100 Subject: [PATCH 08/18] Cleanup staking try states + fix min bonds (#9415) Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- prdoc/pr_9415.prdoc | 9 +++++++++ .../frame/nomination-pools/benchmarking/src/inner.rs | 4 ++-- substrate/frame/nomination-pools/src/lib.rs | 10 ++++++---- substrate/frame/nomination-pools/src/migration.rs | 2 +- substrate/frame/staking-async/src/pallet/mod.rs | 5 ++--- 5 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 prdoc/pr_9415.prdoc diff --git a/prdoc/pr_9415.prdoc b/prdoc/pr_9415.prdoc new file mode 100644 index 000000000000..f16ff64d8fd4 --- /dev/null +++ b/prdoc/pr_9415.prdoc @@ -0,0 +1,9 @@ +title: Cleanup staking try states + fix min bonds +doc: +- audience: Runtime Dev + description: ensures staking try-state code passes, and fixes issues of having a mistakenly high min-bond for validators +crates: +- name: pallet-nomination-pools + bump: patch +- name: pallet-staking-async + bump: patch diff --git a/substrate/frame/nomination-pools/benchmarking/src/inner.rs b/substrate/frame/nomination-pools/benchmarking/src/inner.rs index 10bc129f9acc..d71022657576 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/inner.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/inner.rs @@ -966,14 +966,14 @@ mod benchmarks { // Remove ed freeze to create a scenario where the ed deposit needs to be adjusted. let _ = Pools::::unfreeze_pool_deposit(&Pools::::generate_reward_account(1)); - assert!(&Pools::::check_ed_imbalance().is_err()); + assert_eq!(Pools::::check_ed_imbalance().unwrap(), 1); whitelist_account!(depositor); #[extrinsic_call] _(RuntimeOrigin::Signed(depositor), 1); - assert!(&Pools::::check_ed_imbalance().is_ok()); + assert_eq!(Pools::::check_ed_imbalance().unwrap(), 0); } #[benchmark] diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 36d225536796..8b6fdee58bff 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -4026,7 +4026,7 @@ impl Pallet { // Warn if any pool has incorrect ED frozen. We don't want to fail hard as this could be a // result of an intentional ED change. - Self::check_ed_imbalance()?; + let _needs_adjust = Self::check_ed_imbalance()?; Ok(()) } @@ -4041,7 +4041,8 @@ impl Pallet { test, debug_assertions ))] - pub fn check_ed_imbalance() -> Result<(), DispatchError> { + pub fn check_ed_imbalance() -> Result { + let mut needs_adjust = 0; BondedPools::::iter_keys().for_each(|id| { let reward_acc = Self::generate_reward_account(id); let frozen_balance = @@ -4049,9 +4050,10 @@ impl Pallet { let expected_frozen_balance = T::Currency::minimum_balance(); if frozen_balance != expected_frozen_balance { + needs_adjust += 1; log!( warn, - "pool {:?} has incorrect ED frozen that can result from change in ED. Expected = {:?}, Actual = {:?}", + "pool {:?} has incorrect ED frozen that can result from change in ED. Expected = {:?}, Actual = {:?}. Use `adjust_pool_deposit` to fix it", id, expected_frozen_balance, frozen_balance, @@ -4059,7 +4061,7 @@ impl Pallet { } }); - Ok(()) + Ok(needs_adjust) } /// Fully unbond the shares of `member`, when executed from `origin`. /// diff --git a/substrate/frame/nomination-pools/src/migration.rs b/substrate/frame/nomination-pools/src/migration.rs index d8697364a76c..a0e5b45b88cf 100644 --- a/substrate/frame/nomination-pools/src/migration.rs +++ b/substrate/frame/nomination-pools/src/migration.rs @@ -442,7 +442,7 @@ mod v6 { #[cfg(feature = "try-runtime")] fn post_upgrade(_data: Vec) -> Result<(), TryRuntimeError> { // there should be no ED imbalances anymore.. - Pallet::::check_ed_imbalance() + Pallet::::check_ed_imbalance().map(|_| ()) } } } diff --git a/substrate/frame/staking-async/src/pallet/mod.rs b/substrate/frame/staking-async/src/pallet/mod.rs index 9699ad1e4111..035e8b70797b 100644 --- a/substrate/frame/staking-async/src/pallet/mod.rs +++ b/substrate/frame/staking-async/src/pallet/mod.rs @@ -2024,9 +2024,8 @@ pub mod pallet { /// Remove all data structures concerning a staker/stash once it is at a state where it can /// be considered `dust` in the staking system. The requirements are: /// - /// 1. the `total_balance` of the stash is below minimum bond. - /// 2. or, the `ledger.total` of the stash is below minimum bond. - /// 3. or, existential deposit is zero and either `total_balance` or `ledger.total` is zero. + /// 1. the `total_balance` of the stash is below `min_chilled_bond` or is zero. + /// 2. or, the `ledger.total` of the stash is below `min_chilled_bond` or is zero. /// /// The former can happen in cases like a slash; the latter when a fully unbonded account /// is still receiving staking rewards in `RewardDestination::Staked`. From c229dea2dcd88202236bf6dbc6173fb638c75f9e Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 20 Aug 2025 09:16:52 +0100 Subject: [PATCH 09/18] BACKPORT-CONFLICT --- .../snowbridge/runtime/test-common/Cargo.toml | 1 + cumulus/pallets/collator-selection/Cargo.toml | 1 + .../collator-selection/src/benchmarking.rs | 6 +- .../pallets/session-benchmarking/Cargo.toml | 1 + .../pallets/session-benchmarking/src/inner.rs | 2 + .../assets/asset-hub-rococo/Cargo.toml | 1 + .../assets/asset-hub-westend/Cargo.toml | 1 + .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 1 + .../bridge-hubs/bridge-hub-westend/Cargo.toml | 1 + .../collectives-westend/Cargo.toml | 1 + .../coretime/coretime-rococo/Cargo.toml | 1 + .../coretime/coretime-westend/Cargo.toml | 1 + .../runtimes/people/people-rococo/Cargo.toml | 1 + .../runtimes/people/people-westend/Cargo.toml | 1 + .../runtimes/testing/penpal/Cargo.toml | 1 + polkadot/runtime/common/Cargo.toml | 1 + polkadot/runtime/parachains/Cargo.toml | 1 + .../src/disputes/slashing/benchmarking.rs | 1 + polkadot/runtime/rococo/Cargo.toml | 1 + polkadot/runtime/test-runtime/Cargo.toml | 1 + polkadot/runtime/westend/Cargo.toml | 1 + polkadot/runtime/westend/src/lib.rs | 3 +- .../westend/src/weights/pallet_session.rs | 36 +++++------ ...ot_runtime_parachains_disputes_slashing.rs | 38 +++++++----- prdoc/pr_9504.prdoc | 62 +++++++++++++++++++ substrate/frame/babe/Cargo.toml | 1 + substrate/frame/beefy-mmr/Cargo.toml | 1 + substrate/frame/grandpa/Cargo.toml | 1 + substrate/frame/im-online/Cargo.toml | 1 + .../frame/offences/benchmarking/Cargo.toml | 1 + .../frame/offences/benchmarking/src/inner.rs | 1 + substrate/frame/root-offences/Cargo.toml | 1 + substrate/frame/session/Cargo.toml | 8 +++ .../frame/session/benchmarking/Cargo.toml | 1 + .../frame/session/benchmarking/src/inner.rs | 7 ++- .../frame/session/benchmarking/src/mock.rs | 4 +- substrate/frame/session/src/lib.rs | 23 ++++++- .../frame/staking-async/ah-client/Cargo.toml | 1 + .../runtimes/parachain/Cargo.toml | 1 + .../staking-async/runtimes/rc/Cargo.toml | 4 ++ substrate/frame/staking/Cargo.toml | 1 + umbrella/Cargo.toml | 1 + 42 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 prdoc/pr_9504.prdoc diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index 4c625709c9ec..65e93c43e33e 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -78,6 +78,7 @@ runtime-benchmarks = [ "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/pallets/collator-selection/Cargo.toml b/cumulus/pallets/collator-selection/Cargo.toml index 98960b0776d1..dcc75bc88ea2 100644 --- a/cumulus/pallets/collator-selection/Cargo.toml +++ b/cumulus/pallets/collator-selection/Cargo.toml @@ -44,6 +44,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "sp-staking/runtime-benchmarks", diff --git a/cumulus/pallets/collator-selection/src/benchmarking.rs b/cumulus/pallets/collator-selection/src/benchmarking.rs index 706695106ba6..5d34641aee75 100644 --- a/cumulus/pallets/collator-selection/src/benchmarking.rs +++ b/cumulus/pallets/collator-selection/src/benchmarking.rs @@ -79,6 +79,7 @@ fn register_validators(count: u32) -> Vec(c)).collect::>(); for (who, keys) in validators.clone() { + >::ensure_can_pay_key_deposit(&who).unwrap(); >::set_keys(RawOrigin::Signed(who).into(), keys, Vec::new()).unwrap(); } @@ -158,6 +159,7 @@ mod benchmarks { candidates.push((new_invulnerable.clone(), new_invulnerable_keys)); // set their keys ... for (who, keys) in candidates.clone() { + >::ensure_can_pay_key_deposit(&who).unwrap(); >::set_keys(RawOrigin::Signed(who).into(), keys, Vec::new()) .unwrap(); } @@ -298,6 +300,7 @@ mod benchmarks { let bond: BalanceOf = ::Currency::minimum_balance() * 2u32.into(); ::Currency::make_free_balance_be(&caller, bond); + >::ensure_can_pay_key_deposit(&caller).unwrap(); >::set_keys( RawOrigin::Signed(caller.clone()).into(), keys::(c + 1), @@ -325,6 +328,7 @@ mod benchmarks { let bond: BalanceOf = ::Currency::minimum_balance() * 10u32.into(); ::Currency::make_free_balance_be(&caller, bond); + >::ensure_can_pay_key_deposit(&caller).unwrap(); >::set_keys( RawOrigin::Signed(caller.clone()).into(), keys::(c + 1), @@ -456,5 +460,5 @@ mod benchmarks { } } - impl_benchmark_test_suite!(CollatorSelection, crate::mock::new_test_ext(), crate::mock::Test,); + impl_benchmark_test_suite!(CollatorSelection, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/cumulus/pallets/session-benchmarking/Cargo.toml b/cumulus/pallets/session-benchmarking/Cargo.toml index ad2c48d9d067..7b499a657bcd 100644 --- a/cumulus/pallets/session-benchmarking/Cargo.toml +++ b/cumulus/pallets/session-benchmarking/Cargo.toml @@ -29,6 +29,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] std = [ diff --git a/cumulus/pallets/session-benchmarking/src/inner.rs b/cumulus/pallets/session-benchmarking/src/inner.rs index 6c5188921362..be7d7740be6b 100644 --- a/cumulus/pallets/session-benchmarking/src/inner.rs +++ b/cumulus/pallets/session-benchmarking/src/inner.rs @@ -35,6 +35,7 @@ mod benchmarks { frame_system::Pallet::::inc_providers(&caller); let keys = T::Keys::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).unwrap(); let proof: Vec = vec![0, 1, 2, 3]; + >::ensure_can_pay_key_deposit(&caller).unwrap(); #[extrinsic_call] _(RawOrigin::Signed(caller), keys, proof); @@ -48,6 +49,7 @@ mod benchmarks { frame_system::Pallet::::inc_providers(&caller); let keys = T::Keys::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).unwrap(); let proof: Vec = vec![0, 1, 2, 3]; + >::ensure_can_pay_key_deposit(&caller).unwrap(); let _t = pallet_session::Pallet::::set_keys( RawOrigin::Signed(caller.clone()).into(), keys, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 02c98c61482d..0f072129cd2a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -125,6 +125,7 @@ runtime-benchmarks = [ "pallet-nft-fractionalization/runtime-benchmarks", "pallet-nfts/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml index b2fc90bde51f..7be174cf1341 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml @@ -175,6 +175,7 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-revive/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "pallet-staking-async/runtime-benchmarks", "pallet-staking/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 8fab61373787..3c8c6348bd8f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -236,6 +236,7 @@ runtime-benchmarks = [ "pallet-collator-selection/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index 38a294ea185b..218bbbfbdbd5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -245,6 +245,7 @@ runtime-benchmarks = [ "pallet-collator-selection/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml index 2e6b018b2a21..dffe91d74a39 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml @@ -120,6 +120,7 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-salary/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index 4e8587aa4046..e90935a5c6ba 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -164,6 +164,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml index 9fce1c63daf4..e05fa2707ec0 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml @@ -163,6 +163,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml index 54f566272157..ff33921fae96 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml @@ -164,6 +164,7 @@ runtime-benchmarks = [ "pallet-migrations/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml index 1cd020d418e4..6524899cc735 100644 --- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml @@ -166,6 +166,7 @@ runtime-benchmarks = [ "pallet-migrations/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index 46a6fec06302..454a70c91e60 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -171,6 +171,7 @@ runtime-benchmarks = [ "pallet-collator-selection/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", "pallet-revive/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index 37cc82be4cb0..3dafbb43b673 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -127,6 +127,7 @@ runtime-benchmarks = [ "pallet-election-provider-multi-phase/runtime-benchmarks", "pallet-fast-unstake/runtime-benchmarks", "pallet-identity/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-transaction-payment/runtime-benchmarks", diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index eecbf887ad1a..4cc72c1600d0 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -125,6 +125,7 @@ runtime-benchmarks = [ "pallet-broker/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", "pallet-mmr/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs b/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs index f99aa2d1b193..4aa076faac43 100644 --- a/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs +++ b/polkadot/runtime/parachains/src/disputes/slashing/benchmarking.rs @@ -76,6 +76,7 @@ where let proof: Vec = vec![]; whitelist_account!(controller); + pallet_session::Pallet::::ensure_can_pay_key_deposit(&controller).unwrap(); pallet_session::Pallet::::set_keys(RawOrigin::Signed(controller).into(), keys, proof) .expect("session::set_keys should work"); } diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index 1dd9e86860a4..b556d148aa3d 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -239,6 +239,7 @@ runtime-benchmarks = [ "pallet-recovery/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-society/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml index f2446a545f56..50a3c4b14add 100644 --- a/polkadot/runtime/test-runtime/Cargo.toml +++ b/polkadot/runtime/test-runtime/Cargo.toml @@ -131,6 +131,7 @@ runtime-benchmarks = [ "pallet-grandpa/runtime-benchmarks", "pallet-indices/runtime-benchmarks", "pallet-offences/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 6d9bd2bac6cf..ad0eeaaab276 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -263,6 +263,7 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-session-benchmarking/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking-async-ah-client/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "pallet-staking/runtime-benchmarks", diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index b688519f608c..33ed8e3c34aa 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -509,6 +509,7 @@ impl pallet_authorship::Config for Runtime { parameter_types! { pub const Period: BlockNumber = 10 * MINUTES; pub const Offset: BlockNumber = 0; + pub const KeyDeposit: Balance = deposit(1, 5 * 32 + 33); } impl_opaque_keys! { @@ -534,7 +535,7 @@ impl pallet_session::Config for Runtime { type DisablingStrategy = pallet_session::disabling::UpToLimitWithReEnablingDisablingStrategy; type WeightInfo = weights::pallet_session::WeightInfo; type Currency = Balances; - type KeyDeposit = (); + type KeyDeposit = KeyDeposit; } impl pallet_session::historical::Config for Runtime { diff --git a/polkadot/runtime/westend/src/weights/pallet_session.rs b/polkadot/runtime/westend/src/weights/pallet_session.rs index 813c6e3a6671..9f93de3cb9e6 100644 --- a/polkadot/runtime/westend/src/weights/pallet_session.rs +++ b/polkadot/runtime/westend/src/weights/pallet_session.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_session` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-02-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-08-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `3a2e9ae8a8f5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `276823fd1fd5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 // Executed Command: @@ -51,36 +51,36 @@ use core::marker::PhantomData; /// Weight functions for `pallet_session`. pub struct WeightInfo(PhantomData); impl pallet_session::WeightInfo for WeightInfo { - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Session::NextKeys` (r:1 w:1) /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Session::KeyOwner` (r:6 w:6) /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(139), added: 2614, mode: `MaxEncodedLen`) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1899` - // Estimated: `17739` - // Minimum execution time: 71_274_000 picoseconds. - Weight::from_parts(73_693_000, 0) - .saturating_add(Weight::from_parts(0, 17739)) + // Measured: `1154` + // Estimated: `16994` + // Minimum execution time: 98_517_000 picoseconds. + Weight::from_parts(101_461_000, 0) + .saturating_add(Weight::from_parts(0, 16994)) .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Session::NextKeys` (r:1 w:1) /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(139), added: 2614, mode: `MaxEncodedLen`) /// Storage: `Session::KeyOwner` (r:0 w:6) /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1814` - // Estimated: `5279` - // Minimum execution time: 52_441_000 picoseconds. - Weight::from_parts(55_437_000, 0) - .saturating_add(Weight::from_parts(0, 5279)) + // Measured: `1141` + // Estimated: `4606` + // Minimum execution time: 71_897_000 picoseconds. + Weight::from_parts(74_310_000, 0) + .saturating_add(Weight::from_parts(0, 4606)) .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().writes(8)) } } diff --git a/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_disputes_slashing.rs b/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_disputes_slashing.rs index d75724d1ae0f..866a160598ac 100644 --- a/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_disputes_slashing.rs +++ b/polkadot/runtime/westend/src/weights/polkadot_runtime_parachains_disputes_slashing.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `polkadot_runtime_parachains::disputes::slashing` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-08-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `3a2e9ae8a8f5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `276823fd1fd5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 // Executed Command: @@ -61,12 +61,16 @@ impl polkadot_runtime_parachains::disputes::slashing::W /// Proof: `Offences::ConcurrentReportsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Offences::Reports` (r:1 w:1) /// Proof: `Offences::Reports` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `StakingAhClient::Mode` (r:1 w:0) + /// Proof: `StakingAhClient::Mode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `Staking::SlashRewardFraction` (r:1 w:0) + /// Proof: `Staking::SlashRewardFraction` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ActiveEra` (r:1 w:0) /// Proof: `Staking::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0) /// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) /// Storage: `Staking::Invulnerables` (r:1 w:0) - /// Proof: `Staking::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) + /// Proof: `Staking::Invulnerables` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasStakersOverview` (r:1 w:0) /// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// Storage: `Session::DisabledValidators` (r:1 w:1) @@ -75,22 +79,24 @@ impl polkadot_runtime_parachains::disputes::slashing::W /// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Staking::ValidatorSlashInEra` (r:1 w:1) /// Proof: `Staking::ValidatorSlashInEra` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::OffenceQueue` (r:1 w:1) - /// Proof: `Staking::OffenceQueue` (`max_values`: None, `max_size`: Some(101), added: 2576, mode: `MaxEncodedLen`) - /// Storage: `Staking::OffenceQueueEras` (r:1 w:1) - /// Proof: `Staking::OffenceQueueEras` (`max_values`: Some(1), `max_size`: Some(9), added: 504, mode: `MaxEncodedLen`) + /// Storage: `Staking::SlashingSpans` (r:1 w:1) + /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::SpanSlash` (r:1 w:1) + /// Proof: `Staking::SpanSlash` (`max_values`: None, `max_size`: Some(76), added: 2551, mode: `MaxEncodedLen`) + /// Storage: `Staking::UnappliedSlashes` (r:1 w:1) + /// Proof: `Staking::UnappliedSlashes` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `n` is `[4, 300]`. fn report_dispute_lost_unsigned(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2024 + n * (33 ±0)` - // Estimated: `5386 + n * (34 ±0)` - // Minimum execution time: 88_786_000 picoseconds. - Weight::from_parts(127_346_367, 0) - .saturating_add(Weight::from_parts(0, 5386)) - // Standard Error: 3_530 - .saturating_add(Weight::from_parts(144_389, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(14)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `2145 + n * (33 ±0)` + // Estimated: `5588 + n * (34 ±0)` + // Minimum execution time: 106_507_000 picoseconds. + Weight::from_parts(151_695_565, 0) + .saturating_add(Weight::from_parts(0, 5588)) + // Standard Error: 4_446 + .saturating_add(Weight::from_parts(202_889, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(8)) .saturating_add(Weight::from_parts(0, 34).saturating_mul(n.into())) } } diff --git a/prdoc/pr_9504.prdoc b/prdoc/pr_9504.prdoc new file mode 100644 index 000000000000..0e4eff770f91 --- /dev/null +++ b/prdoc/pr_9504.prdoc @@ -0,0 +1,62 @@ +title: Fix `pallet_session` benchmarks +doc: +- audience: Runtime Dev + description: |- + Fixes the benchmarking code of `pallet_session` such that it works with any `KeyDeposit`. +crates: +- name: westend-runtime + bump: minor +- name: pallet-session-benchmarking + bump: patch +- name: pallet-session + bump: patch +- name: polkadot-sdk + bump: patch +- name: polkadot-runtime-parachains + bump: patch +- name: pallet-babe + bump: patch +- name: pallet-staking + bump: patch +- name: pallet-grandpa + bump: patch +- name: polkadot-runtime-common + bump: patch +- name: pallet-beefy-mmr + bump: patch +- name: pallet-offences-benchmarking + bump: patch +- name: pallet-im-online + bump: patch +- name: pallet-staking-async-ah-client + bump: patch +- name: rococo-runtime + bump: patch +- name: pallet-collator-selection + bump: patch +- name: cumulus-pallet-session-benchmarking + bump: patch +- name: pallet-root-offences + bump: patch +- name: snowbridge-runtime-test-common + bump: patch +- name: asset-hub-rococo-runtime + bump: patch +- name: asset-hub-westend-runtime + bump: patch +- name: bridge-hub-rococo-runtime + bump: patch +- name: bridge-hub-westend-runtime + bump: patch +- name: collectives-westend-runtime + bump: patch +- name: coretime-rococo-runtime + bump: patch +- name: coretime-westend-runtime + bump: patch +- name: people-rococo-runtime + bump: patch +- name: people-westend-runtime + bump: patch +- name: penpal-runtime + bump: patch diff --git a/substrate/frame/babe/Cargo.toml b/substrate/frame/babe/Cargo.toml index 2f1f70e71640..920cbcf65149 100644 --- a/substrate/frame/babe/Cargo.toml +++ b/substrate/frame/babe/Cargo.toml @@ -69,6 +69,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-offences/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/substrate/frame/beefy-mmr/Cargo.toml b/substrate/frame/beefy-mmr/Cargo.toml index 7206e9638a90..98f2eab48c74 100644 --- a/substrate/frame/beefy-mmr/Cargo.toml +++ b/substrate/frame/beefy-mmr/Cargo.toml @@ -74,6 +74,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-mmr/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "sp-staking/runtime-benchmarks", ] diff --git a/substrate/frame/grandpa/Cargo.toml b/substrate/frame/grandpa/Cargo.toml index 2d8d27bfda82..54afb90d8d12 100644 --- a/substrate/frame/grandpa/Cargo.toml +++ b/substrate/frame/grandpa/Cargo.toml @@ -70,6 +70,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-offences/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/substrate/frame/im-online/Cargo.toml b/substrate/frame/im-online/Cargo.toml index 7f84c3127696..e7fc4323891d 100644 --- a/substrate/frame/im-online/Cargo.toml +++ b/substrate/frame/im-online/Cargo.toml @@ -55,6 +55,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "sp-staking/runtime-benchmarks", ] diff --git a/substrate/frame/offences/benchmarking/Cargo.toml b/substrate/frame/offences/benchmarking/Cargo.toml index 0dc8cfb8e433..0b2e3448f9b9 100644 --- a/substrate/frame/offences/benchmarking/Cargo.toml +++ b/substrate/frame/offences/benchmarking/Cargo.toml @@ -70,6 +70,7 @@ runtime-benchmarks = [ "pallet-grandpa/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-offences/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index cb8e3cf56d02..02888c9b44c8 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -112,6 +112,7 @@ fn create_offender(n: u32, nominators: u32) -> Result, &' ::Keys::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) .unwrap(); let proof: Vec = vec![0, 1, 2, 3]; + Session::::ensure_can_pay_key_deposit(&stash)?; Session::::set_keys(RawOrigin::Signed(stash.clone()).into(), keys, proof)?; let mut individual_exposures = vec![]; diff --git a/substrate/frame/root-offences/Cargo.toml b/substrate/frame/root-offences/Cargo.toml index f1f53a5669f3..991eb764d25f 100644 --- a/substrate/frame/root-offences/Cargo.toml +++ b/substrate/frame/root-offences/Cargo.toml @@ -53,6 +53,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/substrate/frame/session/Cargo.toml b/substrate/frame/session/Cargo.toml index 57f3b326913f..ca777b137ee1 100644 --- a/substrate/frame/session/Cargo.toml +++ b/substrate/frame/session/Cargo.toml @@ -58,3 +58,11 @@ try-runtime = [ "pallet-timestamp/try-runtime", "sp-runtime/try-runtime", ] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "sp-staking/runtime-benchmarks", +] diff --git a/substrate/frame/session/benchmarking/Cargo.toml b/substrate/frame/session/benchmarking/Cargo.toml index 83e766bbed94..4948ec157d46 100644 --- a/substrate/frame/session/benchmarking/Cargo.toml +++ b/substrate/frame/session/benchmarking/Cargo.toml @@ -55,6 +55,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/substrate/frame/session/benchmarking/src/inner.rs b/substrate/frame/session/benchmarking/src/inner.rs index f3707763f350..bcff238d4ea0 100644 --- a/substrate/frame/session/benchmarking/src/inner.rs +++ b/substrate/frame/session/benchmarking/src/inner.rs @@ -23,7 +23,10 @@ use sp_runtime::traits::{One, StaticLookup, TrailingZeroInput}; use codec::Decode; use frame_benchmarking::v2::*; -use frame_support::traits::{Get, KeyOwnerProofSystem, OnInitialize}; +use frame_support::{ + assert_ok, + traits::{Get, KeyOwnerProofSystem, OnInitialize}, +}; use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; use pallet_session::{historical::Pallet as Historical, Pallet as Session, *}; use pallet_staking::{ @@ -66,6 +69,7 @@ mod benchmarks { // Whitelist controller account from further DB operations. let v_controller_key = frame_system::Account::::hashed_key_for(&v_controller); frame_benchmarking::benchmarking::add_to_whitelist(v_controller_key.into()); + assert_ok!(Session::::ensure_can_pay_key_deposit(&v_controller)); #[extrinsic_call] _(RawOrigin::Signed(v_controller), keys, proof); @@ -86,6 +90,7 @@ mod benchmarks { let v_controller = pallet_staking::Pallet::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::decode(&mut TrailingZeroInput::zeroes()).unwrap(); let proof: Vec = vec![0, 1, 2, 3]; + assert_ok!(Session::::ensure_can_pay_key_deposit(&v_controller)); Session::::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?; // Whitelist controller account from further DB operations. let v_controller_key = frame_system::Account::::hashed_key_for(&v_controller); diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs index 288bf56ad25e..5910772e6d0f 100644 --- a/substrate/frame/session/benchmarking/src/mock.rs +++ b/substrate/frame/session/benchmarking/src/mock.rs @@ -107,7 +107,9 @@ impl pallet_session::Config for Test { type DisablingStrategy = (); type WeightInfo = (); type Currency = Balances; - type KeyDeposit = (); + // Note: setting to a large amount to ensure bench setup can handle increasing the balance of + // the validator before setting session keys; see `ensure_can_pay_key_deposit`. + type KeyDeposit = ConstU64<2000000000>; } pallet_staking_reward_curve::build! { const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( diff --git a/substrate/frame/session/src/lib.rs b/substrate/frame/session/src/lib.rs index bfa754013229..ffafbd540d18 100644 --- a/substrate/frame/session/src/lib.rs +++ b/substrate/frame/session/src/lib.rs @@ -129,7 +129,7 @@ use frame_support::{ dispatch::DispatchResult, ensure, traits::{ - fungible::{hold::Mutate as HoldMutate, Inspect}, + fungible::{hold::Mutate as HoldMutate, Inspect, Mutate}, Defensive, EstimateNextNewSession, EstimateNextSessionRotation, FindAuthor, Get, OneSessionHandler, ValidatorRegistration, ValidatorSet, }, @@ -447,7 +447,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// The currency type for placing holds when setting keys. - type Currency: Inspect + type Currency: Mutate + HoldMutate>; /// The amount to be held when setting keys. @@ -668,6 +668,25 @@ pub mod pallet { Ok(()) } } + + #[cfg(feature = "runtime-benchmarks")] + impl Pallet { + /// Mint enough funds into `who`, such that they can pay the session key setting deposit. + /// + /// Meant to be used if any pallet's benchmarking code wishes to set session keys, and wants + /// to make sure it will succeed. + pub fn ensure_can_pay_key_deposit(who: &T::AccountId) -> Result<(), DispatchError> { + use frame_support::traits::tokens::{Fortitude, Preservation}; + let deposit = T::KeyDeposit::get(); + let has = T::Currency::reducible_balance(who, Preservation::Protect, Fortitude::Force); + if let Some(deficit) = deposit.checked_sub(&has) { + T::Currency::mint_into(who, deficit.max(T::Currency::minimum_balance())) + .map(|_inc| ()) + } else { + Ok(()) + } + } + } } impl Pallet { diff --git a/substrate/frame/staking-async/ah-client/Cargo.toml b/substrate/frame/staking-async/ah-client/Cargo.toml index f23493d584cf..986bae328b0a 100644 --- a/substrate/frame/staking-async/ah-client/Cargo.toml +++ b/substrate/frame/staking-async/ah-client/Cargo.toml @@ -45,6 +45,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "sp-staking/runtime-benchmarks", diff --git a/substrate/frame/staking-async/runtimes/parachain/Cargo.toml b/substrate/frame/staking-async/runtimes/parachain/Cargo.toml index ad51a59b54d7..4bf1bbc149cf 100644 --- a/substrate/frame/staking-async/runtimes/parachain/Cargo.toml +++ b/substrate/frame/staking-async/runtimes/parachain/Cargo.toml @@ -168,6 +168,7 @@ runtime-benchmarks = [ "pallet-proxy/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "pallet-staking-async/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", diff --git a/substrate/frame/staking-async/runtimes/rc/Cargo.toml b/substrate/frame/staking-async/runtimes/rc/Cargo.toml index b526995295a0..be61354abdd3 100644 --- a/substrate/frame/staking-async/runtimes/rc/Cargo.toml +++ b/substrate/frame/staking-async/runtimes/rc/Cargo.toml @@ -268,7 +268,11 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-session-benchmarking/runtime-benchmarks", +<<<<<<< HEAD "pallet-society/runtime-benchmarks", +======= + "pallet-session/runtime-benchmarks", +>>>>>>> b183b7e (Fix `pallet_session` benchmarks (#9504)) "pallet-staking-async-ah-client/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "pallet-staking/runtime-benchmarks", diff --git a/substrate/frame/staking/Cargo.toml b/substrate/frame/staking/Cargo.toml index 58f6bea55567..c29818013187 100644 --- a/substrate/frame/staking/Cargo.toml +++ b/substrate/frame/staking/Cargo.toml @@ -71,6 +71,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-bags-list/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-session/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "rand_chacha", "sp-runtime/runtime-benchmarks", diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 5a2db5191309..edd3b07a064b 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -317,6 +317,7 @@ runtime-benchmarks = [ "pallet-salary?/runtime-benchmarks", "pallet-scheduler?/runtime-benchmarks", "pallet-session-benchmarking?/runtime-benchmarks", + "pallet-session?/runtime-benchmarks", "pallet-skip-feeless-payment?/runtime-benchmarks", "pallet-society?/runtime-benchmarks", "pallet-staking-async-ah-client?/runtime-benchmarks", From 9cd1ef41ac0e731931c4a2d3cd144bba4256325b Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 20 Aug 2025 12:32:27 +0200 Subject: [PATCH 10/18] Update substrate/frame/staking-async/runtimes/rc/Cargo.toml --- substrate/frame/staking-async/runtimes/rc/Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/substrate/frame/staking-async/runtimes/rc/Cargo.toml b/substrate/frame/staking-async/runtimes/rc/Cargo.toml index be61354abdd3..feee0b4f2f81 100644 --- a/substrate/frame/staking-async/runtimes/rc/Cargo.toml +++ b/substrate/frame/staking-async/runtimes/rc/Cargo.toml @@ -268,11 +268,6 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-session-benchmarking/runtime-benchmarks", -<<<<<<< HEAD - "pallet-society/runtime-benchmarks", -======= - "pallet-session/runtime-benchmarks", ->>>>>>> b183b7e (Fix `pallet_session` benchmarks (#9504)) "pallet-staking-async-ah-client/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "pallet-staking/runtime-benchmarks", From 92e051c1a12f43aa1944422aba8bb133a222d213 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 20 Aug 2025 12:35:32 +0200 Subject: [PATCH 11/18] zepter Signed-off-by: Oliver Tale-Yazdi --- substrate/frame/staking-async/runtimes/rc/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substrate/frame/staking-async/runtimes/rc/Cargo.toml b/substrate/frame/staking-async/runtimes/rc/Cargo.toml index feee0b4f2f81..7c753461bd2f 100644 --- a/substrate/frame/staking-async/runtimes/rc/Cargo.toml +++ b/substrate/frame/staking-async/runtimes/rc/Cargo.toml @@ -291,6 +291,8 @@ runtime-benchmarks = [ "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", "xcm/runtime-benchmarks", + "pallet-session/runtime-benchmarks", + "pallet-society/runtime-benchmarks" ] try-runtime = [ "frame-election-provider-support/try-runtime", From 7ee5433d26b8a72b0f5076749cccc7524dcbd357 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 21 Aug 2025 09:22:32 +0100 Subject: [PATCH 12/18] BACKPORT-CONFLICT --- prdoc/pr_9511.prdoc | 11 + .../src/signed/mod.rs | 45 +++-- .../src/signed/tests.rs | 189 ++++++++++++------ .../runtimes/parachain/src/staking.rs | 39 ++++ .../frame/staking-async/src/pallet/impls.rs | 20 -- 5 files changed, 213 insertions(+), 91 deletions(-) create mode 100644 prdoc/pr_9511.prdoc diff --git a/prdoc/pr_9511.prdoc b/prdoc/pr_9511.prdoc new file mode 100644 index 000000000000..35aa5f493e04 --- /dev/null +++ b/prdoc/pr_9511.prdoc @@ -0,0 +1,11 @@ +title: 'EPMB/Signed: Make invulnerables non-eject-able' +doc: +- audience: Runtime Dev + description: 'Follow-up to https://github.com/paritytech/polkadot-sdk/pull/8877 + and audits: Make it such that invulnerable accounts cannot be ejected from the + election signed queue altogether. ' +crates: +- name: pallet-election-provider-multi-block + bump: patch +- name: pallet-staking-async + bump: patch diff --git a/substrate/frame/election-provider-multi-block/src/signed/mod.rs b/substrate/frame/election-provider-multi-block/src/signed/mod.rs index 7326e5886147..f0061ad9bdc2 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/mod.rs @@ -455,13 +455,13 @@ pub mod pallet { ) -> Result { let mut sorted_scores = SortedScores::::get(round); - let discarded = if let Some(_) = sorted_scores.iter().position(|(x, _)| x == who) { + let did_eject = if let Some(_) = sorted_scores.iter().position(|(x, _)| x == who) { return Err(Error::::Duplicate.into()); } else { // must be new. debug_assert!(!SubmissionMetadataStorage::::contains_key(round, who)); - let pos = match sorted_scores + let insert_idx = match sorted_scores .binary_search_by_key(&metadata.claimed_score, |(_, y)| *y) { // an equal score exists, unlikely, but could very well happen. We just put them @@ -471,10 +471,23 @@ pub mod pallet { Err(pos) => pos, }; - let record = (who.clone(), metadata.claimed_score); - match sorted_scores.force_insert_keep_right(pos, record) { - Ok(None) => false, - Ok(Some((discarded, _score))) => { + let mut record = (who.clone(), metadata.claimed_score); + if sorted_scores.is_full() { + let remove_idx = sorted_scores + .iter() + .position(|(x, _)| !Pallet::::is_invulnerable(x)) + .ok_or(Error::::QueueFull)?; + if insert_idx > remove_idx { + // we have a better solution + sp_std::mem::swap(&mut sorted_scores[remove_idx], &mut record); + // slicing safety note: + // - `insert_idx` is at most `sorted_scores.len()`, obtained from + // `binary_search_by_key`, valid for the upper bound of slicing. + // - `remove_idx` is a valid index, less then `insert_idx`, obtained from + // `.iter().position()` + sorted_scores[remove_idx..insert_idx].rotate_left(1); + + let discarded = record.0; let maybe_metadata = SubmissionMetadataStorage::::take(round, &discarded).defensive(); // Note: safe to remove unbounded, as at most `Pages` pages are stored. @@ -489,24 +502,27 @@ pub mod pallet { Pallet::::settle_deposit( &discarded, metadata.deposit, - if Pallet::::is_invulnerable(&discarded) { - One::one() - } else { - T::EjectGraceRatio::get() - }, + T::EjectGraceRatio::get(), ); } Pallet::::deposit_event(Event::::Ejected(round, discarded)); true - }, - Err(_) => return Err(Error::::QueueFull.into()), + } else { + // we don't have a better solution + return Err(Error::::QueueFull.into()) + } + } else { + sorted_scores + .try_insert(insert_idx, record) + .expect("length checked above; qed"); + false } }; SortedScores::::insert(round, sorted_scores); SubmissionMetadataStorage::::insert(round, who, metadata); - Ok(discarded) + Ok(did_eject) } /// Submit a page of `solution` to the `page` index of `who`'s submission. @@ -1023,6 +1039,7 @@ impl Pallet { ); debug_assert_eq!(_res, Ok(slash)); Self::deposit_event(Event::::Slashed(current_round, loser.clone(), slash)); + Invulnerables::::mutate(|x| x.retain(|y| y != &loser)); // Try to start verification again if we still have submissions if let crate::types::Phase::SignedValidation(remaining_blocks) = diff --git a/substrate/frame/election-provider-multi-block/src/signed/tests.rs b/substrate/frame/election-provider-multi-block/src/signed/tests.rs index cbd64adf84c7..085cec58935c 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/tests.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/tests.rs @@ -29,6 +29,10 @@ use sp_npos_elections::ElectionScore; pub type T = Runtime; +fn score_from(x: u128) -> ElectionScore { + ElectionScore { minimal_stake: x, ..Default::default() } +} + mod calls { use super::*; use sp_runtime::{DispatchError, TokenError::FundsUnavailable}; @@ -213,13 +217,11 @@ mod calls { } #[test] - fn metadata_submission_sorted_based_on_stake() { + fn metadata_submission_sorted_based_on_score() { ExtBuilder::signed().build_and_execute(|| { roll_to_signed_open(); assert_full_snapshot(); - let score_from = |x| ElectionScore { minimal_stake: x, ..Default::default() }; - assert_ok!(SignedPallet::register(RuntimeOrigin::signed(91), score_from(100))); assert_eq!(*Submissions::::leaderboard(0), vec![(91, score_from(100))]); assert_eq!(balances(91), (95, 5)); @@ -1259,6 +1261,8 @@ mod e2e { } mod invulnerables { + use frame_support::hypothetically; + use super::*; fn make_invulnerable(who: AccountId) { @@ -1395,73 +1399,102 @@ mod invulnerables { } #[test] - fn ejected_invulnerable_gets_deposit_back() { - ExtBuilder::signed().max_signed_submissions(2).build_and_execute(|| { + fn invulnerable_cannot_eject_first() { + ExtBuilder::signed().max_signed_submissions(3).build_and_execute(|| { roll_to_signed_open(); assert_full_snapshot(); make_invulnerable(99); - // by default, we pay back 20% of the discarded deposit back + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(99), score_from(100))); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(98), score_from(150))); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(97), score_from(200))); + assert_eq!( - ::EjectGraceRatio::get(), - Perbill::from_percent(20) + Submissions::::leaderboard(0), + vec![(99, score_from(100)), (98, score_from(150)), (97, score_from(200))] ); - // submit 99 as invulnerable - assert_ok!(SignedPallet::register( - RuntimeOrigin::signed(99), - ElectionScore { minimal_stake: 100, ..Default::default() } - )); - assert!(matches!( - Submissions::::metadata_of(0, 99).unwrap(), - SubmissionMetadata { deposit: 7, .. } - )); + // inserting someone who would eject 99 won't work. + assert_noop!( + SignedPallet::register(RuntimeOrigin::signed(96), score_from(100)), + Error::::QueueFull, + ); + // inserting someone who would eject 98 will work. + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(96), score_from(155))); + assert_eq!( + Submissions::::leaderboard(0), + vec![(99, score_from(100)), (96, score_from(155)), (97, score_from(200))] + ); + }) + } - // submit 98 as normal - assert_ok!(SignedPallet::register( - RuntimeOrigin::signed(98), - ElectionScore { minimal_stake: 101, ..Default::default() } - )); - assert!(matches!( - Submissions::::metadata_of(0, 98).unwrap(), - SubmissionMetadata { deposit: 5, .. } - )); - let _ = signed_events_since_last_call(); - assert_eq!(balances(99), (93, 7)); - assert_eq!(balances(98), (95, 5)); + #[test] + fn invulnerable_cannot_eject_middle() { + ExtBuilder::signed().max_signed_submissions(3).build_and_execute(|| { + roll_to_signed_open(); + assert_full_snapshot(); + make_invulnerable(99); - // submit 97 and 96 with higher scores, eject both of the previous ones - assert_ok!(SignedPallet::register( - RuntimeOrigin::signed(97), - ElectionScore { minimal_stake: 200, ..Default::default() } - )); - assert_ok!(SignedPallet::register( - RuntimeOrigin::signed(96), - ElectionScore { minimal_stake: 201, ..Default::default() } - )); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(99), score_from(150))); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(98), score_from(100))); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(97), score_from(200))); assert_eq!( - signed_events_since_last_call(), - vec![ - Event::Ejected(0, 99), - Event::Registered( - 0, - 97, - ElectionScore { minimal_stake: 200, sum_stake: 0, sum_stake_squared: 0 } - ), - Event::Ejected(0, 98), - Event::Registered( - 0, - 96, - ElectionScore { minimal_stake: 201, sum_stake: 0, sum_stake_squared: 0 } - ) - ] + Submissions::::leaderboard(0), + vec![(98, score_from(100)), (99, score_from(150)), (97, score_from(200))] ); - // 99 gets everything back - assert_eq!(balances(99), (100, 0)); - // 98 gets 20% x 5 = 1 back - assert_eq!(balances(98), (96, 0)); + // worse than all + assert_noop!( + SignedPallet::register(RuntimeOrigin::signed(96), score_from(50)), + Error::::QueueFull, + ); + + // better than our first item + hypothetically!({ + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(96), score_from(125))); + assert_eq!( + Submissions::::leaderboard(0), + vec![(96, score_from(125)), (99, score_from(150)), (97, score_from(200))] + ); + }); + + // better than inv + hypothetically!({ + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(96), score_from(175))); + assert_eq!( + Submissions::::leaderboard(0), + vec![(99, score_from(150)), (96, score_from(175)), (97, score_from(200))] + ); + }); + + // better than all + hypothetically!({ + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(96), score_from(225))); + assert_eq!( + Submissions::::leaderboard(0), + vec![(99, score_from(150)), (97, score_from(200)), (96, score_from(225))] + ); + }); + }) + } + + #[test] + fn all_invulnerables() { + ExtBuilder::signed().max_signed_submissions(3).build_and_execute(|| { + roll_to_signed_open(); + assert_full_snapshot(); + assert_ok!(SignedPallet::set_invulnerables(RuntimeOrigin::root(), vec![99, 98, 97])); + + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(99), score_from(150))); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(98), score_from(100))); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(97), score_from(200))); + + // Nothing can touch our boys now. + assert_noop!( + SignedPallet::register(RuntimeOrigin::signed(96), score_from(1000)), + Error::::QueueFull, + ); }) } @@ -1559,6 +1592,48 @@ mod invulnerables { assert_eq!(new_deposit, 5); // Should not be fixed deposit anymore }); } + + #[test] + fn slashed_invulnerable_is_expelled() { + ExtBuilder::signed().build_and_execute(|| { + roll_to_signed_open(); + assert_full_snapshot(); + make_invulnerable(99); + assert!(Invulnerables::::get().contains(&99)); + + let invalid_score = score_from(777); + assert_ok!(SignedPallet::register(RuntimeOrigin::signed(99), invalid_score)); + + roll_to_signed_validation_open(); + roll_next(); // one block so signed pallet will send start signal. + roll_to_full_verification(); + + // Check that rejection events were properly generated + assert_eq!( + verifier_events_since_last_call(), + vec![ + crate::verifier::Event::Verified(2, 0), // empty page + crate::verifier::Event::Verified(1, 0), // empty page + crate::verifier::Event::Verified(0, 0), // empty page + crate::verifier::Event::VerificationFailed(0, FeasibilityError::InvalidScore), + ] + ); + + // Check that expected events were emitted for the rejection + assert_eq!( + signed_events(), + vec![Event::Registered(0, 99, invalid_score), Event::Slashed(0, 99, 7)] /* slash + * amount + * is indeed + * the invulnerable + * deposit + * (7) ^^^^ */ + ); + + // Verify invulnerable is expelled + assert!(!Invulnerables::::get().contains(&99)); + }); + } } mod defensive_tests { diff --git a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs index 7603f27d4ff3..9c4ba688afb8 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs @@ -31,6 +31,45 @@ use sp_runtime::{ use xcm::latest::prelude::*; parameter_types! { +<<<<<<< HEAD +======= + /// Number of election pages that we operate upon. + /// + /// * Polkadot: 32 (3.2m snapshot) + /// * Kusama: 16 (1.6m snapshot) + /// + /// Reasoning: Both leads to around 700 nominators per-page, yielding the weights in + /// https://github.com/paritytech/polkadot-sdk/pull/8704, the maximum of which being around 1mb + /// compressed PoV and 2mb uncompressed. + /// + /// NOTE: in principle, there is nothing preventing us from stretching these values further, it + /// will only reduce the per-page POVs. Although, some operations like the first snapshot, and + /// the last page of export (where we operate on `MaxValidatorSet` validators) will not get any + /// better. + pub storage Pages: u32 = 4; + + /// * Polkadot: 16 * 32 (512 blocks, 51.2m). + /// * Kusama: 8 * 16 (12 blocks, 12.8m). + /// + /// (MaxSubmissions * Pages) for both, enough to verify all solutions. + /// + /// Reasoning: Less security needed in Kusama, to compensate for the shorter session duration. + pub storage SignedValidationPhase: u32 = Pages::get() * 2; + + /// * Polkadot: 200 blocks, 20m. + /// * Kusama: 100 blocks, 10m. + /// + /// Reasoning: + /// + /// * Polkadot wishes at least 8 submitters to be able to submit. That is 8 * 32 = 256 pages + /// for all submitters. Weight of each submission page is roughly 0.0007 of block weight. 200 + /// blocks is more than enough. + /// * Kusama wishes at least 4 submitters to be able to submit. That is 4 * 16 = 64 pages for + /// all submitters. Weight of each submission page is roughly 0.0007 of block weight. 100 + /// blocks is more than enough. + /// + /// See `signed_weight_ratios` test below for more info. +>>>>>>> 56d3c42 (EPMB/Signed: Make invulnerables non-eject-able (#9511)) pub storage SignedPhase: u32 = 4 * MINUTES; pub storage UnsignedPhase: u32 = MINUTES; pub storage SignedValidationPhase: u32 = Pages::get() *2; diff --git a/substrate/frame/staking-async/src/pallet/impls.rs b/substrate/frame/staking-async/src/pallet/impls.rs index 9cf03048e67f..f6d0056552b4 100644 --- a/substrate/frame/staking-async/src/pallet/impls.rs +++ b/substrate/frame/staking-async/src/pallet/impls.rs @@ -731,11 +731,6 @@ impl Pallet { .defensive_unwrap_or_default(); } Nominators::::insert(who, nominations); - - debug_assert_eq!( - Nominators::::count() + Validators::::count(), - T::VoterList::count() - ); } /// This function will remove a nominator from the `Nominators` storage map, @@ -755,11 +750,6 @@ impl Pallet { false }; - debug_assert_eq!( - Nominators::::count() + Validators::::count(), - T::VoterList::count() - ); - outcome } @@ -776,11 +766,6 @@ impl Pallet { let _ = T::VoterList::on_insert(who.clone(), Self::weight_of(who)); } Validators::::insert(who, prefs); - - debug_assert_eq!( - Nominators::::count() + Validators::::count(), - T::VoterList::count() - ); } /// This function will remove a validator from the `Validators` storage map. @@ -799,11 +784,6 @@ impl Pallet { false }; - debug_assert_eq!( - Nominators::::count() + Validators::::count(), - T::VoterList::count() - ); - outcome } From f4b5ae2f09d8c0f858ef2d1001acead334232885 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 21 Aug 2025 14:55:52 +0100 Subject: [PATCH 13/18] resolve --- .../runtimes/parachain/src/staking.rs | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs index 9c4ba688afb8..7603f27d4ff3 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs @@ -31,45 +31,6 @@ use sp_runtime::{ use xcm::latest::prelude::*; parameter_types! { -<<<<<<< HEAD -======= - /// Number of election pages that we operate upon. - /// - /// * Polkadot: 32 (3.2m snapshot) - /// * Kusama: 16 (1.6m snapshot) - /// - /// Reasoning: Both leads to around 700 nominators per-page, yielding the weights in - /// https://github.com/paritytech/polkadot-sdk/pull/8704, the maximum of which being around 1mb - /// compressed PoV and 2mb uncompressed. - /// - /// NOTE: in principle, there is nothing preventing us from stretching these values further, it - /// will only reduce the per-page POVs. Although, some operations like the first snapshot, and - /// the last page of export (where we operate on `MaxValidatorSet` validators) will not get any - /// better. - pub storage Pages: u32 = 4; - - /// * Polkadot: 16 * 32 (512 blocks, 51.2m). - /// * Kusama: 8 * 16 (12 blocks, 12.8m). - /// - /// (MaxSubmissions * Pages) for both, enough to verify all solutions. - /// - /// Reasoning: Less security needed in Kusama, to compensate for the shorter session duration. - pub storage SignedValidationPhase: u32 = Pages::get() * 2; - - /// * Polkadot: 200 blocks, 20m. - /// * Kusama: 100 blocks, 10m. - /// - /// Reasoning: - /// - /// * Polkadot wishes at least 8 submitters to be able to submit. That is 8 * 32 = 256 pages - /// for all submitters. Weight of each submission page is roughly 0.0007 of block weight. 200 - /// blocks is more than enough. - /// * Kusama wishes at least 4 submitters to be able to submit. That is 4 * 16 = 64 pages for - /// all submitters. Weight of each submission page is roughly 0.0007 of block weight. 100 - /// blocks is more than enough. - /// - /// See `signed_weight_ratios` test below for more info. ->>>>>>> 56d3c42 (EPMB/Signed: Make invulnerables non-eject-able (#9511)) pub storage SignedPhase: u32 = 4 * MINUTES; pub storage UnsignedPhase: u32 = MINUTES; pub storage SignedValidationPhase: u32 = Pages::get() *2; From e657c9f76315d81cebb29634b97519bb7980fd64 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 21 Aug 2025 18:01:24 +0100 Subject: [PATCH 14/18] taplo --- substrate/frame/staking-async/runtimes/rc/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/staking-async/runtimes/rc/Cargo.toml b/substrate/frame/staking-async/runtimes/rc/Cargo.toml index 7c753461bd2f..92186087fb93 100644 --- a/substrate/frame/staking-async/runtimes/rc/Cargo.toml +++ b/substrate/frame/staking-async/runtimes/rc/Cargo.toml @@ -268,6 +268,8 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-session-benchmarking/runtime-benchmarks", + "pallet-session/runtime-benchmarks", + "pallet-society/runtime-benchmarks", "pallet-staking-async-ah-client/runtime-benchmarks", "pallet-staking-async-rc-client/runtime-benchmarks", "pallet-staking/runtime-benchmarks", @@ -291,8 +293,6 @@ runtime-benchmarks = [ "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", "xcm/runtime-benchmarks", - "pallet-session/runtime-benchmarks", - "pallet-society/runtime-benchmarks" ] try-runtime = [ "frame-election-provider-support/try-runtime", From 7cf6bceab27739b82d808cd17a157c115791c84b Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 21 Aug 2025 18:21:26 +0100 Subject: [PATCH 15/18] fix bench --- .../frame/offences/benchmarking/src/inner.rs | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index 31c99800ae3e..154361179572 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -184,17 +184,22 @@ fn make_offenders( } #[cfg(test)] -fn assert_all_slashes_applied(offender_count: usize) -where +fn assert_all_slashes_applied( + offender_count: usize, + reporter: ::AccountId, +) where T: Config, ::RuntimeEvent: TryInto>, ::RuntimeEvent: TryInto>, ::RuntimeEvent: TryInto, ::RuntimeEvent: TryInto>, { - // make sure that all slashes have been applied and TotalIssuance adjusted(BurnedDebt). - // deposit to reporter + reporter account endowed. - assert_eq!(System::::read_events_for_pallet::>().len(), 3); + // make sure reporter got deposited. + assert!(System::::read_events_for_pallet::>() + .into_iter() + .any( + |e| matches!(e, pallet_balances::Event::::Deposit { who, .. } if who == reporter ) + )); // (n nominators + one validator) * slashed + Slash Reported + Slash Computed assert_eq!( System::::read_events_for_pallet::>().len(), @@ -222,9 +227,9 @@ mod benchmarks { ) -> Result<(), BenchmarkError> { // for grandpa equivocation reports the number of reporters // and offenders is always 1 - let reporters = vec![account("reporter", 1, SEED)]; + let reporter = account::("reporter", 1, SEED); - // make sure reporters actually get rewarded + // make sure reporter actually get rewarded Staking::::set_slash_reward_fraction(Perbill::one()); let mut offenders = make_offenders::(1, n)?; @@ -240,12 +245,12 @@ mod benchmarks { #[block] { - let _ = Offences::::report_offence(reporters, offence); + let _ = Offences::::report_offence(vec![reporter.clone()], offence); } #[cfg(test)] { - assert_all_slashes_applied::(n as usize); + assert_all_slashes_applied::(n as usize, reporter); } Ok(()) @@ -257,7 +262,7 @@ mod benchmarks { ) -> Result<(), BenchmarkError> { // for babe equivocation reports the number of reporters // and offenders is always 1 - let reporters = vec![account("reporter", 1, SEED)]; + let reporter = account::("reporter", 1, SEED); // make sure reporters actually get rewarded Staking::::set_slash_reward_fraction(Perbill::one()); @@ -275,11 +280,11 @@ mod benchmarks { #[block] { - let _ = Offences::::report_offence(reporters, offence); + let _ = Offences::::report_offence(vec![reporter.clone()], offence); } #[cfg(test)] { - assert_all_slashes_applied::(n as usize); + assert_all_slashes_applied::(n as usize, reporter); } Ok(()) From af748508a0e007c1e741f13e0063433678a53ee9 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 22 Aug 2025 12:50:09 +0100 Subject: [PATCH 16/18] Update polkadot/runtime/westend/src/lib.rs Co-authored-by: Adrian Catangiu --- polkadot/runtime/westend/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 33ed8e3c34aa..b0f594a8a900 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -509,6 +509,7 @@ impl pallet_authorship::Config for Runtime { parameter_types! { pub const Period: BlockNumber = 10 * MINUTES; pub const Offset: BlockNumber = 0; + // 5 keys of 32 bytes, plus beefy key 33 bytes pub const KeyDeposit: Balance = deposit(1, 5 * 32 + 33); } From ec84ecb0c3055aea8de788da2aaf659fee660e55 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 20 Nov 2025 14:04:40 +0100 Subject: [PATCH 17/18] Update substrate/frame/offences/benchmarking/src/inner.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dónal Murray --- substrate/frame/offences/benchmarking/src/inner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index 154361179572..0a7cc7c6f3c8 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -229,7 +229,7 @@ mod benchmarks { // and offenders is always 1 let reporter = account::("reporter", 1, SEED); - // make sure reporter actually get rewarded + // make sure reporter actually gets rewarded Staking::::set_slash_reward_fraction(Perbill::one()); let mut offenders = make_offenders::(1, n)?; From e744fce7d97b7240ecd0f1992f91cc85f936c464 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 20 Nov 2025 15:08:45 +0200 Subject: [PATCH 18/18] prdoc Signed-off-by: Oliver Tale-Yazdi --- prdoc/pr_9513.prdoc | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 prdoc/pr_9513.prdoc diff --git a/prdoc/pr_9513.prdoc b/prdoc/pr_9513.prdoc new file mode 100644 index 000000000000..6363278b399a --- /dev/null +++ b/prdoc/pr_9513.prdoc @@ -0,0 +1,75 @@ +title: '[AHM] Fixes to unstable2507' +doc: +- audience: Runtime Dev + description: See prdoc/pr_9415.prdoc, prdoc/pr_9504.prdoc and prdoc/pr_9511.prdoc. +crates: +- name: pallet-offences-benchmarking + bump: patch +- name: pallet-nomination-pools + bump: patch +- name: pallet-staking-async + bump: patch +- name: pallet-bounties + bump: patch +- name: pallet-nomination-pools-benchmarking + bump: patch +- name: snowbridge-runtime-test-common + bump: patch +- name: pallet-collator-selection + bump: patch +- name: cumulus-pallet-session-benchmarking + bump: patch +- name: asset-hub-rococo-runtime + bump: patch +- name: asset-hub-westend-runtime + bump: patch +- name: bridge-hub-rococo-runtime + bump: patch +- name: bridge-hub-westend-runtime + bump: patch +- name: collectives-westend-runtime + bump: patch +- name: coretime-rococo-runtime + bump: patch +- name: coretime-westend-runtime + bump: patch +- name: people-rococo-runtime + bump: patch +- name: people-westend-runtime + bump: patch +- name: penpal-runtime + bump: patch +- name: polkadot-runtime-common + bump: patch +- name: polkadot-runtime-parachains + bump: patch +- name: rococo-runtime + bump: patch +- name: westend-runtime + bump: minor +- name: pallet-babe + bump: patch +- name: pallet-beefy-mmr + bump: patch +- name: pallet-grandpa + bump: patch +- name: pallet-im-online + bump: patch +- name: pallet-root-offences + bump: patch +- name: pallet-session + bump: patch +- name: pallet-session-benchmarking + bump: patch +- name: pallet-staking-async-ah-client + bump: patch +- name: pallet-staking-async-parachain-runtime + bump: patch +- name: pallet-staking-async-rc-runtime + bump: patch +- name: pallet-staking + bump: patch +- name: polkadot-sdk + bump: patch +- name: pallet-election-provider-multi-block + bump: patch