cumulus_pallet_parachain_system/
benchmarking.rs1#![cfg(feature = "runtime-benchmarks")]
21
22use super::*;
23use crate::{
24 block_weight::{
25 BlockWeightMode, DynamicMaxBlockWeight, MaxParachainBlockWeight, FULL_CORE_WEIGHT,
26 },
27 parachain_inherent::InboundDownwardMessages,
28};
29use cumulus_primitives_core::{
30 relay_chain::Hash as RelayHash, BlockBundleInfo, CoreInfo, InboundDownwardMessage,
31};
32use frame_benchmarking::v2::*;
33use frame_support::{
34 dispatch::{DispatchInfo, PostDispatchInfo},
35 weights::constants::WEIGHT_REF_TIME_PER_SECOND,
36};
37use frame_system::RawOrigin;
38use sp_core::ConstU32;
39use sp_runtime::traits::{BlakeTwo256, DispatchTransaction, Dispatchable};
40
41fn has_use_full_core_digest<T: Config>() -> bool {
42 let digest = frame_system::Pallet::<T>::digest();
43 CumulusDigestItem::contains_use_full_core(&digest)
44}
45
46#[benchmarks(where
47 T: Send + Sync,
48 T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
49)]
50mod benchmarks {
51 use super::*;
52
53 #[benchmark]
58 fn enqueue_inbound_downward_messages(n: Linear<0, 1000>) {
59 let msg = InboundDownwardMessage {
60 sent_at: n, msg: vec![0u8; MaxDmpMessageLenOf::<T>::get() as usize],
62 };
63 let msgs = vec![msg; n as usize];
64 let head = mqp_head(&msgs);
65
66 #[block]
67 {
68 Pallet::<T>::enqueue_inbound_downward_messages(
69 head,
70 InboundDownwardMessages::new(msgs).into_abridged(&mut usize::MAX.clone()),
71 );
72 }
73
74 assert_eq!(ProcessedDownwardMessages::<T>::get(), n);
75 assert_eq!(LastDmqMqcHead::<T>::get().head(), head);
76 }
77
78 fn mqp_head(msgs: &Vec<InboundDownwardMessage>) -> RelayHash {
80 let mut head = Default::default();
81 for msg in msgs.iter() {
82 let msg_hash = BlakeTwo256::hash_of(&msg.msg);
83 head = BlakeTwo256::hash_of(&(head, msg.sent_at, msg_hash));
84 }
85 head
86 }
87
88 #[benchmark]
93 fn block_weight_tx_extension_max_weight() -> Result<(), BenchmarkError> {
94 let caller = account("caller", 0, 0);
95
96 frame_system::Pallet::<T>::note_inherents_applied();
97
98 frame_system::Pallet::<T>::set_extrinsic_index(1);
99
100 frame_system::Pallet::<T>::deposit_log(
101 BlockBundleInfo { index: 0, is_last: false }.to_digest_item(),
102 );
103 frame_system::Pallet::<T>::deposit_log(
104 CoreInfo {
105 selector: 0.into(),
106 claim_queue_offset: 0.into(),
107 number_of_cores: 1.into(),
108 }
109 .to_digest_item(),
110 );
111 let target_weight = MaxParachainBlockWeight::<T, ConstU32<4>>::target_block_weight();
112
113 let info = DispatchInfo {
114 call_weight: target_weight
116 .saturating_add(Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND, 0)),
117 extension_weight: Weight::zero(),
118 class: DispatchClass::Normal,
119 ..Default::default()
120 };
121 let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
122 let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Default::default() };
123 let len = 0_usize;
124
125 crate::BlockWeightMode::<T>::put(BlockWeightMode::fraction_of_core(None));
126
127 let ext = DynamicMaxBlockWeight::<T, (), ConstU32<4>>::new(());
128
129 #[block]
130 {
131 ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, 0, |_| {
132 frame_system::Pallet::<T>::register_extra_weight_unchecked(
134 info.call_weight,
135 DispatchClass::Normal,
136 );
137 Ok(post_info)
138 })
139 .unwrap()
140 .unwrap();
141 }
142
143 assert_eq!(crate::BlockWeightMode::<T>::get().unwrap(), BlockWeightMode::full_core());
144 assert!(has_use_full_core_digest::<T>());
145 assert_eq!(MaxParachainBlockWeight::<T, ConstU32<4>>::get(), FULL_CORE_WEIGHT);
146
147 Ok(())
148 }
149
150 #[benchmark]
152 fn block_weight_tx_extension_stays_fraction_of_core() -> Result<(), BenchmarkError> {
153 let caller = account("caller", 0, 0);
154
155 frame_system::Pallet::<T>::note_inherents_applied();
156
157 frame_system::Pallet::<T>::set_extrinsic_index(1);
158
159 frame_system::Pallet::<T>::deposit_log(
160 BlockBundleInfo { index: 0, is_last: false }.to_digest_item(),
161 );
162 frame_system::Pallet::<T>::deposit_log(
163 CoreInfo {
164 selector: 0.into(),
165 claim_queue_offset: 0.into(),
166 number_of_cores: 1.into(),
167 }
168 .to_digest_item(),
169 );
170 let target_weight = MaxParachainBlockWeight::<T, ConstU32<4>>::target_block_weight();
171
172 let info = DispatchInfo {
173 call_weight: Weight::from_parts(1024, 1024),
174 extension_weight: Weight::zero(),
175 class: DispatchClass::Normal,
176 ..Default::default()
177 };
178 let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
179 let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Default::default() };
180 let len = 0_usize;
181
182 crate::BlockWeightMode::<T>::put(BlockWeightMode::fraction_of_core(None));
183
184 let ext = DynamicMaxBlockWeight::<T, (), ConstU32<4>>::new(());
185
186 #[block]
187 {
188 ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, 0, |_| {
189 frame_system::Pallet::<T>::register_extra_weight_unchecked(
191 info.call_weight,
192 DispatchClass::Normal,
193 );
194 Ok(post_info)
195 })
196 .unwrap()
197 .unwrap();
198 }
199
200 assert_eq!(
201 crate::BlockWeightMode::<T>::get().unwrap(),
202 BlockWeightMode::fraction_of_core(Some(1))
203 );
204 assert!(!has_use_full_core_digest::<T>());
205 assert_eq!(MaxParachainBlockWeight::<T, ConstU32<4>>::get(), target_weight);
206
207 Ok(())
208 }
209
210 #[benchmark]
212 fn block_weight_tx_extension_full_core() -> Result<(), BenchmarkError> {
213 let caller = account("caller", 0, 0);
214
215 frame_system::Pallet::<T>::set_block_number(1u32.into());
216
217 frame_system::Pallet::<T>::note_inherents_applied();
218
219 frame_system::Pallet::<T>::set_extrinsic_index(1);
220
221 frame_system::Pallet::<T>::deposit_log(
222 BlockBundleInfo { index: 0, is_last: false }.to_digest_item(),
223 );
224 frame_system::Pallet::<T>::deposit_log(
225 CoreInfo {
226 selector: 0.into(),
227 claim_queue_offset: 0.into(),
228 number_of_cores: 1.into(),
229 }
230 .to_digest_item(),
231 );
232
233 let info = DispatchInfo {
234 call_weight: Weight::from_parts(1024, 1024),
235 extension_weight: Weight::zero(),
236 class: DispatchClass::Normal,
237 ..Default::default()
238 };
239 let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
240 let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Default::default() };
241 let len = 0_usize;
242
243 crate::BlockWeightMode::<T>::put(BlockWeightMode::full_core());
244
245 let ext = DynamicMaxBlockWeight::<T, (), ConstU32<4>>::new(());
246
247 #[block]
248 {
249 ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, 0, |_| {
250 frame_system::Pallet::<T>::register_extra_weight_unchecked(
252 info.call_weight,
253 DispatchClass::Normal,
254 );
255 Ok(post_info)
256 })
257 .unwrap()
258 .unwrap();
259 }
260
261 assert_eq!(crate::BlockWeightMode::<T>::get().unwrap(), BlockWeightMode::full_core());
262
263 Ok(())
264 }
265
266 impl_benchmark_test_suite! {
267 Pallet,
268 crate::mock::new_test_ext(),
269 crate::mock::Test
270 }
271}