Fix update_lock (#10485)

* Fix update_lock

* Fixes

* Formatting

* add `inc_consumers_without_limits` to session too

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Gavin Wood
2021-12-15 01:27:13 +01:00
committed by GitHub
parent 1d3b51361a
commit 7ee25416c2
4 changed files with 56 additions and 11 deletions
+51 -7
View File
@@ -85,8 +85,8 @@ use frame_support::{
dispatch::{DispatchResult, DispatchResultWithPostInfo},
storage,
traits::{
Contains, EnsureOrigin, Get, HandleLifetime, OnKilledAccount, OnNewAccount, OriginTrait,
PalletInfo, SortedMembers, StoredMap,
ConstU32, Contains, EnsureOrigin, Get, HandleLifetime, OnKilledAccount, OnNewAccount,
OriginTrait, PalletInfo, SortedMembers, StoredMap,
},
weights::{
extract_actual_weight, DispatchClass, DispatchInfo, PerDispatchClass, RuntimeDbWeight,
@@ -154,6 +154,36 @@ impl<T: Config> SetCode<T> for () {
}
}
/// Numeric limits over the ability to add a consumer ref using `inc_consumers`.
pub trait ConsumerLimits {
/// The number of consumers over which `inc_consumers` will cease to work.
fn max_consumers() -> RefCount;
/// The maximum number of additional consumers expected to be over be added at once using
/// `inc_consumers_without_limit`.
///
/// Note: This is not enforced and it's up to the chain's author to ensure this reflects the
/// actual situation.
fn max_overflow() -> RefCount;
}
impl<const Z: u32> ConsumerLimits for ConstU32<Z> {
fn max_consumers() -> RefCount {
Z
}
fn max_overflow() -> RefCount {
Z
}
}
impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal, MaxOverflow) {
fn max_consumers() -> RefCount {
MaxNormal::get()
}
fn max_overflow() -> RefCount {
MaxOverflow::get()
}
}
#[frame_support::pallet]
pub mod pallet {
use crate::{self as frame_system, pallet_prelude::*, *};
@@ -310,8 +340,7 @@ pub mod pallet {
type OnSetCode: SetCode<Self>;
/// The maximum number of consumers allowed on a single account.
#[pallet::constant]
type MaxConsumers: Get<RefCount>;
type MaxConsumers: ConsumerLimits;
}
#[pallet::pallet]
@@ -1122,11 +1151,12 @@ impl<T: Config> Pallet<T> {
/// Increment the reference counter on an account.
///
/// The account `who`'s `providers` must be non-zero or this will return an error.
/// The account `who`'s `providers` must be non-zero and the current number of consumers must
/// be less than `MaxConsumers::max_consumers()` or this will return an error.
pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
Account::<T>::try_mutate(who, |a| {
if a.providers > 0 {
if a.consumers < T::MaxConsumers::get() {
if a.consumers < T::MaxConsumers::max_consumers() {
a.consumers = a.consumers.saturating_add(1);
Ok(())
} else {
@@ -1138,6 +1168,20 @@ impl<T: Config> Pallet<T> {
})
}
/// Increment the reference counter on an account, ignoring the `MaxConsumers` limits.
///
/// The account `who`'s `providers` must be non-zero or this will return an error.
pub fn inc_consumers_without_limit(who: &T::AccountId) -> Result<(), DispatchError> {
Account::<T>::try_mutate(who, |a| {
if a.providers > 0 {
a.consumers = a.consumers.saturating_add(1);
Ok(())
} else {
Err(DispatchError::NoProviders)
}
})
}
/// Decrement the reference counter on an account. This *MUST* only be done once for every time
/// you called `inc_consumers` on `who`.
pub fn dec_consumers(who: &T::AccountId) {
@@ -1172,7 +1216,7 @@ impl<T: Config> Pallet<T> {
/// True if the account has at least one provider reference.
pub fn can_inc_consumer(who: &T::AccountId) -> bool {
let a = Account::<T>::get(who);
a.providers > 0 && a.consumers < T::MaxConsumers::get()
a.providers > 0 && a.consumers < T::MaxConsumers::max_consumers()
}
/// Deposits an event into this block's event record.