pallet_safe_mode/
benchmarking.rs1#![cfg(feature = "runtime-benchmarks")]
19
20use super::{Pallet as SafeMode, *};
21use frame::benchmarking::prelude::*;
22
23#[benchmarks(where T::Currency: fungible::Mutate<T::AccountId>)]
24mod benchmarks {
25 use super::*;
26
27 #[benchmark]
29 fn on_initialize_noop() {
30 #[block]
31 {
32 SafeMode::<T>::on_initialize(1u32.into());
33 }
34 }
35
36 #[benchmark]
38 fn on_initialize_exit() {
39 EnteredUntil::<T>::put(&BlockNumberFor::<T>::zero());
40 assert!(SafeMode::<T>::is_entered());
41
42 #[block]
43 {
44 SafeMode::<T>::on_initialize(1u32.into());
45 }
46
47 assert!(!SafeMode::<T>::is_entered());
48 }
49
50 #[benchmark]
52 fn enter() -> Result<(), BenchmarkError> {
53 T::EnterDepositAmount::get().ok_or_else(|| BenchmarkError::Weightless)?;
54
55 let caller: T::AccountId = whitelisted_caller();
56 let origin = RawOrigin::Signed(caller.clone());
57 <T::Currency as fungible::Mutate<_>>::set_balance(&caller, init_bal::<T>());
58
59 #[extrinsic_call]
60 _(origin);
61
62 assert_eq!(
63 EnteredUntil::<T>::get().unwrap(),
64 frame_system::Pallet::<T>::block_number() + T::EnterDuration::get()
65 );
66 Ok(())
67 }
68
69 #[benchmark]
71 fn force_enter() -> Result<(), BenchmarkError> {
72 let force_origin =
73 T::ForceEnterOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
74
75 let duration = T::ForceEnterOrigin::ensure_origin(force_origin.clone()).unwrap();
76
77 #[extrinsic_call]
78 _(force_origin as T::RuntimeOrigin);
79
80 assert_eq!(
81 EnteredUntil::<T>::get().unwrap(),
82 frame_system::Pallet::<T>::block_number() + duration
83 );
84 Ok(())
85 }
86
87 #[benchmark]
89 fn extend() -> Result<(), BenchmarkError> {
90 T::ExtendDepositAmount::get().ok_or_else(|| BenchmarkError::Weightless)?;
91
92 let alice: T::AccountId = whitelisted_caller();
93 <T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
94
95 frame_system::Pallet::<T>::set_block_number(1u32.into());
96 assert!(SafeMode::<T>::do_enter(None, 1u32.into()).is_ok());
97
98 #[extrinsic_call]
99 _(RawOrigin::Signed(alice));
100
101 assert_eq!(
102 EnteredUntil::<T>::get().unwrap(),
103 frame_system::Pallet::<T>::block_number() + 1u32.into() + T::ExtendDuration::get()
104 );
105 Ok(())
106 }
107
108 #[benchmark]
110 fn force_extend() -> Result<(), BenchmarkError> {
111 let force_origin = T::ForceExtendOrigin::try_successful_origin()
112 .map_err(|_| BenchmarkError::Weightless)?;
113
114 frame_system::Pallet::<T>::set_block_number(1u32.into());
115 assert!(SafeMode::<T>::do_enter(None, 1u32.into()).is_ok());
116
117 let duration = T::ForceExtendOrigin::ensure_origin(force_origin.clone()).unwrap();
118 let call = Call::<T>::force_extend {};
119
120 #[block]
121 {
122 call.dispatch_bypass_filter(force_origin)?;
123 }
124
125 assert_eq!(
126 EnteredUntil::<T>::get().unwrap(),
127 frame_system::Pallet::<T>::block_number() + 1u32.into() + duration
128 );
129 Ok(())
130 }
131
132 #[benchmark]
134 fn force_exit() -> Result<(), BenchmarkError> {
135 let force_origin =
136 T::ForceExitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
137 assert!(SafeMode::<T>::do_enter(None, 1u32.into()).is_ok());
138
139 #[extrinsic_call]
140 _(force_origin as T::RuntimeOrigin);
141
142 assert_eq!(EnteredUntil::<T>::get(), None);
143 Ok(())
144 }
145
146 #[benchmark]
148 fn release_deposit() -> Result<(), BenchmarkError> {
149 let delay = T::ReleaseDelay::get().ok_or_else(|| BenchmarkError::Weightless)?;
150
151 let alice: T::AccountId = whitelisted_caller();
152 let origin = RawOrigin::Signed(alice.clone());
153
154 <T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
155 let block: BlockNumberFor<T> = 1u32.into();
157 let bal: BalanceOf<T> = 1u32.into();
158 Deposits::<T>::insert(&alice, &block, &bal);
159 T::Currency::hold(&HoldReason::EnterOrExtend.into(), &alice, bal)?;
160 EnteredUntil::<T>::put(&block);
161 assert!(SafeMode::<T>::do_exit(ExitReason::Force).is_ok());
162
163 frame_system::Pallet::<T>::set_block_number(delay + One::one() + 2u32.into());
164 frame_system::Pallet::<T>::on_initialize(frame_system::Pallet::<T>::block_number());
165 SafeMode::<T>::on_initialize(frame_system::Pallet::<T>::block_number());
166
167 #[extrinsic_call]
168 _(origin, alice.clone(), 1u32.into());
169
170 assert!(!Deposits::<T>::contains_key(&alice, &block));
171 assert_eq!(<T::Currency as fungible::Inspect<_>>::balance(&alice), init_bal::<T>());
172 Ok(())
173 }
174
175 #[benchmark]
177 fn force_release_deposit() -> Result<(), BenchmarkError> {
178 let force_origin = T::ForceDepositOrigin::try_successful_origin()
179 .map_err(|_| BenchmarkError::Weightless)?;
180
181 let alice: T::AccountId = whitelisted_caller();
182 <T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
183
184 let block: BlockNumberFor<T> = 1u32.into();
186 let bal: BalanceOf<T> = 1u32.into();
187 Deposits::<T>::insert(&alice, &block, &bal);
188 T::Currency::hold(&&HoldReason::EnterOrExtend.into(), &alice, bal)?;
189 EnteredUntil::<T>::put(&block);
190
191 assert_eq!(
192 <T::Currency as fungible::Inspect<_>>::balance(&alice),
193 init_bal::<T>() - 1u32.into()
194 );
195 assert!(SafeMode::<T>::do_exit(ExitReason::Force).is_ok());
196
197 frame_system::Pallet::<T>::set_block_number(
198 frame_system::Pallet::<T>::block_number() + One::one(),
199 );
200 frame_system::Pallet::<T>::on_initialize(frame_system::Pallet::<T>::block_number());
201 SafeMode::<T>::on_initialize(frame_system::Pallet::<T>::block_number());
202
203 #[extrinsic_call]
204 _(force_origin as T::RuntimeOrigin, alice.clone(), block);
205
206 assert!(!Deposits::<T>::contains_key(&alice, block));
207 assert_eq!(<T::Currency as fungible::Inspect<_>>::balance(&alice), init_bal::<T>());
208 Ok(())
209 }
210
211 #[benchmark]
212 fn force_slash_deposit() -> Result<(), BenchmarkError> {
213 let force_origin = T::ForceDepositOrigin::try_successful_origin()
214 .map_err(|_| BenchmarkError::Weightless)?;
215
216 let alice: T::AccountId = whitelisted_caller();
217 <T::Currency as fungible::Mutate<_>>::set_balance(&alice, init_bal::<T>());
218
219 let block: BlockNumberFor<T> = 1u32.into();
221 let bal: BalanceOf<T> = 1u32.into();
222 Deposits::<T>::insert(&alice, &block, &bal);
223 T::Currency::hold(&&HoldReason::EnterOrExtend.into(), &alice, bal)?;
224 EnteredUntil::<T>::put(&block);
225 assert!(SafeMode::<T>::do_exit(ExitReason::Force).is_ok());
226
227 #[extrinsic_call]
228 _(force_origin as T::RuntimeOrigin, alice.clone(), block);
229
230 assert!(!Deposits::<T>::contains_key(&alice, block));
231 assert_eq!(
232 <T::Currency as fungible::Inspect<_>>::balance(&alice),
233 init_bal::<T>() - 1u32.into()
234 );
235 Ok(())
236 }
237
238 fn init_bal<T: Config>() -> BalanceOf<T> {
239 BalanceOf::<T>::max_value() / 10u32.into()
240 }
241
242 impl_benchmark_test_suite!(SafeMode, crate::mock::new_test_ext(), crate::mock::Test);
243}