referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_parachains/configuration/migration/
v13.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//! A module that is responsible for migration of storage for the configuration pallet.
18//! v12 -> v13:
19//! - Added `max_relay_parent_session_age` field to configuration
20//! - Removed `ttl` and `max_availability_timeouts` from `SchedulerParams`.
21
22use crate::configuration::{self, Config, Pallet};
23use alloc::vec::Vec;
24use frame_support::{
25	migrations::VersionedMigration,
26	pallet_prelude::*,
27	traits::{Defensive, UncheckedOnRuntimeUpgrade},
28};
29use frame_system::pallet_prelude::BlockNumberFor;
30use polkadot_core_primitives::Balance;
31use polkadot_primitives::vstaging::SchedulerParams;
32use sp_core::Get;
33use sp_staking::SessionIndex;
34
35type V13HostConfiguration<BlockNumber> = configuration::HostConfiguration<BlockNumber>;
36
37/// The v12 `SchedulerParams`, before the `max_relay_parent_session_age` field was added.
38/// This is identical to `polkadot_primitives::v9::SchedulerParams`.
39pub type V12SchedulerParams<BlockNumber> = polkadot_primitives::v9::SchedulerParams<BlockNumber>;
40
41/// The v12 `HostConfiguration`, before the `max_relay_parent_session_age` field was added to
42/// `SchedulerParams`.
43#[derive(Encode, Decode, Debug, Clone)]
44pub struct V12HostConfiguration<BlockNumber> {
45	pub max_code_size: u32,
46	pub max_head_data_size: u32,
47	pub max_upward_queue_count: u32,
48	pub max_upward_queue_size: u32,
49	pub max_upward_message_size: u32,
50	pub max_upward_message_num_per_candidate: u32,
51	pub hrmp_max_message_num_per_candidate: u32,
52	pub validation_upgrade_cooldown: BlockNumber,
53	pub validation_upgrade_delay: BlockNumber,
54	pub async_backing_params: polkadot_primitives::AsyncBackingParams,
55	pub max_pov_size: u32,
56	pub max_downward_message_size: u32,
57	pub hrmp_max_parachain_outbound_channels: u32,
58	pub hrmp_sender_deposit: Balance,
59	pub hrmp_recipient_deposit: Balance,
60	pub hrmp_channel_max_capacity: u32,
61	pub hrmp_channel_max_total_size: u32,
62	pub hrmp_max_parachain_inbound_channels: u32,
63	pub hrmp_channel_max_message_size: u32,
64	pub executor_params: polkadot_primitives::ExecutorParams,
65	pub code_retention_period: BlockNumber,
66	pub max_validators: Option<u32>,
67	pub dispute_period: SessionIndex,
68	pub dispute_post_conclusion_acceptance_period: BlockNumber,
69	pub no_show_slots: u32,
70	pub n_delay_tranches: u32,
71	pub zeroth_delay_tranche_width: u32,
72	pub needed_approvals: u32,
73	pub relay_vrf_modulo_samples: u32,
74	pub pvf_voting_ttl: SessionIndex,
75	pub minimum_validation_upgrade_delay: BlockNumber,
76	pub minimum_backing_votes: u32,
77	pub node_features: polkadot_primitives::NodeFeatures,
78	pub approval_voting_params: polkadot_primitives::ApprovalVotingParams,
79	pub scheduler_params: V12SchedulerParams<BlockNumber>,
80}
81
82impl<BlockNumber: Default + From<u32>> Default for V12HostConfiguration<BlockNumber> {
83	fn default() -> Self {
84		Self {
85			async_backing_params: polkadot_primitives::AsyncBackingParams {
86				max_candidate_depth: 0,
87				allowed_ancestry_len: 0,
88			},
89			no_show_slots: 1u32.into(),
90			validation_upgrade_cooldown: Default::default(),
91			validation_upgrade_delay: 2u32.into(),
92			code_retention_period: Default::default(),
93			max_code_size: polkadot_primitives::MAX_CODE_SIZE,
94			max_pov_size: Default::default(),
95			max_head_data_size: Default::default(),
96			max_validators: None,
97			dispute_period: 6,
98			dispute_post_conclusion_acceptance_period: 100.into(),
99			n_delay_tranches: 1,
100			zeroth_delay_tranche_width: Default::default(),
101			needed_approvals: Default::default(),
102			relay_vrf_modulo_samples: Default::default(),
103			max_upward_queue_count: Default::default(),
104			max_upward_queue_size: Default::default(),
105			max_downward_message_size: Default::default(),
106			max_upward_message_size: Default::default(),
107			max_upward_message_num_per_candidate: Default::default(),
108			hrmp_sender_deposit: Default::default(),
109			hrmp_recipient_deposit: Default::default(),
110			hrmp_channel_max_capacity: Default::default(),
111			hrmp_channel_max_total_size: Default::default(),
112			hrmp_max_parachain_inbound_channels: Default::default(),
113			hrmp_channel_max_message_size: Default::default(),
114			hrmp_max_parachain_outbound_channels: Default::default(),
115			hrmp_max_message_num_per_candidate: Default::default(),
116			pvf_voting_ttl: 2u32.into(),
117			minimum_validation_upgrade_delay: 2.into(),
118			executor_params: Default::default(),
119			approval_voting_params: polkadot_primitives::ApprovalVotingParams {
120				max_approval_coalesce_count: 1,
121			},
122			minimum_backing_votes: polkadot_primitives::LEGACY_MIN_BACKING_VOTES,
123			node_features: Default::default(),
124			scheduler_params: Default::default(),
125		}
126	}
127}
128
129mod v12 {
130	use super::*;
131
132	#[frame_support::storage_alias]
133	pub(crate) type ActiveConfig<T: Config> =
134		StorageValue<Pallet<T>, V12HostConfiguration<BlockNumberFor<T>>, OptionQuery>;
135
136	#[frame_support::storage_alias]
137	pub(crate) type PendingConfigs<T: Config> = StorageValue<
138		Pallet<T>,
139		Vec<(SessionIndex, V12HostConfiguration<BlockNumberFor<T>>)>,
140		OptionQuery,
141	>;
142}
143
144mod v13 {
145	use super::*;
146
147	#[frame_support::storage_alias]
148	pub(crate) type ActiveConfig<T: Config> =
149		StorageValue<Pallet<T>, V13HostConfiguration<BlockNumberFor<T>>, OptionQuery>;
150
151	#[frame_support::storage_alias]
152	pub(crate) type PendingConfigs<T: Config> = StorageValue<
153		Pallet<T>,
154		Vec<(SessionIndex, V13HostConfiguration<BlockNumberFor<T>>)>,
155		OptionQuery,
156	>;
157}
158
159pub type MigrateToV13<T> = VersionedMigration<
160	12,
161	13,
162	UncheckedMigrateToV13<T>,
163	Pallet<T>,
164	<T as frame_system::Config>::DbWeight,
165>;
166
167pub struct UncheckedMigrateToV13<T>(core::marker::PhantomData<T>);
168
169impl<T: Config> UncheckedOnRuntimeUpgrade for UncheckedMigrateToV13<T> {
170	#[cfg(feature = "try-runtime")]
171	fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
172		log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade() for HostConfiguration MigrateToV13");
173		Ok(Vec::new())
174	}
175
176	fn on_runtime_upgrade() -> Weight {
177		log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV13 started");
178		let weight_consumed = migrate_to_v13::<T>();
179
180		log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV13 executed successfully");
181
182		weight_consumed
183	}
184
185	#[cfg(feature = "try-runtime")]
186	fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
187		log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade() for HostConfiguration MigrateToV13");
188		ensure!(
189			StorageVersion::get::<Pallet<T>>() >= 13,
190			"Storage version should be >= 13 after the migration"
191		);
192
193		Ok(())
194	}
195}
196
197fn migrate_to_v13<T: Config>() -> Weight {
198	// Unusual formatting is justified:
199	// - make it easier to verify that fields assign what they supposed to assign.
200	// - this code is transient and will be removed after all migrations are done.
201	// - this code is important enough to optimize for legibility sacrificing consistency.
202	#[rustfmt::skip]
203		let translate =
204		|pre: V12HostConfiguration<BlockNumberFor<T>>| ->
205		V13HostConfiguration<BlockNumberFor<T>>
206			{
207				V13HostConfiguration {
208					max_code_size                            : pre.max_code_size,
209					max_head_data_size                       : pre.max_head_data_size,
210					max_upward_queue_count                   : pre.max_upward_queue_count,
211					max_upward_queue_size                    : pre.max_upward_queue_size,
212					max_upward_message_size                  : pre.max_upward_message_size,
213					max_upward_message_num_per_candidate     : pre.max_upward_message_num_per_candidate,
214					hrmp_max_message_num_per_candidate       : pre.hrmp_max_message_num_per_candidate,
215					validation_upgrade_cooldown              : pre.validation_upgrade_cooldown,
216					validation_upgrade_delay                 : pre.validation_upgrade_delay,
217					max_pov_size                             : pre.max_pov_size,
218					max_downward_message_size                : pre.max_downward_message_size,
219					hrmp_sender_deposit                      : pre.hrmp_sender_deposit,
220					hrmp_recipient_deposit                   : pre.hrmp_recipient_deposit,
221					hrmp_channel_max_capacity                : pre.hrmp_channel_max_capacity,
222					hrmp_channel_max_total_size              : pre.hrmp_channel_max_total_size,
223					hrmp_max_parachain_inbound_channels      : pre.hrmp_max_parachain_inbound_channels,
224					hrmp_max_parachain_outbound_channels     : pre.hrmp_max_parachain_outbound_channels,
225					hrmp_channel_max_message_size            : pre.hrmp_channel_max_message_size,
226					code_retention_period                    : pre.code_retention_period,
227					max_validators                           : pre.max_validators,
228					dispute_period                           : pre.dispute_period,
229					dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period,
230					no_show_slots                            : pre.no_show_slots,
231					n_delay_tranches                         : pre.n_delay_tranches,
232					zeroth_delay_tranche_width               : pre.zeroth_delay_tranche_width,
233					needed_approvals                         : pre.needed_approvals,
234					relay_vrf_modulo_samples                 : pre.relay_vrf_modulo_samples,
235					pvf_voting_ttl                           : pre.pvf_voting_ttl,
236					minimum_validation_upgrade_delay         : pre.minimum_validation_upgrade_delay,
237					async_backing_params                     : pre.async_backing_params,
238					executor_params                          : pre.executor_params,
239					minimum_backing_votes                    : pre.minimum_backing_votes,
240					node_features                            : pre.node_features,
241					approval_voting_params                   : pre.approval_voting_params,
242					scheduler_params: SchedulerParams {
243							group_rotation_frequency             : pre.scheduler_params.group_rotation_frequency,
244							paras_availability_period            : pre.scheduler_params.paras_availability_period,
245							max_validators_per_core              : pre.scheduler_params.max_validators_per_core,
246							lookahead                            : pre.scheduler_params.lookahead,
247							num_cores                            : pre.scheduler_params.num_cores,
248							on_demand_queue_max_size             : pre.scheduler_params.on_demand_queue_max_size,
249							on_demand_target_queue_utilization   : pre.scheduler_params.on_demand_target_queue_utilization,
250							on_demand_fee_variability            : pre.scheduler_params.on_demand_fee_variability,
251							on_demand_base_fee                   : pre.scheduler_params.on_demand_base_fee,
252					},
253					// New field: default to 0 (only allowing backing of candidates with relay parent in the current session).
254					max_relay_parent_session_age              : 0,
255				}
256			};
257
258	let v12 = v12::ActiveConfig::<T>::get()
259		.defensive_proof("Could not decode old config")
260		.unwrap_or_default();
261	let v13 = translate(v12);
262	v13::ActiveConfig::<T>::set(Some(v13));
263
264	// Allowed to be empty.
265	let pending_v12 = v12::PendingConfigs::<T>::get().unwrap_or_default();
266	let mut pending_v13 = Vec::with_capacity(pending_v12.len());
267
268	for (session, v12) in pending_v12.into_iter() {
269		let v13 = translate(v12);
270		pending_v13.push((session, v13));
271	}
272	v13::PendingConfigs::<T>::set(Some(pending_v13.clone()));
273
274	let num_configs = (pending_v13.len() + 1) as u64;
275	T::DbWeight::get().reads_writes(num_configs, num_configs)
276}
277
278#[cfg(test)]
279mod tests {
280	use super::*;
281	use crate::mock::{new_test_ext, Test};
282
283	#[test]
284	fn test_migrate_to_v13() {
285		let v12 = V12HostConfiguration::<polkadot_primitives::BlockNumber> {
286			scheduler_params: V12SchedulerParams { lookahead: 3, ..Default::default() },
287			..Default::default()
288		};
289
290		let mut pending_configs = Vec::new();
291		pending_configs.push((100, v12.clone()));
292		pending_configs.push((300, v12.clone()));
293
294		new_test_ext(Default::default()).execute_with(|| {
295			v12::ActiveConfig::<Test>::set(Some(v12.clone()));
296			v12::PendingConfigs::<Test>::set(Some(pending_configs));
297
298			migrate_to_v13::<Test>();
299
300			let v13 = v13::ActiveConfig::<Test>::get().unwrap();
301
302			let mut configs_to_check = v13::PendingConfigs::<Test>::get().unwrap();
303			configs_to_check.push((0, v13.clone()));
304
305			for (_, v13) in configs_to_check {
306				#[rustfmt::skip]
307				#[allow(deprecated)]
308				{
309					assert_eq!(v12.max_code_size                            , v13.max_code_size);
310					assert_eq!(v12.max_head_data_size                       , v13.max_head_data_size);
311					assert_eq!(v12.max_upward_queue_count                   , v13.max_upward_queue_count);
312					assert_eq!(v12.max_upward_queue_size                    , v13.max_upward_queue_size);
313					assert_eq!(v12.max_upward_message_size                  , v13.max_upward_message_size);
314					assert_eq!(v12.max_upward_message_num_per_candidate     , v13.max_upward_message_num_per_candidate);
315					assert_eq!(v12.hrmp_max_message_num_per_candidate       , v13.hrmp_max_message_num_per_candidate);
316					assert_eq!(v12.validation_upgrade_cooldown              , v13.validation_upgrade_cooldown);
317					assert_eq!(v12.validation_upgrade_delay                 , v13.validation_upgrade_delay);
318					assert_eq!(v12.max_pov_size                             , v13.max_pov_size);
319					assert_eq!(v12.max_downward_message_size                , v13.max_downward_message_size);
320					assert_eq!(v12.hrmp_max_parachain_outbound_channels     , v13.hrmp_max_parachain_outbound_channels);
321					assert_eq!(v12.hrmp_sender_deposit                      , v13.hrmp_sender_deposit);
322					assert_eq!(v12.hrmp_recipient_deposit                   , v13.hrmp_recipient_deposit);
323					assert_eq!(v12.hrmp_channel_max_capacity                , v13.hrmp_channel_max_capacity);
324					assert_eq!(v12.hrmp_channel_max_total_size              , v13.hrmp_channel_max_total_size);
325					assert_eq!(v12.hrmp_max_parachain_inbound_channels      , v13.hrmp_max_parachain_inbound_channels);
326					assert_eq!(v12.hrmp_channel_max_message_size            , v13.hrmp_channel_max_message_size);
327					assert_eq!(v12.code_retention_period                    , v13.code_retention_period);
328					assert_eq!(v12.max_validators                           , v13.max_validators);
329					assert_eq!(v12.dispute_period                           , v13.dispute_period);
330					assert_eq!(v12.no_show_slots                            , v13.no_show_slots);
331					assert_eq!(v12.n_delay_tranches                         , v13.n_delay_tranches);
332					assert_eq!(v12.zeroth_delay_tranche_width               , v13.zeroth_delay_tranche_width);
333					assert_eq!(v12.needed_approvals                         , v13.needed_approvals);
334					assert_eq!(v12.relay_vrf_modulo_samples                 , v13.relay_vrf_modulo_samples);
335					assert_eq!(v12.pvf_voting_ttl                           , v13.pvf_voting_ttl);
336					assert_eq!(v12.minimum_validation_upgrade_delay         , v13.minimum_validation_upgrade_delay);
337					assert_eq!(v12.async_backing_params                     , v13.async_backing_params);
338					assert_eq!(v12.executor_params                          , v13.executor_params);
339					assert_eq!(v12.minimum_backing_votes                    , v13.minimum_backing_votes);
340					assert_eq!(v12.scheduler_params.group_rotation_frequency, v13.scheduler_params.group_rotation_frequency);
341					assert_eq!(v12.scheduler_params.paras_availability_period, v13.scheduler_params.paras_availability_period);
342					assert_eq!(v12.scheduler_params.max_validators_per_core , v13.scheduler_params.max_validators_per_core);
343					assert_eq!(v12.scheduler_params.lookahead               , v13.scheduler_params.lookahead);
344					assert_eq!(v12.scheduler_params.num_cores               , v13.scheduler_params.num_cores);
345					assert_eq!(v12.scheduler_params.on_demand_queue_max_size, v13.scheduler_params.on_demand_queue_max_size);
346					assert_eq!(v12.scheduler_params.on_demand_target_queue_utilization, v13.scheduler_params.on_demand_target_queue_utilization);
347					assert_eq!(v12.scheduler_params.on_demand_fee_variability, v13.scheduler_params.on_demand_fee_variability);
348					assert_eq!(v12.scheduler_params.on_demand_base_fee      , v13.scheduler_params.on_demand_base_fee);
349					// New field should default to zero.
350					assert_eq!(v13.max_relay_parent_session_age, 0);
351				}; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression.
352			}
353		});
354	}
355
356	#[test]
357	fn test_migrate_to_v13_no_pending() {
358		let v12 = V12HostConfiguration::<polkadot_primitives::BlockNumber>::default();
359
360		new_test_ext(Default::default()).execute_with(|| {
361			v12::ActiveConfig::<Test>::set(Some(v12));
362			v13::PendingConfigs::<Test>::set(None);
363
364			// Shouldn't fail.
365			migrate_to_v13::<Test>();
366		});
367	}
368}