Skip to content

Commit ca0fb0d

Browse files
authored
pallet_balances: Add try_state for checking Holds and Freezes (#4490)
Co-authored-by: command-bot <>
1 parent 2c48b9d commit ca0fb0d

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

substrate/frame/balances/src/lib.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,8 @@ pub mod pallet {
542542

543543
#[pallet::hooks]
544544
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
545-
#[cfg(not(feature = "insecure_zero_ed"))]
546545
fn integrity_test() {
546+
#[cfg(not(feature = "insecure_zero_ed"))]
547547
assert!(
548548
!<T as Config<I>>::ExistentialDeposit::get().is_zero(),
549549
"The existential deposit must be greater than zero!"
@@ -555,6 +555,29 @@ pub mod pallet {
555555
T::MaxFreezes::get(), <T::RuntimeFreezeReason as VariantCount>::VARIANT_COUNT,
556556
);
557557
}
558+
559+
#[cfg(feature = "try-runtime")]
560+
fn try_state(_n: BlockNumberFor<T>) -> Result<(), sp_runtime::TryRuntimeError> {
561+
Holds::<T, I>::iter_keys().try_for_each(|k| {
562+
if Holds::<T, I>::decode_len(k).unwrap_or(0) >
563+
T::RuntimeHoldReason::VARIANT_COUNT as usize
564+
{
565+
Err("Found `Hold` with too many elements")
566+
} else {
567+
Ok(())
568+
}
569+
})?;
570+
571+
Freezes::<T, I>::iter_keys().try_for_each(|k| {
572+
if Freezes::<T, I>::decode_len(k).unwrap_or(0) > T::MaxFreezes::get() as usize {
573+
Err("Found `Freeze` with too many elements")
574+
} else {
575+
Ok(())
576+
}
577+
})?;
578+
579+
Ok(())
580+
}
558581
}
559582

560583
#[pallet::call(weight(<T as Config<I>>::WeightInfo))]

substrate/frame/balances/src/tests/general_tests.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,35 @@ fn regression_historic_acc_does_not_evaporate_reserve() {
109109
});
110110
});
111111
}
112+
113+
#[cfg(feature = "try-runtime")]
114+
#[test]
115+
fn try_state_works() {
116+
use crate::{Config, Freezes, Holds};
117+
use frame_support::{
118+
storage,
119+
traits::{Get, Hooks, VariantCount},
120+
};
121+
122+
ExtBuilder::default().build_and_execute_with(|| {
123+
storage::unhashed::put(
124+
&Holds::<Test>::hashed_key_for(1),
125+
&vec![0u8; <Test as Config>::RuntimeHoldReason::VARIANT_COUNT as usize + 1],
126+
);
127+
128+
assert!(format!("{:?}", Balances::try_state(0).unwrap_err())
129+
.contains("Found `Hold` with too many elements"));
130+
});
131+
132+
ExtBuilder::default().build_and_execute_with(|| {
133+
let max_freezes: u32 = <Test as Config>::MaxFreezes::get();
134+
135+
storage::unhashed::put(
136+
&Freezes::<Test>::hashed_key_for(1),
137+
&vec![0u8; max_freezes as usize + 1],
138+
);
139+
140+
assert!(format!("{:?}", Balances::try_state(0).unwrap_err())
141+
.contains("Found `Freeze` with too many elements"));
142+
});
143+
}

0 commit comments

Comments
 (0)