Ensure correct variant count in Runtime[Hold/Freeze]Reason (#1900)

closes https://github.com/paritytech/polkadot-sdk/issues/1882

## Breaking Changes

This PR introduces a new item to `pallet_balances::Config`:

```diff
trait Config {
++    type RuntimeFreezeReasons;
}
```

This value is only used to check it against `type MaxFreeze`. A similar
check has been added for `MaxHolds` against `RuntimeHoldReasons`, which
is already given to `pallet_balances`.

In all contexts, you should pass the real `RuntimeFreezeReasons`
generated by `construct_runtime` to `type RuntimeFreezeReasons`. Passing
`()` would also work, but it would imply that the runtime uses no
freezes at all.

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Kian Paimani
2023-10-24 11:01:04 +01:00
committed by GitHub
parent a5a2432d22
commit 35eb133baa
102 changed files with 154 additions and 10 deletions
+1
View File
@@ -69,6 +69,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -87,6 +87,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -73,6 +73,7 @@ impl pallet_balances::Config for Test {
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type FreezeIdentifier = ();
type MaxHolds = ();
type MaxFreezes = ();
+1
View File
@@ -83,6 +83,7 @@ impl pallet_balances::Config for Test {
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type FreezeIdentifier = ();
type MaxHolds = ();
type MaxFreezes = ();
+1
View File
@@ -77,6 +77,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -125,6 +125,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+21 -2
View File
@@ -207,7 +207,7 @@ pub mod pallet {
use super::*;
use frame_support::{
pallet_prelude::*,
traits::{fungible::Credit, tokens::Precision},
traits::{fungible::Credit, tokens::Precision, VariantCount},
};
use frame_system::pallet_prelude::*;
@@ -229,6 +229,8 @@ pub mod pallet {
type RuntimeEvent = ();
#[inject_runtime_type]
type RuntimeHoldReason = ();
#[inject_runtime_type]
type RuntimeFreezeReason = ();
type Balance = u64;
type ExistentialDeposit = ConstU64<1>;
@@ -256,7 +258,11 @@ pub mod pallet {
/// The overarching hold reason.
#[pallet::no_default_bounds]
type RuntimeHoldReason: Parameter + Member + MaxEncodedLen + Copy;
type RuntimeHoldReason: Parameter + Member + MaxEncodedLen + Copy + VariantCount;
/// The overarching freeze reason.
#[pallet::no_default_bounds]
type RuntimeFreezeReason: VariantCount;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
@@ -544,6 +550,19 @@ pub mod pallet {
!<T as Config<I>>::ExistentialDeposit::get().is_zero(),
"The existential deposit must be greater than zero!"
);
assert!(
T::MaxHolds::get() >= <T::RuntimeHoldReason as VariantCount>::VARIANT_COUNT,
"MaxHolds should be greater than or equal to the number of hold reasons: {} < {}",
T::MaxHolds::get(),
<T::RuntimeHoldReason as VariantCount>::VARIANT_COUNT
);
assert!(
T::MaxFreezes::get() >= <T::RuntimeFreezeReason as VariantCount>::VARIANT_COUNT,
"MaxFreezes should be greater than or equal to the number of freeze reasons: {} < {}",
T::MaxFreezes::get(), <T::RuntimeFreezeReason as VariantCount>::VARIANT_COUNT,
);
}
}
+7 -2
View File
@@ -27,7 +27,7 @@ use frame_support::{
parameter_types,
traits::{
fungible, ConstU32, ConstU64, ConstU8, Imbalance as ImbalanceT, OnUnbalanced,
StorageMapShim, StoredMap, WhitelistedStorageKeys,
StorageMapShim, StoredMap, VariantCount, WhitelistedStorageKeys,
},
weights::{IdentityFee, Weight},
};
@@ -70,6 +70,10 @@ pub enum TestId {
Baz,
}
impl VariantCount for TestId {
const VARIANT_COUNT: u32 = 3;
}
frame_support::construct_runtime!(
pub struct Test
{
@@ -132,9 +136,10 @@ impl Config for Test {
type ReserveIdentifier = TestId;
type WeightInfo = ();
type RuntimeHoldReason = TestId;
type RuntimeFreezeReason = RuntimeFreezeReason;
type FreezeIdentifier = TestId;
type MaxFreezes = ConstU32<2>;
type MaxHolds = ConstU32<2>;
type MaxHolds = ConstU32<3>;
}
#[derive(Clone)]
+1
View File
@@ -135,6 +135,7 @@ impl pallet_balances::Config for Test {
type AccountStore = System;
type WeightInfo = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
+1
View File
@@ -98,6 +98,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
@@ -101,6 +101,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
+1
View File
@@ -370,6 +370,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type MaxHolds = ConstU32<1>;
}
@@ -90,6 +90,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -140,6 +140,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
@@ -253,6 +253,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -114,6 +114,7 @@ impl pallet_balances::Config for Runtime {
type MaxHolds = ConstU32<1>;
type MaxFreezes = traits::ConstU32<1>;
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type FreezeIdentifier = ();
type WeightInfo = ();
}
@@ -1360,6 +1360,7 @@ mod tests {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -84,6 +84,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -78,6 +78,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type MaxHolds = ();
}
@@ -56,6 +56,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -904,6 +904,7 @@ mod tests {
type FreezeIdentifier = ();
type MaxFreezes = ConstU32<1>;
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ConstU32<1>;
}
+1
View File
@@ -76,6 +76,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -141,6 +141,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -83,6 +83,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -74,6 +74,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -86,6 +86,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -86,6 +86,7 @@ impl pallet_balances::Config for Test {
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type MaxHolds = ConstU32<1>;
type FreezeIdentifier = ();
type MaxFreezes = ();
+1
View File
@@ -85,6 +85,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -313,6 +313,7 @@ mod tests {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+2
View File
@@ -89,6 +89,7 @@ impl pallet_balances::Config<Instance1> for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type MaxHolds = ConstU32<1>;
}
@@ -109,6 +110,7 @@ impl pallet_balances::Config<Instance2> for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -77,6 +77,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = RuntimeFreezeReason;
type MaxFreezes = ConstU32<1>;
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -247,6 +247,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = RuntimeFreezeReason;
type MaxFreezes = ConstU32<1>;
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -88,6 +88,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = RuntimeFreezeReason;
type MaxFreezes = ConstU32<1>;
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -79,6 +79,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -82,6 +82,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ConstU32<1>;
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ConstU32<2>;
}
+1
View File
@@ -84,6 +84,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -116,6 +116,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
@@ -123,6 +123,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -79,6 +79,7 @@ impl pallet_balances::Config for Test {
type MaxReserves = ConstU32<10>;
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type FreezeIdentifier = ();
type MaxHolds = ConstU32<10>;
type MaxFreezes = ConstU32<0>;
+1
View File
@@ -90,6 +90,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -84,6 +84,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -97,6 +97,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -162,6 +162,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -1126,6 +1126,7 @@ mod mock {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -86,6 +86,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type MaxHolds = ();
}
@@ -46,6 +46,7 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
));
}
}
let freeze_reason_variants_count = freeze_reason_variants.len() as u32;
quote! {
/// A reason for placing a freeze on funds.
@@ -59,6 +60,10 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
#( #freeze_reason_variants )*
}
impl #scrate::traits::VariantCount for RuntimeFreezeReason {
const VARIANT_COUNT: u32 = #freeze_reason_variants_count;
}
#( #conversion_fns )*
}
}
@@ -46,6 +46,7 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
));
}
}
let hold_reason_variants_count = hold_reason_variants.len() as u32;
quote! {
/// A reason for placing a hold on funds.
@@ -59,6 +60,10 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
#( #hold_reason_variants )*
}
impl #scrate::traits::VariantCount for RuntimeHoldReason {
const VARIANT_COUNT: u32 = #hold_reason_variants_count;
}
#( #conversion_fns )*
}
}
+1 -1
View File
@@ -61,7 +61,7 @@ pub use misc::{
DefensiveTruncateFrom, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee,
ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType,
Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time,
TryCollect, TryDrop, TypedGet, UnixTime, WrapperKeepOpaque, WrapperOpaque,
TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, WrapperKeepOpaque, WrapperOpaque,
};
#[allow(deprecated)]
pub use misc::{PreimageProvider, PreimageRecipient};
@@ -36,6 +36,18 @@ pub const DEFENSIVE_OP_PUBLIC_ERROR: &str = "a defensive failure has been trigge
#[doc(hidden)]
pub const DEFENSIVE_OP_INTERNAL_ERROR: &str = "Defensive failure has been triggered!";
/// Trait to get the number of variants in any enum.
///
/// NOTE: can be removed once <https://doc.rust-lang.org/std/mem/fn.variant_count.html> is stable.
pub trait VariantCount {
/// Get the number of variants.
const VARIANT_COUNT: u32;
}
impl VariantCount for () {
const VARIANT_COUNT: u32 = 0;
}
/// Generic function to mark an execution path as ONLY defensive.
///
/// Similar to mark a match arm or `if/else` branch as `unreachable!`.
+1
View File
@@ -95,6 +95,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
@@ -121,6 +121,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -113,6 +113,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -108,6 +108,7 @@ impl pallet_balances::Config for Runtime {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
@@ -81,6 +81,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -92,6 +92,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -78,6 +78,7 @@ impl pallet_balances::Config for Test {
type ReserveIdentifier = [u8; 8];
type FreezeIdentifier = ();
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type MaxHolds = ConstU32<0>;
type MaxFreezes = ConstU32<0>;
}
+1
View File
@@ -80,6 +80,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -183,6 +183,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
+1
View File
@@ -78,6 +78,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
+1
View File
@@ -83,6 +83,7 @@ impl pallet_balances::Config for Test {
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}