From 5a8134029a587b2a7cce7d65b1fe0c82a14c4bf8 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:18:27 +0200 Subject: [PATCH] Better Handling of Candidates Who Become Invulnerable (#2801) * remove candidate when to invulnerable * fix * candidates to collators * make parameters consistent and more reasonable * add call to kick invulnerable candidates * factor removal into weight * fix: use accrue instead of add * make set_invulnerables non-atomic * benchmark add_invulnerable to account for candidate removal * don't remove from candidates with set_invulnerables * fix bounds on benchmarking * protect against zero min invulnerables underflow * extra event and tests * make candidates/invulnerables self-cleaning on session change * add integrity test * unused imports * make rococo-contracts have 1 collator --- .../collator-selection/src/benchmarking.rs | 87 +++++-- cumulus/pallets/collator-selection/src/lib.rs | 223 +++++++++++++----- .../pallets/collator-selection/src/mock.rs | 9 +- .../pallets/collator-selection/src/tests.rs | 142 +++++++++-- .../pallets/collator-selection/src/weights.rs | 70 +++--- cumulus/parachain-template/runtime/src/lib.rs | 9 +- cumulus/parachains/common/src/impls.rs | 9 +- .../assets/asset-hub-kusama/src/lib.rs | 9 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../assets/asset-hub-polkadot/src/lib.rs | 9 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../assets/asset-hub-westend/src/lib.rs | 9 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../bridge-hubs/bridge-hub-kusama/src/lib.rs | 8 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../bridge-hub-polkadot/src/lib.rs | 6 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 6 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../collectives-polkadot/src/lib.rs | 6 +- .../src/weights/pallet_collator_selection.rs | 34 ++- .../contracts/contracts-rococo/src/lib.rs | 6 +- .../runtimes/testing/penpal/src/lib.rs | 9 +- 23 files changed, 594 insertions(+), 261 deletions(-) diff --git a/cumulus/pallets/collator-selection/src/benchmarking.rs b/cumulus/pallets/collator-selection/src/benchmarking.rs index 2e363fd604..715135daf0 100644 --- a/cumulus/pallets/collator-selection/src/benchmarking.rs +++ b/cumulus/pallets/collator-selection/src/benchmarking.rs @@ -25,7 +25,8 @@ use frame_benchmarking::{ use frame_support::{ assert_ok, codec::Decode, - traits::{Currency, EnsureOrigin, Get}, + dispatch::DispatchResult, + traits::{Currency, EnsureOrigin, Get, ReservableCurrency}, }; use frame_system::{EventRecord, RawOrigin}; use pallet_authorship::EventHandler; @@ -106,6 +107,18 @@ fn register_candidates(count: u32) { } } +fn min_candidates() -> u32 { + let min_collators = T::MinEligibleCollators::get(); + let invulnerable_length = >::get().len(); + min_collators.saturating_sub(invulnerable_length.try_into().unwrap()) +} + +fn min_invulnerables() -> u32 { + let min_collators = T::MinEligibleCollators::get(); + let candidates_length = >::get().len(); + min_collators.saturating_sub(candidates_length.try_into().unwrap()) +} + benchmarks! { where_clause { where T: pallet_authorship::Config + session::Config } @@ -128,34 +141,67 @@ benchmarks! { } add_invulnerable { + let b in 1 .. T::MaxInvulnerables::get() - 1; + let c in 1 .. T::MaxCandidates::get() - 1; + let origin = T::UpdateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - // we're going to add one, so need one less than max set as invulnerables to start - let b in 1 .. T::MaxInvulnerables::get() - 1; + + // need to fill up candidates + >::put(T::Currency::minimum_balance()); + >::put(c); + // get accounts and keys for the `c` candidates + let mut candidates = (0..c).map(|cc| validator::(cc)).collect::>(); + // add one more to the list. should not be in `b` (invulnerables) because it's the account + // we will _add_ to invulnerables. we want it to be in `candidates` because we need the + // weight associated with removing it. + let (new_invulnerable, new_invulnerable_keys) = validator::(b.max(c) + 1); + candidates.push((new_invulnerable.clone(), new_invulnerable_keys)); + // set their keys ... + for (who, keys) in candidates.clone() { + >::set_keys(RawOrigin::Signed(who).into(), keys, Vec::new()).unwrap(); + } + // ... and register them. + for (who, _) in candidates { + let deposit = >::get(); + T::Currency::make_free_balance_be(&who, deposit * 1000_u32.into()); + let incoming = CandidateInfo { who: who.clone(), deposit }; + >::try_mutate(|candidates| -> DispatchResult { + if !candidates.iter().any(|candidate| candidate.who == who) { + T::Currency::reserve(&who, deposit)?; + candidates.try_push(incoming).expect("we've respected the bounded vec limit"); + >::insert( + who.clone(), + frame_system::Pallet::::block_number() + T::KickThreshold::get(), + ); + } + Ok(()) + }).expect("only returns ok"); + } + + // now we need to fill up invulnerables let mut invulnerables = register_validators::(b); invulnerables.sort(); - let invulnerables: frame_support::BoundedVec<_, T::MaxInvulnerables> = frame_support::BoundedVec::try_from(invulnerables).unwrap(); + let invulnerables: frame_support::BoundedVec<_, T::MaxInvulnerables> = + frame_support::BoundedVec::try_from(invulnerables).unwrap(); >::put(invulnerables); - - // now let's set up a new one to add - let (new, keys) = validator::(b + 1); - >::set_keys(RawOrigin::Signed(new.clone()).into(), keys, Vec::new()).unwrap(); }: { assert_ok!( - >::add_invulnerable(origin, new.clone()) + >::add_invulnerable(origin, new_invulnerable.clone()) ); } verify { - assert_last_event::(Event::InvulnerableAdded{account_id: new}.into()); + assert_last_event::(Event::InvulnerableAdded{account_id: new_invulnerable}.into()); } remove_invulnerable { let origin = T::UpdateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let b in 1 .. T::MaxInvulnerables::get(); + let b in (min_invulnerables::() + 1) .. T::MaxInvulnerables::get(); let mut invulnerables = register_validators::(b); invulnerables.sort(); - let invulnerables: frame_support::BoundedVec<_, T::MaxInvulnerables> = frame_support::BoundedVec::try_from(invulnerables).unwrap(); + let invulnerables: frame_support::BoundedVec<_, T::MaxInvulnerables> = + frame_support::BoundedVec::try_from(invulnerables).unwrap(); >::put(invulnerables); let to_remove = >::get().first().unwrap().clone(); }: { @@ -221,7 +267,7 @@ benchmarks! { // worse case is the last candidate leaving. leave_intent { - let c in (T::MinCandidates::get() + 1) .. T::MaxCandidates::get(); + let c in (min_candidates::() + 1) .. T::MaxCandidates::get(); >::put(T::Currency::minimum_balance()); >::put(c); @@ -286,6 +332,7 @@ benchmarks! { } } + let min_candidates = min_candidates::(); let pre_length = >::get().len(); frame_system::Pallet::::set_block_number(new_block); @@ -294,11 +341,19 @@ benchmarks! { }: { as SessionManager<_>>::new_session(0) } verify { - if c > r && non_removals >= T::MinCandidates::get() { + if c > r && non_removals >= min_candidates { + // candidates > removals and remaining candidates > min candidates + // => remaining candidates should be shorter than before removal, i.e. some were + // actually removed. assert!(>::get().len() < pre_length); - } else if c > r && non_removals < T::MinCandidates::get() { - assert!(>::get().len() == T::MinCandidates::get() as usize); + } else if c > r && non_removals < min_candidates { + // candidates > removals and remaining candidates would be less than min candidates + // => remaining candidates should equal min candidates, i.e. some were removed up to + // the minimum, but then any more were "forced" to stay in candidates. + assert!(>::get().len() == min_candidates as usize); } else { + // removals >= candidates, non removals must == 0 + // can't remove more than exist assert!(>::get().len() == pre_length); } } diff --git a/cumulus/pallets/collator-selection/src/lib.rs b/cumulus/pallets/collator-selection/src/lib.rs index b6a9e109a1..87cff6ae7d 100644 --- a/cumulus/pallets/collator-selection/src/lib.rs +++ b/cumulus/pallets/collator-selection/src/lib.rs @@ -41,8 +41,9 @@ //! The current implementation resolves congestion of [`Candidates`] in a first-come-first-serve //! manner. //! -//! Candidates will not be allowed to get kicked or leave_intent if the total number of candidates -//! fall below MinCandidates. This is for potential disaster recovery scenarios. +//! Candidates will not be allowed to get kicked or `leave_intent` if the total number of collators +//! would fall below `MinEligibleCollators`. This is to ensure that some collators will always +//! exist, i.e. someone is eligible to produce a block. //! //! ### Rewards //! @@ -53,7 +54,7 @@ //! - Half the value of the transaction fees within the block. The other half of the transaction //! fees are deposited into the Pot. //! -//! To initiate rewards an ED needs to be transferred to the pot address. +//! To initiate rewards, an ED needs to be transferred to the pot address. //! //! Note: Eventually the Pot distribution may be modified as discussed in //! [this issue](https://github.com/paritytech/statemint/issues/21#issuecomment-810481073). @@ -128,17 +129,17 @@ pub mod pallet { /// Account Identifier from which the internal Pot is generated. type PotId: Get; - /// Maximum number of candidates that we should have. This is enforced in code. + /// Maximum number of candidates that we should have. /// /// This does not take into account the invulnerables. type MaxCandidates: Get; - /// Minimum number of candidates that we should have. This is used for disaster recovery. - /// - /// This does not take into account the invulnerables. - type MinCandidates: Get; + /// Minimum number eligible collators. Should always be greater than zero. This includes + /// Invulnerable collators. This ensures that there will always be one collator who can + /// produce a block. + type MinEligibleCollators: Get; - /// Maximum number of invulnerables. This is enforced in code. + /// Maximum number of invulnerables. type MaxInvulnerables: Get; // Will be kicked if block is not produced in threshold. @@ -180,7 +181,8 @@ pub mod pallet { pub type Invulnerables = StorageValue<_, BoundedVec, ValueQuery>; - /// The (community, limited) collation candidates. + /// The (community, limited) collation candidates. `Candidates` and `Invulnerables` should be + /// mutually exclusive. #[pallet::storage] #[pallet::getter(fn candidates)] pub type Candidates = StorageValue< @@ -262,6 +264,9 @@ pub mod pallet { CandidateAdded { account_id: T::AccountId, deposit: BalanceOf }, /// A candidate was removed. CandidateRemoved { account_id: T::AccountId }, + /// An account was unable to be added to the Invulnerables because they did not have keys + /// registered. Other Invulnerables may have been set. + InvalidInvulnerableSkipped { account_id: T::AccountId }, } #[pallet::error] @@ -269,7 +274,7 @@ pub mod pallet { /// The pallet has too many candidates. TooManyCandidates, /// Leaving would result in too few candidates. - TooFewCandidates, + TooFewEligibleCollators, /// Account is already a candidate. AlreadyCandidate, /// Account is not a candidate. @@ -287,31 +292,81 @@ pub mod pallet { } #[pallet::hooks] - impl Hooks> for Pallet {} + impl Hooks> for Pallet { + fn integrity_test() { + assert!(T::MinEligibleCollators::get() > 0, "chain must require at least one collator"); + } + } #[pallet::call] impl Pallet { - /// Set the list of invulnerable (fixed) collators. + /// Set the list of invulnerable (fixed) collators. These collators must do some + /// preparation, namely to have registered session keys. + /// + /// The call will remove any accounts that have not registered keys from the set. That is, + /// it is non-atomic; the caller accepts all `AccountId`s passed in `new` _individually_ as + /// acceptable Invulnerables, and is not proposing a _set_ of new Invulnerables. + /// + /// This call does not maintain mutual exclusivity of `Invulnerables` and `Candidates`. It + /// is recommended to use a batch of `add_invulnerable` and `remove_invulnerable` instead. + /// A `batch_all` can also be used to enforce atomicity. If any candidates are included in + /// `new`, they should be removed with `remove_invulnerable_candidate` after execution. + /// + /// Must be called by the `UpdateOrigin`. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::set_invulnerables(new.len() as u32))] - pub fn set_invulnerables( - origin: OriginFor, - new: Vec, - ) -> DispatchResultWithPostInfo { + pub fn set_invulnerables(origin: OriginFor, new: Vec) -> DispatchResult { T::UpdateOrigin::ensure_origin(origin)?; - let mut bounded_invulnerables = BoundedVec::<_, T::MaxInvulnerables>::try_from(new) - .map_err(|_| Error::::TooManyInvulnerables)?; - // check if the invulnerables have associated validator keys before they are set - for account_id in bounded_invulnerables.iter() { - let validator_key = T::ValidatorIdOf::convert(account_id.clone()) - .ok_or(Error::::NoAssociatedValidatorId)?; + // don't wipe out the collator set + if new.is_empty() { ensure!( - T::ValidatorRegistration::is_registered(&validator_key), - Error::::ValidatorNotRegistered + Self::candidates().len() as u32 >= T::MinEligibleCollators::get(), + Error::::TooFewEligibleCollators ); } + // Will need to check the length again when putting into a bounded vec, but this + // prevents the iterator from having too many elements. + ensure!( + new.len() as u32 <= T::MaxInvulnerables::get(), + Error::::TooManyInvulnerables + ); + + let mut new_with_keys = Vec::new(); + + // check if the invulnerables have associated validator keys before they are set + for account_id in &new { + // don't let one unprepared collator ruin things for everyone. + let validator_key = T::ValidatorIdOf::convert(account_id.clone()); + match validator_key { + Some(key) => { + // key is not registered + if !T::ValidatorRegistration::is_registered(&key) { + Self::deposit_event(Event::InvalidInvulnerableSkipped { + account_id: account_id.clone(), + }); + continue + } + // else condition passes; key is registered + }, + // key does not exist + None => { + Self::deposit_event(Event::InvalidInvulnerableSkipped { + account_id: account_id.clone(), + }); + continue + }, + } + + new_with_keys.push(account_id.clone()); + } + + // should never fail since `new_with_keys` must be equal to or shorter than `new` + let mut bounded_invulnerables = + BoundedVec::<_, T::MaxInvulnerables>::try_from(new_with_keys) + .map_err(|_| Error::::TooManyInvulnerables)?; + // Invulnerables must be sorted for removal. bounded_invulnerables.sort(); @@ -319,12 +374,15 @@ pub mod pallet { Self::deposit_event(Event::NewInvulnerables { invulnerables: bounded_invulnerables.to_vec(), }); - Ok(().into()) + + Ok(()) } - /// Set the ideal number of collators (not including the invulnerables). - /// If lowering this number, then the number of running collators could be higher than this figure. - /// Aside from that edge case, there should be no other way to have more collators than the desired number. + /// Set the ideal number of non-invulnerable collators. If lowering this number, then the + /// number of running collators could be higher than this figure. Aside from that edge case, + /// there should be no other way to have more candidates than the desired number. + /// + /// The origin for this call must be the `UpdateOrigin`. #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::set_desired_candidates())] pub fn set_desired_candidates( @@ -342,6 +400,8 @@ pub mod pallet { } /// Set the candidacy bond amount. + /// + /// The origin for this call must be the `UpdateOrigin`. #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::set_candidacy_bond())] pub fn set_candidacy_bond( @@ -401,28 +461,35 @@ pub mod pallet { /// Deregister `origin` as a collator candidate. Note that the collator can only leave on /// session change. The `CandidacyBond` will be unreserved immediately. /// - /// This call will fail if the total number of candidates would drop below `MinCandidates`. - /// - /// This call is not available to `Invulnerable` collators. + /// This call will fail if the total number of candidates would drop below + /// `MinEligibleCollators`. #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::leave_intent(T::MaxCandidates::get()))] pub fn leave_intent(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!( - Self::candidates().len() as u32 > T::MinCandidates::get(), - Error::::TooFewCandidates + Self::eligible_collators() > T::MinEligibleCollators::get(), + Error::::TooFewEligibleCollators ); - let current_count = Self::try_remove_candidate(&who)?; + // Do remove their last authored block. + let current_count = Self::try_remove_candidate(&who, true)?; Ok(Some(T::WeightInfo::leave_intent(current_count as u32)).into()) } - /// Add a new account `who` to the list of `Invulnerables` collators. + /// Add a new account `who` to the list of `Invulnerables` collators. `who` must have + /// registered session keys. If `who` is a candidate, they will be removed. /// /// The origin for this call must be the `UpdateOrigin`. #[pallet::call_index(5)] - #[pallet::weight(T::WeightInfo::add_invulnerable(T::MaxInvulnerables::get() - 1))] - pub fn add_invulnerable(origin: OriginFor, who: T::AccountId) -> DispatchResult { + #[pallet::weight(T::WeightInfo::add_invulnerable( + T::MaxInvulnerables::get().saturating_sub(1), + T::MaxCandidates::get() + ))] + pub fn add_invulnerable( + origin: OriginFor, + who: T::AccountId, + ) -> DispatchResultWithPostInfo { T::UpdateOrigin::ensure_origin(origin)?; // ensure `who` has registered a validator key @@ -443,8 +510,21 @@ pub mod pallet { Ok(()) })?; + // Error just means `who` wasn't a candidate, which is the state we want anyway. Don't + // remove their last authored block, as they are still a collator. + let _ = Self::try_remove_candidate(&who, false); + Self::deposit_event(Event::InvulnerableAdded { account_id: who }); - Ok(()) + + let weight_used = T::WeightInfo::add_invulnerable( + Self::invulnerables() + .len() + .try_into() + .unwrap_or(T::MaxInvulnerables::get().saturating_sub(1)), + Self::candidates().len().try_into().unwrap_or(T::MaxCandidates::get()), + ); + + Ok(Some(weight_used).into()) } /// Remove an account `who` from the list of `Invulnerables` collators. `Invulnerables` must @@ -456,6 +536,11 @@ pub mod pallet { pub fn remove_invulnerable(origin: OriginFor, who: T::AccountId) -> DispatchResult { T::UpdateOrigin::ensure_origin(origin)?; + ensure!( + Self::eligible_collators() > T::MinEligibleCollators::get(), + Error::::TooFewEligibleCollators + ); + >::try_mutate(|invulnerables| -> DispatchResult { let pos = invulnerables.binary_search(&who).map_err(|_| Error::::NotInvulnerable)?; @@ -469,13 +554,29 @@ pub mod pallet { } impl Pallet { - /// Get a unique, inaccessible account id from the `PotId`. + /// Get a unique, inaccessible account ID from the `PotId`. pub fn account_id() -> T::AccountId { T::PotId::get().into_account_truncating() } - /// Removes a candidate if they exist and sends them back their deposit - fn try_remove_candidate(who: &T::AccountId) -> Result { + /// Return the total number of accounts that are eligible collators (candidates and + /// invulnerables). + fn eligible_collators() -> u32 { + Self::candidates() + .len() + .saturating_add(Self::invulnerables().len()) + .try_into() + // More-or-less guaranteed not to Err since it's hard to imagine candidates + + // invulnerables being greater than (or for `usize` to be smaller than) `u32::MAX`, + // but return something "reasonable" instead of panicking. + .unwrap_or(T::MaxCandidates::get()) + } + + /// Removes a candidate if they exist and sends them back their deposit. + fn try_remove_candidate( + who: &T::AccountId, + remove_last_authored: bool, + ) -> Result { let current_count = >::try_mutate(|candidates| -> Result { let index = candidates @@ -484,7 +585,9 @@ pub mod pallet { .ok_or(Error::::NotCandidate)?; let candidate = candidates.remove(index); T::Currency::unreserve(who, candidate.deposit); - >::remove(who.clone()); + if remove_last_authored { + >::remove(who.clone()) + }; Ok(candidates.len()) })?; Self::deposit_event(Event::CandidateRemoved { account_id: who.clone() }); @@ -502,29 +605,39 @@ pub mod pallet { collators } - /// Kicks out candidates that did not produce a block in the kick threshold - /// and refund their deposits. + /// Kicks out candidates that did not produce a block in the kick threshold and refunds + /// their deposits. pub fn kick_stale_candidates( candidates: BoundedVec>, T::MaxCandidates>, ) -> BoundedVec { let now = frame_system::Pallet::::block_number(); let kick_threshold = T::KickThreshold::get(); + let min_collators = T::MinEligibleCollators::get(); candidates .into_iter() .filter_map(|c| { let last_block = >::get(c.who.clone()); let since_last = now.saturating_sub(last_block); - if since_last < kick_threshold || - Self::candidates().len() as u32 <= T::MinCandidates::get() - { - Some(c.who) - } else { - let outcome = Self::try_remove_candidate(&c.who); - if let Err(why) = outcome { - log::warn!("Failed to remove candidate {:?}", why); - debug_assert!(false, "failed to remove candidate {:?}", why); - } + + let is_invulnerable = Self::invulnerables().contains(&c.who); + let is_lazy = since_last >= kick_threshold; + + if is_invulnerable { + // They are invulnerable. No reason for them to be in Candidates also. + // We don't even care about the min collators here, because an Account + // should not be a collator twice. + let _ = Self::try_remove_candidate(&c.who, false); None + } else { + if Self::eligible_collators() <= min_collators || !is_lazy { + // Either this is a good collator (not lazy) or we are at the minimum + // that the system needs. They get to stay. + Some(c.who) + } else { + // This collator has not produced a block recently enough. Bye bye. + let _ = Self::try_remove_candidate(&c.who, true); + None + } } }) .collect::>() diff --git a/cumulus/pallets/collator-selection/src/mock.rs b/cumulus/pallets/collator-selection/src/mock.rs index 361ea3c47b..373970d52f 100644 --- a/cumulus/pallets/collator-selection/src/mock.rs +++ b/cumulus/pallets/collator-selection/src/mock.rs @@ -188,9 +188,6 @@ ord_parameter_types! { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 20; - pub const MaxInvulnerables: u32 = 20; - pub const MinCandidates: u32 = 1; } pub struct IsRegistered; @@ -205,9 +202,9 @@ impl Config for Test { type Currency = Balances; type UpdateOrigin = EnsureSignedBy; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<20>; + type MinEligibleCollators = ConstU32<1>; + type MaxInvulnerables = ConstU32<20>; type KickThreshold = Period; type ValidatorId = ::AccountId; type ValidatorIdOf = IdentityCollator; diff --git a/cumulus/pallets/collator-selection/src/tests.rs b/cumulus/pallets/collator-selection/src/tests.rs index 9014b6eff6..deefb5bd2d 100644 --- a/cumulus/pallets/collator-selection/src/tests.rs +++ b/cumulus/pallets/collator-selection/src/tests.rs @@ -50,16 +50,22 @@ fn it_should_set_invulnerables() { CollatorSelection::set_invulnerables(RuntimeOrigin::signed(1), new_set), BadOrigin ); + }); +} - // cannot set invulnerables without associated validator keys - let invulnerables = vec![42]; - assert_noop!( - CollatorSelection::set_invulnerables( - RuntimeOrigin::signed(RootAccount::get()), - invulnerables - ), - Error::::ValidatorNotRegistered - ); +#[test] +fn it_should_set_invulnerables_even_with_some_invalid() { + new_test_ext().execute_with(|| { + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]); + let new_with_invalid = vec![1, 4, 3, 42, 2]; + + assert_ok!(CollatorSelection::set_invulnerables( + RuntimeOrigin::signed(RootAccount::get()), + new_with_invalid + )); + + // should succeed and order them, but not include 42 + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2, 3, 4]); }); } @@ -190,6 +196,54 @@ fn remove_invulnerable_works() { }); } +#[test] +fn candidate_to_invulnerable_works() { + new_test_ext().execute_with(|| { + initialize_to_block(1); + assert_eq!(CollatorSelection::desired_candidates(), 2); + assert_eq!(CollatorSelection::candidacy_bond(), 10); + assert_eq!(CollatorSelection::candidates(), Vec::new()); + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]); + + assert_eq!(Balances::free_balance(3), 100); + assert_eq!(Balances::free_balance(4), 100); + + assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3))); + assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4))); + + assert_eq!(Balances::free_balance(3), 90); + assert_eq!(Balances::free_balance(4), 90); + + assert_ok!(CollatorSelection::add_invulnerable( + RuntimeOrigin::signed(RootAccount::get()), + 3 + )); + System::assert_has_event(RuntimeEvent::CollatorSelection(crate::Event::CandidateRemoved { + account_id: 3, + })); + System::assert_has_event(RuntimeEvent::CollatorSelection( + crate::Event::InvulnerableAdded { account_id: 3 }, + )); + assert!(CollatorSelection::invulnerables().to_vec().contains(&3)); + assert_eq!(Balances::free_balance(3), 100); + assert_eq!(CollatorSelection::candidates().len(), 1); + + assert_ok!(CollatorSelection::add_invulnerable( + RuntimeOrigin::signed(RootAccount::get()), + 4 + )); + System::assert_has_event(RuntimeEvent::CollatorSelection(crate::Event::CandidateRemoved { + account_id: 4, + })); + System::assert_has_event(RuntimeEvent::CollatorSelection( + crate::Event::InvulnerableAdded { account_id: 4 }, + )); + assert!(CollatorSelection::invulnerables().to_vec().contains(&4)); + assert_eq!(Balances::free_balance(4), 100); + assert_eq!(CollatorSelection::candidates().len(), 0); + }); +} + #[test] fn set_desired_candidates_works() { new_test_ext().execute_with(|| { @@ -256,14 +310,31 @@ fn cannot_register_candidate_if_too_many() { #[test] fn cannot_unregister_candidate_if_too_few() { new_test_ext().execute_with(|| { + assert_eq!(CollatorSelection::candidates(), Vec::new()); + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]); + assert_ok!(CollatorSelection::remove_invulnerable( + RuntimeOrigin::signed(RootAccount::get()), + 1 + )); + assert_noop!( + CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 2), + Error::::TooFewEligibleCollators, + ); + // reset desired candidates: >::put(1); assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4))); + // now we can remove `2` + assert_ok!(CollatorSelection::remove_invulnerable( + RuntimeOrigin::signed(RootAccount::get()), + 2 + )); + // can not remove too few assert_noop!( CollatorSelection::leave_intent(RuntimeOrigin::signed(4)), - Error::::TooFewCandidates, + Error::::TooFewEligibleCollators, ); }) } @@ -487,28 +558,71 @@ fn kick_mechanism() { #[test] fn should_not_kick_mechanism_too_few() { new_test_ext().execute_with(|| { - // add a new collator + // remove the invulnerables and add new collators 3 and 5 + assert_eq!(CollatorSelection::candidates(), Vec::new()); + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]); + assert_ok!(CollatorSelection::remove_invulnerable( + RuntimeOrigin::signed(RootAccount::get()), + 1 + )); assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3))); assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5))); + assert_ok!(CollatorSelection::remove_invulnerable( + RuntimeOrigin::signed(RootAccount::get()), + 2 + )); + initialize_to_block(10); assert_eq!(CollatorSelection::candidates().len(), 2); + initialize_to_block(20); assert_eq!(SessionChangeBlock::get(), 20); - // 4 authored this block, 5 gets to stay too few 3 was kicked + // 4 authored this block, 3 is kicked, 5 stays because of too few collators assert_eq!(CollatorSelection::candidates().len(), 1); // 3 will be kicked after 1 session delay - assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]); + assert_eq!(SessionHandlerCollators::get(), vec![3, 5]); let collator = CandidateInfo { who: 5, deposit: 10 }; assert_eq!(CollatorSelection::candidates(), vec![collator]); assert_eq!(CollatorSelection::last_authored_block(4), 20); + initialize_to_block(30); // 3 gets kicked after 1 session delay - assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]); + assert_eq!(SessionHandlerCollators::get(), vec![5]); // kicked collator gets funds back assert_eq!(Balances::free_balance(3), 100); }); } +#[test] +fn should_kick_invulnerables_from_candidates_on_session_change() { + new_test_ext().execute_with(|| { + assert_eq!(CollatorSelection::candidates(), Vec::new()); + assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3))); + assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4))); + assert_eq!(Balances::free_balance(3), 90); + assert_eq!(Balances::free_balance(4), 90); + assert_ok!(CollatorSelection::set_invulnerables( + RuntimeOrigin::signed(RootAccount::get()), + vec![1, 2, 3] + )); + + let collator_3 = CandidateInfo { who: 3, deposit: 10 }; + let collator_4 = CandidateInfo { who: 4, deposit: 10 }; + + assert_eq!(CollatorSelection::candidates(), vec![collator_3, collator_4.clone()]); + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2, 3]); + + // session change + initialize_to_block(10); + // 3 is removed from candidates + assert_eq!(CollatorSelection::candidates(), vec![collator_4]); + // but not from invulnerables + assert_eq!(CollatorSelection::invulnerables(), vec![1, 2, 3]); + // and it got its deposit back + assert_eq!(Balances::free_balance(3), 100); + }); +} + #[test] #[should_panic = "duplicate invulnerables in genesis."] fn cannot_set_genesis_value_twice() { diff --git a/cumulus/pallets/collator-selection/src/weights.rs b/cumulus/pallets/collator-selection/src/weights.rs index 6b02d28d67..7d227da291 100644 --- a/cumulus/pallets/collator-selection/src/weights.rs +++ b/cumulus/pallets/collator-selection/src/weights.rs @@ -27,7 +27,7 @@ use sp_std::marker::PhantomData; // The weight info trait for `pallet_collator_selection`. pub trait WeightInfo { fn set_invulnerables(_b: u32) -> Weight; - fn add_invulnerable(_b: u32) -> Weight; + fn add_invulnerable(_b: u32, _c: u32) -> Weight; fn remove_invulnerable(_b: u32) -> Weight; fn set_desired_candidates() -> Weight; fn set_candidacy_bond() -> Weight; @@ -82,23 +82,31 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes(2_u64.saturating_mul(r as u64))) .saturating_add(T::DbWeight::get().writes(2_u64.saturating_mul(c as u64))) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) @@ -161,23 +169,31 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(2_u64.saturating_mul(r as u64))) .saturating_add(RocksDbWeight::get().writes(2_u64.saturating_mul(c as u64))) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index d111aff023..c767092329 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -433,10 +433,7 @@ impl pallet_aura::Config for Runtime { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 1000; - pub const MinCandidates: u32 = 5; pub const SessionLength: BlockNumber = 6 * HOURS; - pub const MaxInvulnerables: u32 = 100; // StakingAdmin pluralistic body. pub const StakingAdminBodyId: BodyId = BodyId::Defense; } @@ -452,9 +449,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs index 75ddf23040..79be952450 100644 --- a/cumulus/parachains/common/src/impls.rs +++ b/cumulus/parachains/common/src/impls.rs @@ -222,9 +222,6 @@ mod tests { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 20; - pub const MaxInvulnerables: u32 = 20; - pub const MinCandidates: u32 = 1; } impl pallet_collator_selection::Config for Test { @@ -232,9 +229,9 @@ mod tests { type Currency = Balances; type UpdateOrigin = EnsureRoot; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<20>; + type MinEligibleCollators = ConstU32<1>; + type MaxInvulnerables = ConstU32<20>; type ValidatorId = ::AccountId; type ValidatorIdOf = IdentityCollator; type ValidatorRegistration = IsRegistered; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/lib.rs index 8097a114ea..ab570daa21 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/lib.rs @@ -598,10 +598,7 @@ impl pallet_aura::Config for Runtime { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 1000; - pub const MinCandidates: u32 = 5; pub const SessionLength: BlockNumber = 6 * HOURS; - pub const MaxInvulnerables: u32 = 100; // StakingAdmin pluralistic body. pub const StakingAdminBodyId: BodyId = BodyId::Defense; } @@ -617,9 +614,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_collator_selection.rs index bac78a8d37..910dce813f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs index c11a26ba6c..ea578c6070 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs @@ -611,10 +611,7 @@ impl pallet_aura::Config for Runtime { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 1000; - pub const MinCandidates: u32 = 5; pub const SessionLength: BlockNumber = 6 * HOURS; - pub const MaxInvulnerables: u32 = 100; // `StakingAdmin` pluralistic body. pub const StakingAdminBodyId: BodyId = BodyId::Defense; } @@ -630,9 +627,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_collator_selection.rs index f26fd83b17..c82a634258 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 88ff06e4fb..2dffccae27 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -637,10 +637,7 @@ impl pallet_aura::Config for Runtime { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 1000; - pub const MinCandidates: u32 = 1; pub const SessionLength: BlockNumber = 6 * HOURS; - pub const MaxInvulnerables: u32 = 100; } pub type CollatorSelectionUpdateOrigin = EnsureRoot; @@ -650,9 +647,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_collator_selection.rs index 0746670988..9ff6de553e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/lib.rs index f5b84b8e67..3d828d110f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/lib.rs @@ -352,7 +352,7 @@ parameter_types! { pub const StakingAdminBodyId: BodyId = BodyId::Defense; } -/// We allow root, the StakingAdmin to execute privileged collator selection operations. +/// We allow Root and the `StakingAdmin` to execute privileged collator selection operations. pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< EnsureRoot, EnsureXcm>, @@ -363,9 +363,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = ConstU32<1000>; - type MinCandidates = ConstU32<5>; - type MaxInvulnerables = ConstU32<100>; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = ConstU32; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_collator_selection.rs index 59a867d8ab..ba55055521 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/lib.rs index 865c74df65..58203829f7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/lib.rs @@ -363,9 +363,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = ConstU32<1000>; - type MinCandidates = ConstU32<5>; - type MaxInvulnerables = ConstU32<100>; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = ConstU32; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_collator_selection.rs index 424da20230..9c54874229 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 8b71e15087..043988068d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -361,9 +361,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = ConstU32<1000>; - type MinCandidates = ConstU32<5>; - type MaxInvulnerables = ConstU32<100>; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = ConstU32; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_collator_selection.rs index a91daf3ea8..c525871e52 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/lib.rs index 5ca00d8c79..ce512d2353 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/lib.rs @@ -436,9 +436,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = ConstU32<1000>; - type MinCandidates = ConstU32<5>; - type MaxInvulnerables = ConstU32<100>; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = ConstU32; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_collator_selection.rs index 05843b159a..f55cfead0e 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_collator_selection.rs @@ -147,23 +147,31 @@ impl pallet_collator_selection::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: CollatorSelection Invulnerables (r:1 w:1) - /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) /// Storage: Session NextKeys (r:1 w:0) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 99]`. - fn add_invulnerable(b: u32, ) -> Weight { + /// Storage: CollatorSelection Invulnerables (r:1 w:1) + /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(641), added: 1136, mode: MaxEncodedLen) + /// Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `581 + b * (37 ±0)` - // Estimated: `4687 + b * (37 ±0)` - // Minimum execution time: 269_126_000 picoseconds. - Weight::from_parts(286_711_880, 0) - .saturating_add(Weight::from_parts(0, 4687)) - // Standard Error: 22_887 - .saturating_add(Weight::from_parts(813_399, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + .saturating_add(Weight::from_parts(26_422, 0).saturating_mul(b.into())) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: CollatorSelection Invulnerables (r:1 w:1) /// Proof: CollatorSelection Invulnerables (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index e96b067a73..5f5d419ca9 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -318,9 +318,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = ConstU32<1000>; - type MinCandidates = ConstU32<0>; - type MaxInvulnerables = ConstU32<100>; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<1>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId; diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index ba0d5198b5..54ada9fea4 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -511,10 +511,7 @@ impl pallet_aura::Config for Runtime { parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 1000; - pub const MinCandidates: u32 = 5; pub const SessionLength: BlockNumber = 6 * HOURS; - pub const MaxInvulnerables: u32 = 100; pub const ExecutiveBody: BodyId = BodyId::Executive; } @@ -526,9 +523,9 @@ impl pallet_collator_selection::Config for Runtime { type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; + type MaxCandidates = ConstU32<100>; + type MinEligibleCollators = ConstU32<4>; + type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId;