Add Storage Info to Various Pallets (#10810)

* atomic swap

* bounties

* bounties fmt

* gilt

* indices

* nicks

* randomness-collective-flip

* recovery

* reuse maxapprovals

* Update tests.rs

* Update frame/randomness-collective-flip/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* use the correct bound

* complete recovery

* use `bounded_vec` macro

* Update tests.rs

* transaction payment

* uniques

* mmr

* example offchain worker

* beefy-mmr

* Update frame/recovery/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Use BoundedVec instead of a type-parameterized BoundedString

* cargo fmt

* Update frame/atomic-swap/src/lib.rs

* use config const

* Update lib.rs

* update mel_bound

* fmt

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
This commit is contained in:
Shawn Tabrizi
2022-02-08 15:10:35 +01:00
committed by GitHub
parent d14e1c641e
commit f6f82d876b
25 changed files with 165 additions and 115 deletions
+9 -4
View File
@@ -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<T: Config> {
/// Source of the swap.
pub source: T::AccountId,
@@ -93,8 +95,9 @@ pub trait SwapAction<AccountId, T: Config> {
}
/// 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<AccountId, C: ReservableCurrency<AccountId>> {
value: <C as Currency<AccountId>>::Balance,
_marker: PhantomData<C>,
@@ -165,7 +168,7 @@ pub mod pallet {
/// The overarching event type.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// Swap action.
type SwapAction: SwapAction<Self::AccountId, Self> + Parameter;
type SwapAction: SwapAction<Self::AccountId, Self> + 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<T>(PhantomData<T>);
#[pallet::storage]
@@ -193,6 +195,9 @@ pub mod pallet {
Blake2_128Concat,
HashedProof,
PendingSwap<T>,
OptionQuery,
GetDefault,
ConstU32<300_000>,
>;
#[pallet::error]
+2 -2
View File
@@ -545,7 +545,7 @@ impl<T: Config> List<T> {
/// 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<T: Config> {
@@ -748,7 +748,7 @@ impl<T: Config> Bag<T> {
/// 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<T: Config> {
-1
View File
@@ -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<T>(_);
/// The module's configuration trait.
+14 -12
View File
@@ -107,7 +107,7 @@ type PositiveImbalanceOf<T> = pallet_treasury::PositiveImbalanceOf<T>;
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<AccountId, Balance, BlockNumber> {
/// The account proposing it.
proposer: AccountId,
@@ -133,7 +133,7 @@ impl<AccountId: PartialEq + Clone + Ord, Balance, BlockNumber: Clone>
}
/// 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<AccountId, BlockNumber> {
/// 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<T>(_);
#[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<T: Config> = StorageMap<_, Twox64Concat, BountyIndex, Vec<u8>>;
pub type BountyDescriptions<T: Config> =
StorageMap<_, Twox64Concat, BountyIndex, BoundedVec<u8, T::MaximumReasonLength>>;
/// Bounty indices that have been approved but not yet funded.
#[pallet::storage]
#[pallet::getter(fn bounty_approvals)]
pub type BountyApprovals<T: Config> = StorageValue<_, Vec<BountyIndex>, ValueQuery>;
pub type BountyApprovals<T: Config> =
StorageValue<_, BoundedVec<BountyIndex, T::MaxApprovals>, ValueQuery>;
#[pallet::call]
impl<T: Config> Pallet<T> {
@@ -341,7 +344,8 @@ pub mod pallet {
bounty.status = BountyStatus::Approved;
BountyApprovals::<T>::append(bounty_id);
BountyApprovals::<T>::try_append(bounty_id)
.map_err(|()| Error::<T>::TooManyQueued)?;
Ok(())
})?;
@@ -780,17 +784,15 @@ impl<T: Config> Pallet<T> {
description: Vec<u8>,
value: BalanceOf<T>,
) -> DispatchResult {
ensure!(
description.len() <= T::MaximumReasonLength::get() as usize,
Error::<T>::ReasonTooBig
);
let bounded_description: BoundedVec<_, _> =
description.try_into().map_err(|()| Error::<T>::ReasonTooBig)?;
ensure!(value >= T::BountyValueMinimum::get(), Error::<T>::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::<T>::InsufficientProposersBalance)?;
@@ -806,7 +808,7 @@ impl<T: Config> Pallet<T> {
};
Bounties::<T>::insert(index, &bounty);
BountyDescriptions::<T>::insert(index, description);
BountyDescriptions::<T>::insert(index, bounded_description);
Self::deposit_event(Event::<T>::BountyProposed { index });
+1 -1
View File
@@ -87,7 +87,7 @@ pub struct PrefabWasmModule<T: Config> {
///
/// 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<T: Config> {
/// The account that has deployed the contract and hence is allowed to remove it.
@@ -460,7 +460,7 @@ pub struct ReadySolution<A> {
///
/// 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<T: Config> {
/// All of the voters.
@@ -154,11 +154,14 @@ pub mod pallet {
/// multiple pallets send unsigned transactions.
#[pallet::constant]
type UnsignedPriority: Get<TransactionPriority>;
/// Maximum number of prices.
#[pallet::constant]
type MaxPrices: Get<u32>;
}
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);
#[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<T: Config> = StorageValue<_, Vec<u32>, ValueQuery>;
pub(super) type Prices<T: Config> = StorageValue<_, BoundedVec<u32, T::MaxPrices>, ValueQuery>;
/// Defines the block when next unsigned transaction will be accepted.
///
@@ -645,12 +648,8 @@ impl<T: Config> Pallet<T> {
fn add_price(maybe_who: Option<T::AccountId>, price: u32) {
log::info!("Adding to the average: {}", price);
<Prices<T>>::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;
}
});
@@ -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 {
+30 -13
View File
@@ -112,7 +112,8 @@ pub mod pallet {
+ sp_std::fmt::Debug
+ Default
+ From<u64>
+ TypeInfo;
+ TypeInfo
+ MaxEncodedLen;
/// Origin required for setting the target proportion to be under gilt.
type AdminOrigin: EnsureOrigin<Self::Origin>;
@@ -178,11 +179,12 @@ pub mod pallet {
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);
/// 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<Balance, AccountId> {
/// 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<Balance, AccountId, BlockNumber> {
/// 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<Balance> {
/// 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<T> = StorageValue<_, Vec<(u32, BalanceOf<T>)>, ValueQuery>;
pub type QueueTotals<T: Config> =
StorageValue<_, BoundedVec<(u32, BalanceOf<T>), T::QueueCount>, ValueQuery>;
/// The queues of bids ready to become gilts. Indexed by duration (in `Period`s).
#[pallet::storage]
pub type Queues<T: Config> =
StorageMap<_, Blake2_128Concat, u32, Vec<GiltBid<BalanceOf<T>, T::AccountId>>, ValueQuery>;
pub type Queues<T: Config> = StorageMap<
_,
Blake2_128Concat,
u32,
BoundedVec<GiltBid<BalanceOf<T>, 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<T: Config> GenesisBuild<T> for GenesisConfig {
fn build(&self) {
QueueTotals::<T>::put(vec![(0, BalanceOf::<T>::zero()); T::QueueCount::get() as usize]);
let unbounded = vec![(0, BalanceOf::<T>::zero()); T::QueueCount::get() as usize];
let bounded: BoundedVec<_, _> = unbounded
.try_into()
.expect("QueueTotals should support up to QueueCount items. qed");
QueueTotals::<T>::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::<T>::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::<T>::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.
+2 -6
View File
@@ -364,13 +364,9 @@ pub type BoundedAuthorityList<Limit> = WeakBoundedVec<(AuthorityId, AuthorityWei
/// A stored pending change.
/// `Limit` is the bound for `next_authorities`
#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
#[codec(mel_bound(Limit: Get<u32>))]
#[codec(mel_bound(N: MaxEncodedLen, Limit: Get<u32>))]
#[scale_info(skip_type_params(Limit))]
pub struct StoredPendingChange<N, Limit>
where
Limit: Get<u32>,
N: MaxEncodedLen,
{
pub struct StoredPendingChange<N, Limit> {
/// The block number this was scheduled at.
pub scheduled_at: N,
/// The delay in blocks until it will be applied.
+2 -6
View File
@@ -283,7 +283,7 @@ impl TypeInfo for IdentityFields {
#[derive(
CloneNoBound, Encode, Decode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo,
)]
#[codec(mel_bound(FieldLimit: Get<u32>))]
#[codec(mel_bound())]
#[cfg_attr(test, derive(frame_support::DefaultNoBound))]
#[scale_info(skip_type_params(FieldLimit))]
pub struct IdentityInfo<FieldLimit: Get<u32>> {
@@ -339,11 +339,7 @@ pub struct IdentityInfo<FieldLimit: Get<u32>> {
#[derive(
CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo,
)]
#[codec(mel_bound(
Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq + Zero + Add,
MaxJudgements: Get<u32>,
MaxAdditionalFields: Get<u32>,
))]
#[codec(mel_bound())]
#[scale_info(skip_type_params(MaxJudgements, MaxAdditionalFields))]
pub struct Registration<
Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq,
+1 -2
View File
@@ -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<u32>,
MultiAddrEncodingLimit: Get<u32>, AddressesLimit: Get<u32>))]
#[codec(mel_bound())]
#[scale_info(skip_type_params(PeerIdEncodingLimit, MultiAddrEncodingLimit, AddressesLimit))]
pub struct BoundedOpaqueNetworkState<PeerIdEncodingLimit, MultiAddrEncodingLimit, AddressesLimit>
where
+2 -2
View File
@@ -56,7 +56,8 @@ pub mod pallet {
+ Codec
+ Default
+ AtLeast32Bit
+ Copy;
+ Copy
+ MaxEncodedLen;
/// The currency trait.
type Currency: ReservableCurrency<Self::AccountId>;
@@ -74,7 +75,6 @@ pub mod pallet {
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T>(PhantomData<T>);
#[pallet::call]
@@ -84,7 +84,6 @@ pub mod pallet {
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T, I = ()>(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.
///
+16 -8
View File
@@ -110,11 +110,10 @@ pub mod pallet {
/// The lookup table for names.
#[pallet::storage]
pub(super) type NameOf<T: Config> =
StorageMap<_, Twox64Concat, T::AccountId, (Vec<u8>, BalanceOf<T>)>;
StorageMap<_, Twox64Concat, T::AccountId, (BoundedVec<u8, T::MaxLength>, BalanceOf<T>)>;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);
#[pallet::call]
@@ -139,8 +138,9 @@ pub mod pallet {
pub fn set_name(origin: OriginFor<T>, name: Vec<u8>) -> DispatchResult {
let sender = ensure_signed(origin)?;
ensure!(name.len() >= T::MinLength::get() as usize, Error::<T>::TooShort);
ensure!(name.len() <= T::MaxLength::get() as usize, Error::<T>::TooLong);
let bounded_name: BoundedVec<_, _> =
name.try_into().map_err(|()| Error::<T>::TooLong)?;
ensure!(bounded_name.len() >= T::MinLength::get() as usize, Error::<T>::TooShort);
let deposit = if let Some((_, deposit)) = <NameOf<T>>::get(&sender) {
Self::deposit_event(Event::<T>::NameChanged { who: sender.clone() });
@@ -152,7 +152,7 @@ pub mod pallet {
deposit
};
<NameOf<T>>::insert(&sender, (name, deposit));
<NameOf<T>>::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::<T>::TooLong)?;
let target = T::Lookup::lookup(target)?;
let deposit = <NameOf<T>>::get(&target).map(|x| x.1).unwrap_or_else(Zero::zero);
<NameOf<T>>::insert(&target, (name, deposit));
<NameOf<T>>::insert(&target, (bounded_name, deposit));
Self::deposit_event(Event::<T>::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::<Test>::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!(<NameOf<Test>>::get(2).unwrap(), (b"Dr. David Brubeck, III".to_vec(), 2));
let (name, amount) = <NameOf<Test>>::get(2).unwrap();
assert_eq!(name, b"Dr. Brubeck, III".to_vec());
assert_eq!(amount, 2);
});
}
@@ -91,7 +91,6 @@ pub mod pallet {
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);
#[pallet::config]
@@ -103,9 +102,7 @@ pub mod pallet {
let parent_hash = <frame_system::Pallet<T>>::parent_hash();
<RandomMaterial<T>>::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::<T>(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<T: Config> = StorageValue<_, Vec<T::Hash>, ValueQuery>;
pub(super) type RandomMaterial<T: Config> =
StorageValue<_, BoundedVec<T::Hash, ConstU32<RANDOM_MATERIAL_LEN>>, ValueQuery>;
}
impl<T: Config> Randomness<T::Hash, T::BlockNumber> for Pallet<T> {
+33 -20
View File
@@ -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<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
type FriendsOf<T> = BoundedVec<<T as frame_system::Config>::AccountId, <T as Config>::MaxFriends>;
/// An active recovery process.
#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo)]
pub struct ActiveRecovery<BlockNumber, Balance, AccountId> {
#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct ActiveRecovery<BlockNumber, Balance, Friends> {
/// 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<AccountId>,
friends: Friends,
}
/// Configuration for recovering an account.
#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo)]
pub struct RecoveryConfig<BlockNumber, Balance, AccountId> {
#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct RecoveryConfig<BlockNumber, Balance, Friends> {
/// 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<BlockNumber, Balance, AccountId> {
/// to be returned once this configuration is removed.
deposit: Balance,
/// The list of friends which can help recover an account. Always sorted.
friends: Vec<AccountId>,
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<T>(_);
/// Configuration trait.
@@ -245,8 +246,13 @@ pub mod pallet {
type FriendDepositFactor: Get<BalanceOf<Self>>;
/// 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<u16>;
type MaxFriends: Get<u32>;
/// The base amount of currency needed to reserve for starting a recovery.
///
@@ -324,7 +330,7 @@ pub mod pallet {
_,
Twox64Concat,
T::AccountId,
RecoveryConfig<T::BlockNumber, BalanceOf<T>, T::AccountId>,
RecoveryConfig<T::BlockNumber, BalanceOf<T>, FriendsOf<T>>,
>;
/// Active recovery attempts.
@@ -339,7 +345,7 @@ pub mod pallet {
T::AccountId,
Twox64Concat,
T::AccountId,
ActiveRecovery<T::BlockNumber, BalanceOf<T>, T::AccountId>,
ActiveRecovery<T::BlockNumber, BalanceOf<T>, FriendsOf<T>>,
>;
/// The list of allowed proxy accounts.
@@ -458,12 +464,12 @@ pub mod pallet {
ensure!(threshold >= 1, Error::<T>::ZeroThreshold);
ensure!(!friends.is_empty(), Error::<T>::NotEnoughFriends);
ensure!(threshold as usize <= friends.len(), Error::<T>::NotEnoughFriends);
let max_friends = T::MaxFriends::get() as usize;
ensure!(friends.len() <= max_friends, Error::<T>::MaxFriends);
ensure!(Self::is_sorted_and_unique(&friends), Error::<T>::NotSorted);
let bounded_friends: FriendsOf<T> =
friends.try_into().map_err(|()| Error::<T>::MaxFriends)?;
ensure!(Self::is_sorted_and_unique(&bounded_friends), Error::<T>::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
<Recoverable<T>>::insert(&who, recovery_config);
@@ -519,7 +529,7 @@ pub mod pallet {
let recovery_status = ActiveRecovery {
created: <frame_system::Pallet<T>>::block_number(),
deposit: recovery_deposit,
friends: vec![],
friends: Default::default(),
};
// Create the active recovery storage item
<ActiveRecoveries<T>>::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::<T>::AlreadyVouched)?,
Err(pos) => active_recovery.friends.insert(pos, who.clone()),
Err(pos) => active_recovery
.friends
.try_insert(pos, who.clone())
.map_err(|()| Error::<T>::MaxFriends)?,
}
// Update storage with the latest details
<ActiveRecoveries<T>>::insert(&lost, &rescuer, active_recovery);
+2 -2
View File
@@ -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;
}
+11 -5
View File
@@ -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!(<ActiveRecoveries<Test>>::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!(<ActiveRecoveries<Test>>::get(&5, &1), Some(recovery_status));
});
}
+1 -1
View File
@@ -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<T: Config> {
/// The targets of nomination.
@@ -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<T>(_);
#[pallet::config]
+2
View File
@@ -193,6 +193,8 @@ pub mod pallet {
type SpendFunds: SpendFunds<Self, I>;
/// 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<u32>;
}
+8 -3
View File
@@ -62,7 +62,6 @@ pub mod pallet {
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T, I = ()>(_);
#[pallet::config]
@@ -72,10 +71,16 @@ pub mod pallet {
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::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<u16>;
type InstanceId: Member
+ Parameter
+ Default
+ Copy
+ HasCompact
+ From<u16>
+ MaxEncodedLen;
/// The currency mechanism, used for paying for reserves.
type Currency: ReservableCurrency<Self::AccountId>;
+11 -6
View File
@@ -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<T, I = ()> =
@@ -28,7 +31,7 @@ pub(super) type ClassDetailsFor<T, I> =
pub(super) type InstanceDetailsFor<T, I> =
InstanceDetails<<T as SystemConfig>::AccountId, DepositBalanceOf<T, I>>;
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)]
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct ClassDetails<AccountId, DepositBalance> {
/// Can change `owner`, `issuer`, `freezer` and `admin` accounts.
pub(super) owner: AccountId,
@@ -54,7 +57,7 @@ pub struct ClassDetails<AccountId, DepositBalance> {
}
/// 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<AccountId, DepositBalance> ClassDetails<AccountId, DepositBalance> {
}
/// 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<AccountId, DepositBalance> {
/// The owner of this asset.
pub(super) owner: AccountId,
@@ -91,8 +94,9 @@ pub struct InstanceDetails<AccountId, DepositBalance> {
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<DepositBalance, StringLimit: Get<u32>> {
/// The balance deposited for this metadata.
///
@@ -106,8 +110,9 @@ pub struct ClassMetadata<DepositBalance, StringLimit: Get<u32>> {
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<DepositBalance, StringLimit: Get<u32>> {
/// The balance deposited for this metadata.
///
+2 -2
View File
@@ -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<MerkleRoot> {
/// Id of the next set.
///