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
74	#[benchmark]
75	fn reserve() -> Result<(), BenchmarkError> {
76		let caller: T::AccountId = whitelisted_caller();
77		T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
78
79		#[extrinsic_call]
80		_(RawOrigin::Signed(caller.clone()));
81
82		assert_last_event::<T>(
83			Event::<T>::Reserved { para_id: LOWEST_PUBLIC_ID, who: caller }.into(),
84		);
85		assert!(Paras::<T>::get(LOWEST_PUBLIC_ID).is_some());
86		assert_eq!(paras::Pallet::<T>::lifecycle(LOWEST_PUBLIC_ID), None);
87
88		Ok(())
89	}
90
91	#[benchmark]
92	fn register() -> Result<(), BenchmarkError> {
93		let para = LOWEST_PUBLIC_ID;
94		let genesis_head = Registrar::<T>::worst_head_data();
95		let validation_code = Registrar::<T>::worst_validation_code();
96		let caller: T::AccountId = whitelisted_caller();
97		T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
98		assert_ok!(Registrar::<T>::reserve(RawOrigin::Signed(caller.clone()).into()));
99
100		#[extrinsic_call]
101		_(RawOrigin::Signed(caller.clone()), para, genesis_head, validation_code.clone());
102
103		assert_last_event::<T>(Event::<T>::Registered { para_id: para, manager: caller }.into());
104		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
105		assert_ok!(polkadot_runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
106			frame_system::Origin::<T>::Root.into(),
107			validation_code,
108		));
109		next_scheduled_session::<T>();
110		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
111
112		Ok(())
113	}
114
115	#[benchmark]
116	fn force_register() -> Result<(), BenchmarkError> {
117		let manager: T::AccountId = account("manager", 0, 0);
118		let deposit = 0u32.into();
119		let para = ParaId::from(69);
120		let genesis_head = Registrar::<T>::worst_head_data();
121		let validation_code = Registrar::<T>::worst_validation_code();
122
123		#[extrinsic_call]
124		_(RawOrigin::Root, manager.clone(), deposit, para, genesis_head, validation_code.clone());
125
126		assert_last_event::<T>(Event::<T>::Registered { para_id: para, manager }.into());
127		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
128		assert_ok!(polkadot_runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
129			frame_system::Origin::<T>::Root.into(),
130			validation_code,
131		));
132		next_scheduled_session::<T>();
133		assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
134
135		Ok(())
136	}
137
138	#[benchmark]
139	fn deregister() -> Result<(), BenchmarkError> {
140		let para = register_para::<T>(LOWEST_PUBLIC_ID.into());
141		next_scheduled_session::<T>();
142		let caller: T::AccountId = whitelisted_caller();
143
144		#[extrinsic_call]
145		_(RawOrigin::Signed(caller), para);
146
147		assert_last_event::<T>(Event::<T>::Deregistered { para_id: para }.into());
148
149		Ok(())
150	}
151
152	#[benchmark]
153	fn swap() -> Result<(), BenchmarkError> {
154		// On demand parachain
155		let parathread = register_para::<T>(LOWEST_PUBLIC_ID.into());
156		let parachain = register_para::<T>((LOWEST_PUBLIC_ID + 1).into());
157
158		let parachain_origin = para_origin(parachain.into());
159
160		// Actually finish registration process
161		next_scheduled_session::<T>();
162
163		// Upgrade the parachain
164		Registrar::<T>::make_parachain(parachain)?;
165		next_scheduled_session::<T>();
166
167		assert_eq!(paras::Pallet::<T>::lifecycle(parachain), Some(ParaLifecycle::Parachain));
168		assert_eq!(paras::Pallet::<T>::lifecycle(parathread), Some(ParaLifecycle::Parathread));
169
170		let caller: T::AccountId = whitelisted_caller();
171		Registrar::<T>::swap(parachain_origin.into(), parachain, parathread)?;
172
173		#[extrinsic_call]
174		_(RawOrigin::Signed(caller.clone()), parathread, parachain);
175
176		next_scheduled_session::<T>();
177		// Swapped!
178		assert_eq!(paras::Pallet::<T>::lifecycle(parachain), Some(ParaLifecycle::Parathread));
179		assert_eq!(paras::Pallet::<T>::lifecycle(parathread), Some(ParaLifecycle::Parachain));
180
181		Ok(())
182	}
183
184	#[benchmark]
185	fn schedule_code_upgrade(
186		b: Linear<MIN_CODE_SIZE, MAX_CODE_SIZE>,
187	) -> Result<(), BenchmarkError> {
188		let new_code = ValidationCode(vec![0; b as usize]);
189		let para_id = ParaId::from(1000);
190
191		#[extrinsic_call]
192		_(RawOrigin::Root, para_id, new_code);
193
194		Ok(())
195	}
196
197	#[benchmark]
198	fn set_current_head(b: Linear<1, MAX_HEAD_DATA_SIZE>) -> Result<(), BenchmarkError> {
199		let new_head = HeadData(vec![0; b as usize]);
200		let para_id = ParaId::from(1000);
201
202		#[extrinsic_call]
203		_(RawOrigin::Root, para_id, new_head);
204
205		Ok(())
206	}
207
208	impl_benchmark_test_suite!(
209		Registrar,
210		crate::integration_tests::new_test_ext(),
211		crate::integration_tests::Test,
212	);
213}