polkadot_runtime_parachains/paras_inherent/
benchmarking.rs1#![cfg(feature = "runtime-benchmarks")]
17
18use super::*;
19use crate::{inclusion, ParaId};
20use alloc::collections::btree_map::BTreeMap;
21use core::cmp::{max, min};
22use frame_benchmarking::v2::*;
23use frame_system::RawOrigin;
24
25use polkadot_primitives::{node_features::FeatureIndex, GroupIndex};
26
27use crate::builder::BenchBuilder;
28
29#[benchmarks]
30mod benchmarks {
31 use super::*;
32
33 #[benchmark]
34 fn enter_empty() -> Result<(), BenchmarkError> {
35 let scenario = BenchBuilder::<T>::new().build();
36
37 let mut benchmark = scenario.data.clone();
38
39 benchmark.bitfields.clear();
40 benchmark.backed_candidates.clear();
41 benchmark.disputes.clear();
42
43 #[extrinsic_call]
44 enter(RawOrigin::None, benchmark);
45
46 assert!(Included::<T>::get().is_some());
48
49 Ok(())
50 }
51
52 #[benchmark]
56 fn enter_variable_disputes(
57 v: Linear<400, { BenchBuilder::<T>::fallback_max_validators() }>,
58 ) -> Result<(), BenchmarkError> {
59 let scenario = BenchBuilder::<T>::new().set_dispute_sessions(&[2]).build();
60
61 let mut benchmark = scenario.data.clone();
62 let dispute = benchmark.disputes.pop().unwrap();
63
64 benchmark.bitfields.clear();
65 benchmark.backed_candidates.clear();
66 benchmark.disputes.clear();
67
68 benchmark.disputes.push(dispute);
69 benchmark.disputes.get_mut(0).unwrap().statements.drain(v as usize..);
70
71 #[extrinsic_call]
72 enter(RawOrigin::None, benchmark);
73
74 assert!(Included::<T>::get().is_some());
76
77 let onchain_votes = OnChainVotes::<T>::get();
79 assert!(onchain_votes.is_some());
80 let vote = onchain_votes.unwrap();
81
82 assert_eq!(vote.session, scenario._session);
84
85 Ok(())
86 }
87
88 #[benchmark]
90 fn enter_bitfields() -> Result<(), BenchmarkError> {
91 let cores_with_backed: BTreeMap<_, _> =
92 vec![(0, BenchBuilder::<T>::fallback_max_validators())].into_iter().collect();
93
94 let scenario = BenchBuilder::<T>::new()
95 .set_backed_and_concluding_paras(cores_with_backed)
96 .build();
97
98 let mut benchmark = scenario.data.clone();
99 let bitfield = benchmark.bitfields.pop().unwrap();
100
101 benchmark.bitfields.clear();
102 benchmark.backed_candidates.clear();
103 benchmark.disputes.clear();
104
105 benchmark.bitfields.push(bitfield);
106
107 #[extrinsic_call]
108 enter(RawOrigin::None, benchmark);
109
110 assert!(Included::<T>::get().is_some());
112 let onchain_votes = OnChainVotes::<T>::get();
114 assert!(onchain_votes.is_some());
115 let vote = onchain_votes.unwrap();
116 assert_eq!(vote.session, scenario._session);
118
119 Ok(())
120 }
121
122 #[benchmark]
125 fn enter_backed_candidates_variable(
126 v: Linear<
127 { BenchBuilder::<T>::fallback_min_backing_votes() },
128 {
129 max(
130 BenchBuilder::<T>::fallback_min_backing_votes() + 1,
131 BenchBuilder::<T>::fallback_max_validators_per_core(),
132 )
133 },
134 >,
135 ) -> Result<(), BenchmarkError> {
136 configuration::Pallet::<T>::set_node_feature(
137 RawOrigin::Root.into(),
138 FeatureIndex::CandidateReceiptV2 as u8,
139 true,
140 )
141 .unwrap();
142 let cores_with_backed: BTreeMap<_, _> = vec![(0, v)] .into_iter()
144 .collect();
145
146 let scenario = BenchBuilder::<T>::new()
147 .set_backed_in_inherent_paras(cores_with_backed.clone())
148 .build();
149
150 let mut benchmark = scenario.data.clone();
151
152 assert_eq!(benchmark.backed_candidates.len(), 1);
154 let votes = min(
156 scheduler::Pallet::<T>::group_validators(GroupIndex::from(0)).unwrap().len(),
157 v as usize,
158 );
159 assert_eq!(benchmark.backed_candidates.get(0).unwrap().validity_votes().len(), votes);
160
161 benchmark.bitfields.clear();
162 benchmark.disputes.clear();
163
164 #[extrinsic_call]
165 enter(RawOrigin::None, benchmark);
166
167 assert!(Included::<T>::get().is_some());
169 let onchain_votes = OnChainVotes::<T>::get();
171 assert!(onchain_votes.is_some());
172 let vote = onchain_votes.unwrap();
173 assert_eq!(vote.session, scenario._session);
175 let header = BenchBuilder::<T>::header(scenario._block_number);
177 for (para_id, backing_validators) in
179 vote.backing_validators_per_candidate.iter().enumerate()
180 {
181 let descriptor = backing_validators.0.descriptor();
182 assert_eq!(ParaId::from(para_id), descriptor.para_id());
183 assert_eq!(header.hash(), descriptor.relay_parent());
184 assert_eq!(backing_validators.1.len(), votes);
185 }
186
187 assert_eq!(inclusion::PendingAvailability::<T>::iter().count(), cores_with_backed.len());
188
189 Ok(())
190 }
191
192 #[benchmark]
193 fn enter_backed_candidate_code_upgrade() -> Result<(), BenchmarkError> {
194 configuration::Pallet::<T>::set_node_feature(
195 RawOrigin::Root.into(),
196 FeatureIndex::CandidateReceiptV2 as u8,
197 true,
198 )
199 .unwrap();
200
201 let v = crate::configuration::ActiveConfig::<T>::get().max_code_size;
203
204 let cores_with_backed: BTreeMap<_, _> =
205 vec![(0, BenchBuilder::<T>::fallback_min_backing_votes())].into_iter().collect();
206
207 let scenario = BenchBuilder::<T>::new()
208 .set_backed_in_inherent_paras(cores_with_backed.clone())
209 .set_code_upgrade(v)
210 .build();
211
212 let mut benchmark = scenario.data.clone();
213
214 let votes = min(
215 scheduler::Pallet::<T>::group_validators(GroupIndex::from(0)).unwrap().len(),
216 BenchBuilder::<T>::fallback_min_backing_votes() as usize,
217 );
218
219 assert_eq!(benchmark.backed_candidates.len(), 1);
221 assert_eq!(benchmark.backed_candidates.get(0).unwrap().validity_votes().len(), votes,);
222
223 benchmark.bitfields.clear();
224 benchmark.disputes.clear();
225 crate::paras::benchmarking::generate_disordered_upgrades::<T>();
226
227 #[extrinsic_call]
228 enter(RawOrigin::None, benchmark);
229
230 assert!(Included::<T>::get().is_some());
232 let onchain_votes = OnChainVotes::<T>::get();
234 assert!(onchain_votes.is_some());
235 let vote = onchain_votes.unwrap();
236 assert_eq!(vote.session, scenario._session);
238 let header = BenchBuilder::<T>::header(scenario._block_number);
240 for (para_id, backing_validators) in
242 vote.backing_validators_per_candidate.iter().enumerate()
243 {
244 let descriptor = backing_validators.0.descriptor();
245 assert_eq!(ParaId::from(para_id), descriptor.para_id());
246 assert_eq!(header.hash(), descriptor.relay_parent());
247 assert_eq!(backing_validators.1.len(), votes,);
248 }
249
250 assert_eq!(inclusion::PendingAvailability::<T>::iter().count(), cores_with_backed.len());
251 Ok(())
252 }
253
254 impl_benchmark_test_suite! {
255 Pallet,
256 crate::mock::new_test_ext(Default::default()),
257 crate::mock::Test
258 }
259}