referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_parachains/inclusion/
benchmarking.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17use bitvec::{bitvec, prelude::Lsb0};
18use frame_benchmarking::v2::*;
19use pallet_message_queue as mq;
20use polkadot_primitives::{
21	CandidateCommitments, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, HrmpChannelId,
22	OutboundHrmpMessage, SessionIndex,
23};
24
25use super::*;
26use crate::{
27	builder::generate_validator_pairs,
28	configuration,
29	hrmp::{HrmpChannel, HrmpChannels},
30	initializer, HeadData, ValidationCode,
31};
32
33fn create_candidate_commitments<T: crate::hrmp::pallet::Config>(
34	para_id: ParaId,
35	head_data: HeadData,
36	max_msg_len: usize,
37	ump_msg_count: u32,
38	hrmp_msg_count: u32,
39	code_upgrade: bool,
40) -> CandidateCommitments {
41	let upward_messages = {
42		let unbounded = create_messages(max_msg_len, ump_msg_count as _);
43		BoundedVec::truncate_from(unbounded)
44	};
45
46	let horizontal_messages = {
47		let unbounded = create_messages(max_msg_len, hrmp_msg_count as _);
48
49		for n in 0..unbounded.len() {
50			let channel_id = HrmpChannelId { sender: para_id, recipient: para_id + n as u32 + 1 };
51			HrmpChannels::<T>::insert(
52				&channel_id,
53				HrmpChannel {
54					sender_deposit: 42,
55					recipient_deposit: 42,
56					max_capacity: 10_000_000,
57					max_total_size: 1_000_000_000,
58					max_message_size: 10_000_000,
59					msg_count: 0,
60					total_size: 0,
61					mqc_head: None,
62				},
63			);
64		}
65
66		let unbounded = unbounded
67			.into_iter()
68			.enumerate()
69			.map(|(n, data)| OutboundHrmpMessage { recipient: para_id + n as u32 + 1, data })
70			.collect();
71		BoundedVec::truncate_from(unbounded)
72	};
73
74	let new_validation_code = code_upgrade.then_some(ValidationCode(vec![42_u8; 1024]));
75
76	CandidateCommitments::<u32> {
77		upward_messages,
78		horizontal_messages,
79		new_validation_code,
80		head_data,
81		processed_downward_messages: 0,
82		hrmp_watermark: 10,
83	}
84}
85
86fn create_messages(msg_len: usize, n_msgs: usize) -> Vec<Vec<u8>> {
87	let best_number = 73_u8; // Chuck Norris of numbers
88	vec![vec![best_number; msg_len]; n_msgs]
89}
90
91#[benchmarks(where T: mq::Config + configuration::Config + initializer::Config)]
92mod benchmarks {
93	use super::*;
94
95	#[benchmark]
96	fn enact_candidate(u: Linear<0, 2>, h: Linear<0, 2>, c: Linear<0, 1>) {
97		let para = 42_u32.into(); // not especially important.
98
99		let max_len = mq::MaxMessageLenOf::<T>::get() as usize;
100
101		let config = configuration::ActiveConfig::<T>::get();
102		let n_validators = config.max_validators.unwrap_or(500);
103		let validators = generate_validator_pairs::<T>(n_validators);
104
105		let session = SessionIndex::from(0_u32);
106		initializer::Pallet::<T>::test_trigger_on_new_session(
107			false,
108			session,
109			validators.iter().map(|(a, v)| (a, v.clone())),
110			None,
111		);
112		let backing_group_size = config.scheduler_params.max_validators_per_core.unwrap_or(5);
113		let head_data = HeadData(vec![0xFF; 1024]);
114
115		let relay_parent_number = BlockNumberFor::<T>::from(10_u32);
116		let commitments = create_candidate_commitments::<T>(para, head_data, max_len, u, h, c != 0);
117		let backers = bitvec![u8, Lsb0; 1; backing_group_size as usize];
118		let availability_votes = bitvec![u8, Lsb0; 1; n_validators as usize];
119		let core_index = CoreIndex::from(0);
120		let backing_group = GroupIndex::from(0);
121
122		let descriptor = CandidateDescriptor::<T::Hash>::new(
123			para,
124			Default::default(),
125			CoreIndex(0),
126			1,
127			Default::default(),
128			Default::default(),
129			Default::default(),
130			Default::default(),
131			ValidationCode(vec![1, 2, 3]).hash(),
132		);
133
134		let receipt = CommittedCandidateReceipt::<T::Hash> { descriptor, commitments };
135
136		Pallet::<T>::receive_upward_messages(para, &vec![vec![0; max_len]; 1]);
137
138		#[block]
139		{
140			Pallet::<T>::enact_candidate(
141				relay_parent_number,
142				receipt,
143				backers,
144				availability_votes,
145				core_index,
146				backing_group,
147			);
148		}
149	}
150
151	impl_benchmark_test_suite! {
152		Pallet,
153		crate::mock::new_test_ext(Default::default()),
154		crate::mock::Test
155	}
156}