diff --git a/frame/atomic-swap/src/lib.rs b/frame/atomic-swap/src/lib.rs index e83055b4d283e..e57496954a574 100644 --- a/frame/atomic-swap/src/lib.rs +++ b/frame/atomic-swap/src/lib.rs @@ -45,6 +45,7 @@ mod tests; use codec::{Decode, Encode}; use frame_support::{ dispatch::DispatchResult, + pallet_prelude::MaxEncodedLen, traits::{BalanceStatus, Currency, Get, ReservableCurrency}, weights::Weight, RuntimeDebugNoBound, @@ -59,8 +60,9 @@ use sp_std::{ }; /// Pending atomic swap operation. -#[derive(Clone, Eq, PartialEq, RuntimeDebugNoBound, Encode, Decode, TypeInfo)] +#[derive(Clone, Eq, PartialEq, RuntimeDebugNoBound, Encode, Decode, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(T))] +#[codec(mel_bound())] pub struct PendingSwap { /// Source of the swap. pub source: T::AccountId, @@ -93,8 +95,9 @@ pub trait SwapAction { } /// A swap action that only allows transferring balances. -#[derive(Clone, RuntimeDebug, Eq, PartialEq, Encode, Decode, TypeInfo)] +#[derive(Clone, RuntimeDebug, Eq, PartialEq, Encode, Decode, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(C))] +#[codec(mel_bound())] pub struct BalanceSwapAction> { value: >::Balance, _marker: PhantomData, @@ -165,7 +168,7 @@ pub mod pallet { /// The overarching event type. type Event: From> + IsType<::Event>; /// Swap action. - type SwapAction: SwapAction + Parameter; + type SwapAction: SwapAction + Parameter + MaxEncodedLen; /// Limit of proof size. /// /// Atomic swap is only atomic if once the proof is revealed, both parties can submit the @@ -182,7 +185,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(PhantomData); #[pallet::storage] @@ -193,6 +195,9 @@ pub mod pallet { Blake2_128Concat, HashedProof, PendingSwap, + OptionQuery, + GetDefault, + ConstU32<300_000>, >; #[pallet::error] diff --git a/frame/bags-list/src/list/mod.rs b/frame/bags-list/src/list/mod.rs index aba31b67b2863..8cd89b8fff1cc 100644 --- a/frame/bags-list/src/list/mod.rs +++ b/frame/bags-list/src/list/mod.rs @@ -545,7 +545,7 @@ impl List { /// iteration so that there's no incentive to churn ids positioning to improve the chances of /// appearing within the ids set. #[derive(DefaultNoBound, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[codec(mel_bound(T: Config))] +#[codec(mel_bound())] #[scale_info(skip_type_params(T))] #[cfg_attr(feature = "std", derive(frame_support::DebugNoBound, Clone, PartialEq))] pub struct Bag { @@ -748,7 +748,7 @@ impl Bag { /// A Node is the fundamental element comprising the doubly-linked list described by `Bag`. #[derive(Encode, Decode, MaxEncodedLen, TypeInfo)] -#[codec(mel_bound(T: Config))] +#[codec(mel_bound())] #[scale_info(skip_type_params(T))] #[cfg_attr(feature = "std", derive(frame_support::DebugNoBound, Clone, PartialEq))] pub struct Node { diff --git a/frame/beefy-mmr/src/lib.rs b/frame/beefy-mmr/src/lib.rs index d66de51d9af21..38d0a6ac9a7f8 100644 --- a/frame/beefy-mmr/src/lib.rs +++ b/frame/beefy-mmr/src/lib.rs @@ -119,7 +119,6 @@ pub mod pallet { /// BEEFY-MMR pallet. #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); /// The module's configuration trait. diff --git a/frame/bounties/src/lib.rs b/frame/bounties/src/lib.rs index d46180f6bbe19..988b15c58a13f 100644 --- a/frame/bounties/src/lib.rs +++ b/frame/bounties/src/lib.rs @@ -107,7 +107,7 @@ type PositiveImbalanceOf = pallet_treasury::PositiveImbalanceOf; pub type BountyIndex = u32; /// A bounty proposal. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct Bounty { /// The account proposing it. proposer: AccountId, @@ -133,7 +133,7 @@ impl } /// The status of a bounty proposal. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum BountyStatus { /// The bounty is proposed and waiting for approval. Proposed, @@ -180,7 +180,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] @@ -249,6 +248,8 @@ pub mod pallet { Premature, /// The bounty cannot be closed because it has active child-bounties. HasActiveChildBounty, + /// Too many approvals are already queued. + TooManyQueued, } #[pallet::event] @@ -288,12 +289,14 @@ pub mod pallet { /// The description of each bounty. #[pallet::storage] #[pallet::getter(fn bounty_descriptions)] - pub type BountyDescriptions = StorageMap<_, Twox64Concat, BountyIndex, Vec>; + pub type BountyDescriptions = + StorageMap<_, Twox64Concat, BountyIndex, BoundedVec>; /// Bounty indices that have been approved but not yet funded. #[pallet::storage] #[pallet::getter(fn bounty_approvals)] - pub type BountyApprovals = StorageValue<_, Vec, ValueQuery>; + pub type BountyApprovals = + StorageValue<_, BoundedVec, ValueQuery>; #[pallet::call] impl Pallet { @@ -341,7 +344,8 @@ pub mod pallet { bounty.status = BountyStatus::Approved; - BountyApprovals::::append(bounty_id); + BountyApprovals::::try_append(bounty_id) + .map_err(|()| Error::::TooManyQueued)?; Ok(()) })?; @@ -780,17 +784,15 @@ impl Pallet { description: Vec, value: BalanceOf, ) -> DispatchResult { - ensure!( - description.len() <= T::MaximumReasonLength::get() as usize, - Error::::ReasonTooBig - ); + let bounded_description: BoundedVec<_, _> = + description.try_into().map_err(|()| Error::::ReasonTooBig)?; ensure!(value >= T::BountyValueMinimum::get(), Error::::InvalidValue); let index = Self::bounty_count(); // reserve deposit for new bounty let bond = T::BountyDepositBase::get() + - T::DataDepositPerByte::get() * (description.len() as u32).into(); + T::DataDepositPerByte::get() * (bounded_description.len() as u32).into(); T::Currency::reserve(&proposer, bond) .map_err(|_| Error::::InsufficientProposersBalance)?; @@ -806,7 +808,7 @@ impl Pallet { }; Bounties::::insert(index, &bounty); - BountyDescriptions::::insert(index, description); + BountyDescriptions::::insert(index, bounded_description); Self::deposit_event(Event::::BountyProposed { index }); diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 3be1062ce969a..491daa58523e6 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -87,7 +87,7 @@ pub struct PrefabWasmModule { /// /// It is stored in a separate storage entry to avoid loading the code when not necessary. #[derive(Clone, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] -#[codec(mel_bound(T: Config))] +#[codec(mel_bound())] #[scale_info(skip_type_params(T))] pub struct OwnerInfo { /// The account that has deployed the contract and hence is allowed to remove it. diff --git a/frame/election-provider-multi-phase/src/lib.rs b/frame/election-provider-multi-phase/src/lib.rs index a5ed593e1a4ee..cad3d12605e48 100644 --- a/frame/election-provider-multi-phase/src/lib.rs +++ b/frame/election-provider-multi-phase/src/lib.rs @@ -460,7 +460,7 @@ pub struct ReadySolution { /// /// These are stored together because they are often accessed together. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, Default, TypeInfo)] -#[codec(mel_bound(T: Config))] +#[codec(mel_bound())] #[scale_info(skip_type_params(T))] pub struct RoundSnapshot { /// All of the voters. diff --git a/frame/examples/offchain-worker/src/lib.rs b/frame/examples/offchain-worker/src/lib.rs index 08f449f8d51d0..3cf718217b062 100644 --- a/frame/examples/offchain-worker/src/lib.rs +++ b/frame/examples/offchain-worker/src/lib.rs @@ -154,11 +154,14 @@ pub mod pallet { /// multiple pallets send unsigned transactions. #[pallet::constant] type UnsignedPriority: Get; + + /// Maximum number of prices. + #[pallet::constant] + type MaxPrices: Get; } #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::hooks] @@ -330,7 +333,7 @@ pub mod pallet { /// This is used to calculate average price, should have bounded size. #[pallet::storage] #[pallet::getter(fn prices)] - pub(super) type Prices = StorageValue<_, Vec, ValueQuery>; + pub(super) type Prices = StorageValue<_, BoundedVec, ValueQuery>; /// Defines the block when next unsigned transaction will be accepted. /// @@ -645,12 +648,8 @@ impl Pallet { fn add_price(maybe_who: Option, price: u32) { log::info!("Adding to the average: {}", price); >::mutate(|prices| { - const MAX_LEN: usize = 64; - - if prices.len() < MAX_LEN { - prices.push(price); - } else { - prices[price as usize % MAX_LEN] = price; + if prices.try_push(price).is_err() { + prices[(price % T::MaxPrices::get()) as usize] = price; } }); diff --git a/frame/examples/offchain-worker/src/tests.rs b/frame/examples/offchain-worker/src/tests.rs index 76f80deb12f90..e5bd9fabc629b 100644 --- a/frame/examples/offchain-worker/src/tests.rs +++ b/frame/examples/offchain-worker/src/tests.rs @@ -123,6 +123,7 @@ impl Config for Test { type GracePeriod = ConstU64<5>; type UnsignedInterval = ConstU64<128>; type UnsignedPriority = UnsignedPriority; + type MaxPrices = ConstU32<64>; } fn test_pub() -> sp_core::sr25519::Public { diff --git a/frame/gilt/src/lib.rs b/frame/gilt/src/lib.rs index ac56dc108b2f6..8956e04857f2c 100644 --- a/frame/gilt/src/lib.rs +++ b/frame/gilt/src/lib.rs @@ -112,7 +112,8 @@ pub mod pallet { + sp_std::fmt::Debug + Default + From - + TypeInfo; + + TypeInfo + + MaxEncodedLen; /// Origin required for setting the target proportion to be under gilt. type AdminOrigin: EnsureOrigin; @@ -178,11 +179,12 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); /// A single bid on a gilt, an item of a *queue* in `Queues`. - #[derive(Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo)] + #[derive( + Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen, + )] pub struct GiltBid { /// The amount bid. pub amount: Balance, @@ -191,7 +193,9 @@ pub mod pallet { } /// Information representing an active gilt. - #[derive(Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo)] + #[derive( + Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen, + )] pub struct ActiveGilt { /// The proportion of the effective total issuance (i.e. accounting for any eventual gilt /// expansion or contraction that may eventually be claimed). @@ -215,7 +219,9 @@ pub mod pallet { /// `issuance - frozen + proportion * issuance` /// /// where `issuance = total_issuance - IgnoredIssuance` - #[derive(Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo)] + #[derive( + Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen, + )] pub struct ActiveGiltsTotal { /// The total amount of funds held in reserve for all active gilts. pub frozen: Balance, @@ -233,12 +239,18 @@ pub mod pallet { /// The vector is indexed by duration in `Period`s, offset by one, so information on the queue /// whose duration is one `Period` would be storage `0`. #[pallet::storage] - pub type QueueTotals = StorageValue<_, Vec<(u32, BalanceOf)>, ValueQuery>; + pub type QueueTotals = + StorageValue<_, BoundedVec<(u32, BalanceOf), T::QueueCount>, ValueQuery>; /// The queues of bids ready to become gilts. Indexed by duration (in `Period`s). #[pallet::storage] - pub type Queues = - StorageMap<_, Blake2_128Concat, u32, Vec, T::AccountId>>, ValueQuery>; + pub type Queues = StorageMap< + _, + Blake2_128Concat, + u32, + BoundedVec, T::AccountId>, T::MaxQueueLen>, + ValueQuery, + >; /// Information relating to the gilts currently active. #[pallet::storage] @@ -265,7 +277,11 @@ pub mod pallet { #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - QueueTotals::::put(vec![(0, BalanceOf::::zero()); T::QueueCount::get() as usize]); + let unbounded = vec![(0, BalanceOf::::zero()); T::QueueCount::get() as usize]; + let bounded: BoundedVec<_, _> = unbounded + .try_into() + .expect("QueueTotals should support up to QueueCount items. qed"); + QueueTotals::::put(bounded); } } @@ -366,7 +382,7 @@ pub mod pallet { T::Currency::unreserve(&bid.who, bid.amount); (0, amount - bid.amount) } else { - q.insert(0, bid); + q.try_insert(0, bid).expect("verified queue was not full above. qed."); (1, amount) }; @@ -379,7 +395,7 @@ pub mod pallet { }, )?; QueueTotals::::mutate(|qs| { - qs.resize(queue_count, (0, Zero::zero())); + qs.bounded_resize(queue_count, (0, Zero::zero())); qs[queue_index].0 += net.0; qs[queue_index].1 = qs[queue_index].1.saturating_add(net.1); }); @@ -415,7 +431,7 @@ pub mod pallet { })?; QueueTotals::::mutate(|qs| { - qs.resize(queue_count, (0, Zero::zero())); + qs.bounded_resize(queue_count, (0, Zero::zero())); qs[queue_index].0 = new_len; qs[queue_index].1 = qs[queue_index].1.saturating_sub(bid.amount); }); @@ -592,7 +608,8 @@ pub mod pallet { if remaining < bid.amount { let overflow = bid.amount - remaining; bid.amount = remaining; - q.push(GiltBid { amount: overflow, who: bid.who.clone() }); + q.try_push(GiltBid { amount: overflow, who: bid.who.clone() }) + .expect("just popped, so there must be space. qed"); } let amount = bid.amount; // Can never overflow due to block above. diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 0aaf0f679ce11..68d4cf26a2e23 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -364,13 +364,9 @@ pub type BoundedAuthorityList = WeakBoundedVec<(AuthorityId, AuthorityWei /// A stored pending change. /// `Limit` is the bound for `next_authorities` #[derive(Encode, Decode, TypeInfo, MaxEncodedLen)] -#[codec(mel_bound(Limit: Get))] +#[codec(mel_bound(N: MaxEncodedLen, Limit: Get))] #[scale_info(skip_type_params(Limit))] -pub struct StoredPendingChange -where - Limit: Get, - N: MaxEncodedLen, -{ +pub struct StoredPendingChange { /// The block number this was scheduled at. pub scheduled_at: N, /// The delay in blocks until it will be applied. diff --git a/frame/identity/src/types.rs b/frame/identity/src/types.rs index d91adc8cdd768..cb79ace98d81c 100644 --- a/frame/identity/src/types.rs +++ b/frame/identity/src/types.rs @@ -283,7 +283,7 @@ impl TypeInfo for IdentityFields { #[derive( CloneNoBound, Encode, Decode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] -#[codec(mel_bound(FieldLimit: Get))] +#[codec(mel_bound())] #[cfg_attr(test, derive(frame_support::DefaultNoBound))] #[scale_info(skip_type_params(FieldLimit))] pub struct IdentityInfo> { @@ -339,11 +339,7 @@ pub struct IdentityInfo> { #[derive( CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] -#[codec(mel_bound( - Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq + Zero + Add, - MaxJudgements: Get, - MaxAdditionalFields: Get, -))] +#[codec(mel_bound())] #[scale_info(skip_type_params(MaxJudgements, MaxAdditionalFields))] pub struct Registration< Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq, diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 5ad27850a2c1f..e2213ef4169b1 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -238,8 +238,7 @@ where /// `MultiAddrEncodingLimit` represents the size limit of the encoding of `MultiAddr` /// `AddressesLimit` represents the size limit of the vector of peers connected #[derive(Clone, Eq, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)] -#[codec(mel_bound(PeerIdEncodingLimit: Get, - MultiAddrEncodingLimit: Get, AddressesLimit: Get))] +#[codec(mel_bound())] #[scale_info(skip_type_params(PeerIdEncodingLimit, MultiAddrEncodingLimit, AddressesLimit))] pub struct BoundedOpaqueNetworkState where diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 7d23fa5e8c7f1..9c9e3580f2c04 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -56,7 +56,8 @@ pub mod pallet { + Codec + Default + AtLeast32Bit - + Copy; + + Copy + + MaxEncodedLen; /// The currency trait. type Currency: ReservableCurrency; @@ -74,7 +75,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(PhantomData); #[pallet::call] diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 2a93dc7af2892..f904428e02048 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -84,7 +84,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(PhantomData<(T, I)>); /// This pallet's configuration trait @@ -126,7 +125,8 @@ pub mod pallet { + Default + codec::Codec + codec::EncodeLike - + scale_info::TypeInfo; + + scale_info::TypeInfo + + MaxEncodedLen; /// Data stored in the leaf nodes. /// diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 9e4ecf8b2b1a3..c7c2c675bc014 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -110,11 +110,10 @@ pub mod pallet { /// The lookup table for names. #[pallet::storage] pub(super) type NameOf = - StorageMap<_, Twox64Concat, T::AccountId, (Vec, BalanceOf)>; + StorageMap<_, Twox64Concat, T::AccountId, (BoundedVec, BalanceOf)>; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::call] @@ -139,8 +138,9 @@ pub mod pallet { pub fn set_name(origin: OriginFor, name: Vec) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(name.len() >= T::MinLength::get() as usize, Error::::TooShort); - ensure!(name.len() <= T::MaxLength::get() as usize, Error::::TooLong); + let bounded_name: BoundedVec<_, _> = + name.try_into().map_err(|()| Error::::TooLong)?; + ensure!(bounded_name.len() >= T::MinLength::get() as usize, Error::::TooShort); let deposit = if let Some((_, deposit)) = >::get(&sender) { Self::deposit_event(Event::::NameChanged { who: sender.clone() }); @@ -152,7 +152,7 @@ pub mod pallet { deposit }; - >::insert(&sender, (name, deposit)); + >::insert(&sender, (bounded_name, deposit)); Ok(()) } @@ -230,9 +230,11 @@ pub mod pallet { ) -> DispatchResult { T::ForceOrigin::ensure_origin(origin)?; + let bounded_name: BoundedVec<_, _> = + name.try_into().map_err(|()| Error::::TooLong)?; let target = T::Lookup::lookup(target)?; let deposit = >::get(&target).map(|x| x.1).unwrap_or_else(Zero::zero); - >::insert(&target, (name, deposit)); + >::insert(&target, (bounded_name, deposit)); Self::deposit_event(Event::::NameForced { target }); Ok(()) @@ -356,9 +358,15 @@ mod tests { assert_ok!(Nicks::set_name(Origin::signed(2), b"Dave".to_vec())); assert_eq!(Balances::reserved_balance(2), 2); - assert_ok!(Nicks::force_name(Origin::signed(1), 2, b"Dr. David Brubeck, III".to_vec())); + assert_noop!( + Nicks::force_name(Origin::signed(1), 2, b"Dr. David Brubeck, III".to_vec()), + Error::::TooLong, + ); + assert_ok!(Nicks::force_name(Origin::signed(1), 2, b"Dr. Brubeck, III".to_vec())); assert_eq!(Balances::reserved_balance(2), 2); - assert_eq!(>::get(2).unwrap(), (b"Dr. David Brubeck, III".to_vec(), 2)); + let (name, amount) = >::get(2).unwrap(); + assert_eq!(name, b"Dr. Brubeck, III".to_vec()); + assert_eq!(amount, 2); }); } diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index a74c58405de4f..b72aa665550cf 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -91,7 +91,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] @@ -103,9 +102,7 @@ pub mod pallet { let parent_hash = >::parent_hash(); >::mutate(|ref mut values| { - if values.len() < RANDOM_MATERIAL_LEN as usize { - values.push(parent_hash) - } else { + if values.try_push(parent_hash).is_err() { let index = block_number_to_index::(block_number); values[index] = parent_hash; } @@ -120,7 +117,8 @@ pub mod pallet { /// the oldest hash. #[pallet::storage] #[pallet::getter(fn random_material)] - pub(super) type RandomMaterial = StorageValue<_, Vec, ValueQuery>; + pub(super) type RandomMaterial = + StorageValue<_, BoundedVec>, ValueQuery>; } impl Randomness for Pallet { diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index f5a57843a983b..adc5c0b895c5f 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -154,7 +154,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_runtime::traits::{CheckedAdd, CheckedMul, Dispatchable, SaturatedConversion}; use sp_std::prelude::*; @@ -163,7 +163,7 @@ use frame_support::{ dispatch::PostDispatchInfo, traits::{BalanceStatus, Currency, ReservableCurrency}, weights::GetDispatchInfo, - RuntimeDebug, + BoundedVec, RuntimeDebug, }; pub use pallet::*; @@ -176,21 +176,23 @@ mod tests; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type FriendsOf = BoundedVec<::AccountId, ::MaxFriends>; + /// An active recovery process. -#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo)] -pub struct ActiveRecovery { +#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct ActiveRecovery { /// The block number when the recovery process started. created: BlockNumber, /// The amount held in reserve of the `depositor`, /// To be returned once this recovery process is closed. deposit: Balance, /// The friends which have vouched so far. Always sorted. - friends: Vec, + friends: Friends, } /// Configuration for recovering an account. -#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo)] -pub struct RecoveryConfig { +#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct RecoveryConfig { /// The minimum number of blocks since the start of the recovery process before the account /// can be recovered. delay_period: BlockNumber, @@ -198,7 +200,7 @@ pub struct RecoveryConfig { /// to be returned once this configuration is removed. deposit: Balance, /// The list of friends which can help recover an account. Always sorted. - friends: Vec, + friends: Friends, /// The number of approving friends needed to recover an account. threshold: u16, } @@ -212,7 +214,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); /// Configuration trait. @@ -245,8 +246,13 @@ pub mod pallet { type FriendDepositFactor: Get>; /// The maximum amount of friends allowed in a recovery configuration. + /// + /// NOTE: The threshold programmed in this Pallet uses u16, so it does + /// not really make sense to have a limit here greater than u16::MAX. + /// But also, that is a lot more than you should probably set this value + /// to anyway... #[pallet::constant] - type MaxFriends: Get; + type MaxFriends: Get; /// The base amount of currency needed to reserve for starting a recovery. /// @@ -324,7 +330,7 @@ pub mod pallet { _, Twox64Concat, T::AccountId, - RecoveryConfig, T::AccountId>, + RecoveryConfig, FriendsOf>, >; /// Active recovery attempts. @@ -339,7 +345,7 @@ pub mod pallet { T::AccountId, Twox64Concat, T::AccountId, - ActiveRecovery, T::AccountId>, + ActiveRecovery, FriendsOf>, >; /// The list of allowed proxy accounts. @@ -458,12 +464,12 @@ pub mod pallet { ensure!(threshold >= 1, Error::::ZeroThreshold); ensure!(!friends.is_empty(), Error::::NotEnoughFriends); ensure!(threshold as usize <= friends.len(), Error::::NotEnoughFriends); - let max_friends = T::MaxFriends::get() as usize; - ensure!(friends.len() <= max_friends, Error::::MaxFriends); - ensure!(Self::is_sorted_and_unique(&friends), Error::::NotSorted); + let bounded_friends: FriendsOf = + friends.try_into().map_err(|()| Error::::MaxFriends)?; + ensure!(Self::is_sorted_and_unique(&bounded_friends), Error::::NotSorted); // Total deposit is base fee + number of friends * factor fee let friend_deposit = T::FriendDepositFactor::get() - .checked_mul(&friends.len().saturated_into()) + .checked_mul(&bounded_friends.len().saturated_into()) .ok_or(ArithmeticError::Overflow)?; let total_deposit = T::ConfigDepositBase::get() .checked_add(&friend_deposit) @@ -471,8 +477,12 @@ pub mod pallet { // Reserve the deposit T::Currency::reserve(&who, total_deposit)?; // Create the recovery configuration - let recovery_config = - RecoveryConfig { delay_period, deposit: total_deposit, friends, threshold }; + let recovery_config = RecoveryConfig { + delay_period, + deposit: total_deposit, + friends: bounded_friends, + threshold, + }; // Create the recovery configuration storage item >::insert(&who, recovery_config); @@ -519,7 +529,7 @@ pub mod pallet { let recovery_status = ActiveRecovery { created: >::block_number(), deposit: recovery_deposit, - friends: vec![], + friends: Default::default(), }; // Create the active recovery storage item >::insert(&account, &who, recovery_status); @@ -571,7 +581,10 @@ pub mod pallet { // Either insert the vouch, or return an error that the user already vouched. match active_recovery.friends.binary_search(&who) { Ok(_pos) => Err(Error::::AlreadyVouched)?, - Err(pos) => active_recovery.friends.insert(pos, who.clone()), + Err(pos) => active_recovery + .friends + .try_insert(pos, who.clone()) + .map_err(|()| Error::::MaxFriends)?, } // Update storage with the latest details >::insert(&lost, &rescuer, active_recovery); diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 577aa7dee7117..2088f9eb0937e 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -22,7 +22,7 @@ use super::*; use crate as recovery; use frame_support::{ parameter_types, - traits::{ConstU16, ConstU32, ConstU64, OnFinalize, OnInitialize}, + traits::{ConstU32, ConstU64, OnFinalize, OnInitialize}, }; use sp_core::H256; use sp_runtime::{ @@ -105,7 +105,7 @@ impl Config for Test { type Currency = Balances; type ConfigDepositBase = ConfigDepositBase; type FriendDepositFactor = FriendDepositFactor; - type MaxFriends = ConstU16<3>; + type MaxFriends = ConstU32<3>; type RecoveryDeposit = RecoveryDeposit; } diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index 7d1da6353a3ad..16fc678d357bb 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -18,7 +18,7 @@ //! Tests for the module. use super::*; -use frame_support::{assert_noop, assert_ok, traits::Currency}; +use frame_support::{assert_noop, assert_ok, bounded_vec, traits::Currency}; use mock::{ new_test_ext, run_to_block, Balances, BalancesCall, Call, Origin, Recovery, RecoveryCall, Test, }; @@ -201,8 +201,12 @@ fn create_recovery_works() { // Base 10 + 1 per friends = 13 total reserved assert_eq!(Balances::reserved_balance(5), 13); // Recovery configuration is correctly stored - let recovery_config = - RecoveryConfig { delay_period, deposit: 13, friends: friends.clone(), threshold }; + let recovery_config = RecoveryConfig { + delay_period, + deposit: 13, + friends: friends.try_into().unwrap(), + threshold, + }; assert_eq!(Recovery::recovery_config(5), Some(recovery_config)); }); } @@ -254,7 +258,8 @@ fn initiate_recovery_works() { // Deposit is reserved assert_eq!(Balances::reserved_balance(1), 10); // Recovery status object is created correctly - let recovery_status = ActiveRecovery { created: 0, deposit: 10, friends: vec![] }; + let recovery_status = + ActiveRecovery { created: 0, deposit: 10, friends: Default::default() }; assert_eq!(>::get(&5, &1), Some(recovery_status)); // Multiple users can attempt to recover the same account assert_ok!(Recovery::initiate_recovery(Origin::signed(2), 5)); @@ -314,7 +319,8 @@ fn vouch_recovery_works() { assert_ok!(Recovery::vouch_recovery(Origin::signed(4), 5, 1)); assert_ok!(Recovery::vouch_recovery(Origin::signed(3), 5, 1)); // Final recovery status object is updated correctly - let recovery_status = ActiveRecovery { created: 0, deposit: 10, friends: vec![2, 3, 4] }; + let recovery_status = + ActiveRecovery { created: 0, deposit: 10, friends: bounded_vec![2, 3, 4] }; assert_eq!(>::get(&5, &1), Some(recovery_status)); }); } diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index f1d4cd1e07c2a..17af4829c0ea8 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -576,7 +576,7 @@ where /// A record of the nominations made by a specific account. #[derive(PartialEqNoBound, EqNoBound, Clone, Encode, Decode, RuntimeDebugNoBound, TypeInfo)] -#[codec(mel_bound(T: Config))] +#[codec(mel_bound())] #[scale_info(skip_type_params(T))] pub struct Nominations { /// The targets of nomination. diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 16d2ff5827c4f..e4d77a05f284b 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -47,7 +47,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_runtime::{ @@ -226,7 +226,7 @@ where } /// Storage releases of the pallet. -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] enum Releases { /// Original version of the pallet. V1Ancient, @@ -248,7 +248,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 762c0e592d891..81fca5243afa3 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -193,6 +193,8 @@ pub mod pallet { type SpendFunds: SpendFunds; /// The maximum number of approvals that can wait in the spending queue. + /// + /// NOTE: This parameter is also used within the Bounties Pallet extension if enabled. #[pallet::constant] type MaxApprovals: Get; } diff --git a/frame/uniques/src/lib.rs b/frame/uniques/src/lib.rs index 3a0b34e5bf407..2956735e5ec3e 100644 --- a/frame/uniques/src/lib.rs +++ b/frame/uniques/src/lib.rs @@ -62,7 +62,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] @@ -72,10 +71,16 @@ pub mod pallet { type Event: From> + IsType<::Event>; /// Identifier for the class of asset. - type ClassId: Member + Parameter + Default + Copy + HasCompact; + type ClassId: Member + Parameter + Default + Copy + HasCompact + MaxEncodedLen; /// The type used to identify a unique asset within an asset class. - type InstanceId: Member + Parameter + Default + Copy + HasCompact + From; + type InstanceId: Member + + Parameter + + Default + + Copy + + HasCompact + + From + + MaxEncodedLen; /// The currency mechanism, used for paying for reserves. type Currency: ReservableCurrency; diff --git a/frame/uniques/src/types.rs b/frame/uniques/src/types.rs index 4d1afe694bd8d..b5aee6912fec2 100644 --- a/frame/uniques/src/types.rs +++ b/frame/uniques/src/types.rs @@ -18,7 +18,10 @@ //! Various basic types for use in the assets pallet. use super::*; -use frame_support::{traits::Get, BoundedVec}; +use frame_support::{ + pallet_prelude::{BoundedVec, MaxEncodedLen}, + traits::Get, +}; use scale_info::TypeInfo; pub(super) type DepositBalanceOf = @@ -28,7 +31,7 @@ pub(super) type ClassDetailsFor = pub(super) type InstanceDetailsFor = InstanceDetails<::AccountId, DepositBalanceOf>; -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ClassDetails { /// Can change `owner`, `issuer`, `freezer` and `admin` accounts. pub(super) owner: AccountId, @@ -54,7 +57,7 @@ pub struct ClassDetails { } /// Witness data for the destroy transactions. -#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct DestroyWitness { /// The total number of outstanding instances of this asset class. #[codec(compact)] @@ -78,7 +81,7 @@ impl ClassDetails { } /// Information concerning the ownership of a single unique asset. -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] pub struct InstanceDetails { /// The owner of this asset. pub(super) owner: AccountId, @@ -91,8 +94,9 @@ pub struct InstanceDetails { pub(super) deposit: DepositBalance, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(StringLimit))] +#[codec(mel_bound(DepositBalance: MaxEncodedLen))] pub struct ClassMetadata> { /// The balance deposited for this metadata. /// @@ -106,8 +110,9 @@ pub struct ClassMetadata> { pub(super) is_frozen: bool, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(StringLimit))] +#[codec(mel_bound(DepositBalance: MaxEncodedLen))] pub struct InstanceMetadata> { /// The balance deposited for this metadata. /// diff --git a/primitives/beefy/src/mmr.rs b/primitives/beefy/src/mmr.rs index 215214bef2942..29f513629d012 100644 --- a/primitives/beefy/src/mmr.rs +++ b/primitives/beefy/src/mmr.rs @@ -26,7 +26,7 @@ //! but we imagine they will be useful for other chains that either want to bridge with Polkadot //! or are completely standalone, but heavily inspired by Polkadot. -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; /// A standard leaf that gets added every block to the MMR constructed by Substrate's `pallet_mmr`. @@ -81,7 +81,7 @@ impl MmrLeafVersion { } /// Details of the next BEEFY authority set. -#[derive(Debug, Default, PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] +#[derive(Debug, Default, PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)] pub struct BeefyNextAuthoritySet { /// Id of the next set. ///