pallet_whitelist/
benchmarking.rs1#![cfg(feature = "runtime-benchmarks")]
21
22use super::*;
23#[cfg(test)]
24use crate::Pallet as Whitelist;
25use frame::{benchmarking::prelude::*, traits::Authorize};
26
27#[benchmarks(where <T as frame_system::Config>::RuntimeCall: From<Call<T>>)]
28mod benchmarks {
29 use super::*;
30
31 #[benchmark]
32 fn whitelist_call() -> Result<(), BenchmarkError> {
33 let origin =
34 T::WhitelistOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
35 let call_hash = Default::default();
36
37 #[extrinsic_call]
38 _(origin as T::RuntimeOrigin, call_hash);
39
40 ensure!(WhitelistedCall::<T>::contains_key(call_hash), "call not whitelisted");
41 ensure!(T::Preimages::is_requested(&call_hash), "preimage not requested");
42 Ok(())
43 }
44
45 #[benchmark]
46 fn remove_whitelisted_call() -> Result<(), BenchmarkError> {
47 let origin =
48 T::WhitelistOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
49 let call_hash = Default::default();
50 Pallet::<T>::whitelist_call(origin.clone(), call_hash)
51 .expect("whitelisting call must be successful");
52
53 #[extrinsic_call]
54 _(origin as T::RuntimeOrigin, call_hash);
55
56 ensure!(!WhitelistedCall::<T>::contains_key(call_hash), "whitelist not removed");
57 ensure!(!T::Preimages::is_requested(&call_hash), "preimage still requested");
58 Ok(())
59 }
60
61 #[benchmark]
65 fn defer_dispatch(n: Linear<1, 10_000>) -> Result<(), BenchmarkError> {
66 let origin = T::DispatchWhitelistedOrigin::try_successful_origin()
67 .map_err(|_| BenchmarkError::Weightless)?;
68 let remark = alloc::vec![1u8; n as usize];
69 let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark }.into();
70 let call_hash = T::Hashing::hash_of(&call);
71
72 #[extrinsic_call]
73 dispatch_whitelisted_call_with_preimage(origin as T::RuntimeOrigin, Box::new(call));
74
75 ensure!(DeferredDispatch::<T>::contains_key(call_hash), "dispatch not deferred");
76 Ok(())
77 }
78
79 #[benchmark]
80 fn remove_deferred_dispatch() -> Result<(), BenchmarkError> {
81 let caller: T::AccountId = whitelisted_caller();
82 let call: <T as Config>::RuntimeCall =
83 frame_system::Call::remark { remark: alloc::vec![] }.into();
84 let call_hash = T::Hashing::hash_of(&call);
85
86 let now = T::BlockNumberProvider::current_block_number();
88 DeferredDispatch::<T>::insert(call_hash, now);
89
90 #[extrinsic_call]
91 _(frame_system::RawOrigin::Signed(caller), call_hash);
92
93 ensure!(!DeferredDispatch::<T>::contains_key(call_hash), "deferred entry not removed");
94 Ok(())
95 }
96
97 #[benchmark(pov_mode = Measured {
107 Whitelist: MaxEncodedLen,
108 Preimage: MaxEncodedLen,
109 Preimage::PreimageFor: Measured
111 })]
112 fn dispatch_whitelisted_call(
114 n: Linear<1, { T::Preimages::MAX_LENGTH as u32 - 10 }>,
115 ) -> Result<(), BenchmarkError> {
116 let whitelist_origin = T::DispatchWhitelistedOrigin::try_successful_origin()
117 .map_err(|_| BenchmarkError::Weightless)?;
118 let caller: T::AccountId = whitelisted_caller();
119 let remark = alloc::vec![1u8; n as usize];
120 let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark }.into();
121 let call_weight = call.get_dispatch_info().call_weight;
122 let encoded_call = call.encode();
123 let call_encoded_len = encoded_call.len() as u32;
124 let call_hash = T::Hashing::hash_of(&call);
125
126 Pallet::<T>::defer_dispatch(call_hash).expect("deferring dispatch must be successful");
127 Pallet::<T>::whitelist_call(whitelist_origin, call_hash)
128 .expect("whitelisting call must be successful");
129 T::Preimages::note(encoded_call.into()).unwrap();
130
131 #[extrinsic_call]
132 _(frame_system::RawOrigin::Signed(caller), call_hash, call_encoded_len, call_weight);
133
134 ensure!(!WhitelistedCall::<T>::contains_key(call_hash), "whitelist not removed");
135 ensure!(!DeferredDispatch::<T>::contains_key(call_hash), "deferred entry not removed");
136 ensure!(!T::Preimages::is_requested(&call_hash), "preimage still requested");
137 Ok(())
138 }
139
140 #[benchmark]
141 fn dispatch_whitelisted_call_with_preimage(n: Linear<1, 10_000>) -> Result<(), BenchmarkError> {
142 let whitelist_origin = T::DispatchWhitelistedOrigin::try_successful_origin()
143 .map_err(|_| BenchmarkError::Weightless)?;
144 let caller: T::AccountId = whitelisted_caller();
145 let remark = alloc::vec![1u8; n as usize];
146
147 let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark }.into();
148 let call_hash = T::Hashing::hash_of(&call);
149
150 Pallet::<T>::defer_dispatch(call_hash).expect("deferring dispatch must be successful");
151 Pallet::<T>::whitelist_call(whitelist_origin, call_hash)
152 .expect("whitelisting call must be successful");
153
154 #[extrinsic_call]
155 _(frame_system::RawOrigin::Signed(caller), Box::new(call));
156
157 ensure!(!WhitelistedCall::<T>::contains_key(call_hash), "whitelist not removed");
158 ensure!(!DeferredDispatch::<T>::contains_key(call_hash), "deferred entry not removed");
159 ensure!(!T::Preimages::is_requested(&call_hash), "preimage still requested");
160 Ok(())
161 }
162
163 #[benchmark(pov_mode = Measured {
166 Whitelist: MaxEncodedLen,
167 Preimage: MaxEncodedLen,
168 Preimage::PreimageFor: Measured
170 })]
171 fn authorize_dispatch_whitelisted_call(
173 n: Linear<1, { T::Preimages::MAX_LENGTH as u32 - 10 }>,
174 ) -> Result<(), BenchmarkError> {
175 let authorized: T::RuntimeOrigin =
177 frame_system::RawOrigin::<T::AccountId>::Authorized.into();
178 if T::DispatchWhitelistedOrigin::try_origin(authorized).is_err() {
179 return Err(BenchmarkError::Weightless);
180 }
181
182 let whitelist_origin =
183 T::WhitelistOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
184 let remark = alloc::vec![1u8; n as usize];
185 let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark }.into();
186 let call_weight_witness = call.get_dispatch_info().call_weight;
187 let encoded_call = call.encode();
188 let call_encoded_len = encoded_call.len() as u32;
189 let call_hash = T::Hashing::hash_of(&call);
190
191 Pallet::<T>::whitelist_call(whitelist_origin, call_hash)
192 .expect("whitelisting call must be successful");
193 T::Preimages::note(encoded_call.into()).unwrap();
194
195 let call: <T as frame_system::Config>::RuntimeCall = Call::<T>::dispatch_whitelisted_call {
196 call_hash,
197 call_encoded_len,
198 call_weight_witness,
199 }
200 .into();
201
202 #[block]
203 {
204 let result = call
205 .authorize(TransactionSource::InBlock)
206 .expect("dispatch_whitelisted_call declares an authorize callback; qed");
207 assert!(result.is_ok());
208 }
209
210 Ok(())
211 }
212
213 #[benchmark]
216 fn authorize_dispatch_whitelisted_call_with_preimage(
217 n: Linear<1, { *T::BlockLength::get().max.get(DispatchClass::Normal) - 10 }>,
218 ) -> Result<(), BenchmarkError> {
219 let authorized: T::RuntimeOrigin =
221 frame_system::RawOrigin::<T::AccountId>::Authorized.into();
222 if T::DispatchWhitelistedOrigin::try_origin(authorized).is_err() {
223 return Err(BenchmarkError::Weightless);
224 }
225
226 let whitelist_origin =
227 T::WhitelistOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
228 let remark = alloc::vec![1u8; n as usize];
229 let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark }.into();
230 let call_hash = T::Hashing::hash_of(&call);
231
232 Pallet::<T>::whitelist_call(whitelist_origin, call_hash)
233 .expect("whitelisting call must be successful");
234
235 let call: <T as frame_system::Config>::RuntimeCall =
236 Call::<T>::dispatch_whitelisted_call_with_preimage { call: Box::new(call) }.into();
237
238 #[block]
239 {
240 let result = call.authorize(TransactionSource::InBlock).expect(
241 "dispatch_whitelisted_call_with_preimage declares an authorize callback; qed",
242 );
243 assert!(result.is_ok());
244 }
245
246 Ok(())
247 }
248
249 impl_benchmark_test_suite!(Whitelist, crate::mock::new_test_ext(), crate::mock::Test);
250}