referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_common/paras_registrar/
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
17//! Benchmarking for paras_registrar pallet
18
19#[cfg(feature = "runtime-benchmarks")]
20use super::{Pallet as Registrar, *};
21use crate::traits::Registrar as RegistrarT;
22use frame_support::assert_ok;
23use frame_system::RawOrigin;
24use polkadot_primitives::{MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MIN_CODE_SIZE};
25use polkadot_runtime_parachains::{paras, shared, Origin as ParaOrigin};
26use sp_runtime::traits::Bounded;
27
28use frame_benchmarking::v2::*;
29
30fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
31	let events = frame_system::Pallet::<T>::events();
32	let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
33	// compare to the last event record
34	let frame_system::EventRecord { event, .. } = &events[events.len() - 1];
35	assert_eq!(event, &system_event);
36}
37
38fn register_para<T: Config>(id: u32) -> ParaId {
39	let para = ParaId::from(id);
40	let genesis_head = Registrar::<T>::worst_head_data();
41	let validation_code = Registrar::<T>::worst_validation_code();
42	let caller: T::AccountId = whitelisted_caller();
43	T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
44	assert_ok!(Registrar::<T>::reserve(RawOrigin::Signed(caller.clone()).into()));
45	assert_ok!(Registrar::<T>::register(
46		RawOrigin::Signed(caller).into(),
47		para,
48		genesis_head,
49		validation_code.clone()
50	));
51	assert_ok!(polkadot_runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
52		frame_system::Origin::<T>::Root.into(),
53		validation_code,
54	));
55	return para;
56}
57
58fn para_origin(id: u32) -> ParaOrigin {
59	ParaOrigin::Parachain(id.into())
60}
61
62// This function moves forward to the next scheduled session for parachain lifecycle upgrades.
63fn next_scheduled_session<T: Config>() {
64	shared::Pallet::<T>::set_session_index(shared::Pallet::<T>::scheduled_session());
65	paras::Pallet::<T>::test_on_new_session();
66}
67
68#[benchmarks(
69		where ParaOrigin: Into<<T as frame_system::Config>::RuntimeOrigin>,
70	)]
71mod benchmarks {
72	use super::*;
73	use alloc::vec;
74
75	#[benchmark]
76	fn reserve() -> Result<(), BenchmarkError> {
77		let caller: T::AccountId = whitelisted_caller();
78		T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
79
80		#[extrinsic_call]
81		_(RawOrigin::Signed(caller.clone()));
82
83		assert_last_event::<T>(
84			Event::<T>::Reserved { para_id: LOWEST_PUBLIC_ID, who: caller }.into(),
85		);
86		assert!(Paras::<T>::get(LOWEST_PUBLIC_ID).is_some());
87		assert_eq!(paras::Pallet::<T>::lifecycle(LOWEST_PUBLIC_ID), None);
88
89		Ok(())
90	}
91
92	#[benchmark]
93	fn register() -> Result<(), BenchmarkError> {
94		let para = LOWEST_PUBLIC_ID;
95		let genesis_head = Registrar::<T>::worst_head_data();
96		let validation_code = Registrar::<T>::worst_validation_code();
97		let caller: T::AccountId = whitelisted_caller();
98		T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
99		assert_ok!(Registrar::<T>::reserve(RawOrigin::Signed(caller.clone()).into()));
100
101		#[extrinsic_call]
102		_(RawOrigin::Signed(caller.clone()), para, genesis_head, validation_code.clone());
103
104		assert_last_event::<T>(Event::<T>::Registered { para_id: para, manager: caller }.into());
105		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
106		assert_ok!(polkadot_runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
107			frame_system::Origin::<T>::Root.into(),
108			validation_code,
109		));
110		next_scheduled_session::<T>();
111		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
112
113		Ok(())
114	}
115
116	#[benchmark]
117	fn force_register() -> Result<(), BenchmarkError> {
118		let manager: T::AccountId = account("manager", 0, 0);
119		let deposit = 0u32.into();
120		let para = ParaId::from(69);
121		let genesis_head = Registrar::<T>::worst_head_data();
122		let validation_code = Registrar::<T>::worst_validation_code();
123
124		#[extrinsic_call]
125		_(RawOrigin::Root, manager.clone(), deposit, para, genesis_head, validation_code.clone());
126
127		assert_last_event::<T>(Event::<T>::Registered { para_id: para, manager }.into());
128		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
129		assert_ok!(polkadot_runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
130			frame_system::Origin::<T>::Root.into(),
131			validation_code,
132		));
133		next_scheduled_session::<T>();
134		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
135
136		Ok(())
137	}
138
139	#[benchmark]
140	fn deregister() -> Result<(), BenchmarkError> {
141		let para = register_para::<T>(LOWEST_PUBLIC_ID.into());
142		next_scheduled_session::<T>();
143		let caller: T::AccountId = whitelisted_caller();
144
145		#[extrinsic_call]
146		_(RawOrigin::Signed(caller), para);
147
148		assert_last_event::<T>(Event::<T>::Deregistered { para_id: para }.into());
149
150		Ok(())
151	}
152
153	#[benchmark]
154	fn swap() -> Result<(), BenchmarkError> {
155		// On demand parachain
156		let parathread = register_para::<T>(LOWEST_PUBLIC_ID.into());
157		let parachain = register_para::<T>((LOWEST_PUBLIC_ID + 1).into());
158
159		let parachain_origin = para_origin(parachain.into());
160
161		// Actually finish registration process
162		next_scheduled_session::<T>();
163
164		// Upgrade the parachain
165		Registrar::<T>::make_parachain(parachain)?;
166		next_scheduled_session::<T>();
167
168		assert_eq!(paras::Pallet::<T>::lifecycle(parachain), Some(ParaLifecycle::Parachain));
169		assert_eq!(paras::Pallet::<T>::lifecycle(parathread), Some(ParaLifecycle::Parathread));
170
171		let caller: T::AccountId = whitelisted_caller();
172		Registrar::<T>::swap(parachain_origin.into(), parachain, parathread)?;
173
174		#[extrinsic_call]
175		_(RawOrigin::Signed(caller.clone()), parathread, parachain);
176
177		next_scheduled_session::<T>();
178		// Swapped!
179		assert_eq!(paras::Pallet::<T>::lifecycle(parachain), Some(ParaLifecycle::Parathread));
180		assert_eq!(paras::Pallet::<T>::lifecycle(parathread), Some(ParaLifecycle::Parachain));
181
182		Ok(())
183	}
184
185	#[benchmark]
186	fn schedule_code_upgrade(
187		b: Linear<MIN_CODE_SIZE, MAX_CODE_SIZE>,
188	) -> Result<(), BenchmarkError> {
189		let new_code = ValidationCode(vec![0; b as usize]);
190		let para_id = ParaId::from(1000);
191
192		#[extrinsic_call]
193		_(RawOrigin::Root, para_id, new_code);
194
195		Ok(())
196	}
197
198	#[benchmark]
199	fn set_current_head(b: Linear<1, MAX_HEAD_DATA_SIZE>) -> Result<(), BenchmarkError> {
200		let new_head = HeadData(vec![0; b as usize]);
201		let para_id = ParaId::from(1000);
202
203		#[extrinsic_call]
204		_(RawOrigin::Root, para_id, new_head);
205
206		Ok(())
207	}
208
209	impl_benchmark_test_suite!(
210		Registrar,
211		crate::integration_tests::new_test_ext(),
212		crate::integration_tests::Test,
213	);
214}