1use crate::configuration::{Config, Pallet};
20use alloc::vec::Vec;
21use frame_support::{
22 pallet_prelude::*,
23 traits::{Defensive, UncheckedOnRuntimeUpgrade},
24 weights::Weight,
25};
26use frame_system::pallet_prelude::BlockNumberFor;
27use polkadot_primitives::{
28 AsyncBackingParams, Balance, ExecutorParams, NodeFeatures, SessionIndex,
29 LEGACY_MIN_BACKING_VOTES, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE,
30};
31use sp_runtime::Perbill;
32
33use super::v9::V9HostConfiguration;
34#[derive(Clone, Encode, PartialEq, Decode, Debug)]
36pub struct V10HostConfiguration<BlockNumber> {
37 pub max_code_size: u32,
38 pub max_head_data_size: u32,
39 pub max_upward_queue_count: u32,
40 pub max_upward_queue_size: u32,
41 pub max_upward_message_size: u32,
42 pub max_upward_message_num_per_candidate: u32,
43 pub hrmp_max_message_num_per_candidate: u32,
44 pub validation_upgrade_cooldown: BlockNumber,
45 pub validation_upgrade_delay: BlockNumber,
46 pub async_backing_params: AsyncBackingParams,
47 pub max_pov_size: u32,
48 pub max_downward_message_size: u32,
49 pub hrmp_max_parachain_outbound_channels: u32,
50 pub hrmp_sender_deposit: Balance,
51 pub hrmp_recipient_deposit: Balance,
52 pub hrmp_channel_max_capacity: u32,
53 pub hrmp_channel_max_total_size: u32,
54 pub hrmp_max_parachain_inbound_channels: u32,
55 pub hrmp_channel_max_message_size: u32,
56 pub executor_params: ExecutorParams,
57 pub code_retention_period: BlockNumber,
58 pub on_demand_cores: u32,
59 pub on_demand_retries: u32,
60 pub on_demand_queue_max_size: u32,
61 pub on_demand_target_queue_utilization: Perbill,
62 pub on_demand_fee_variability: Perbill,
63 pub on_demand_base_fee: Balance,
64 pub on_demand_ttl: BlockNumber,
65 pub group_rotation_frequency: BlockNumber,
66 pub paras_availability_period: BlockNumber,
67 pub scheduling_lookahead: u32,
68 pub max_validators_per_core: Option<u32>,
69 pub max_validators: Option<u32>,
70 pub dispute_period: SessionIndex,
71 pub dispute_post_conclusion_acceptance_period: BlockNumber,
72 pub no_show_slots: u32,
73 pub n_delay_tranches: u32,
74 pub zeroth_delay_tranche_width: u32,
75 pub needed_approvals: u32,
76 pub relay_vrf_modulo_samples: u32,
77 pub pvf_voting_ttl: SessionIndex,
78 pub minimum_validation_upgrade_delay: BlockNumber,
79 pub minimum_backing_votes: u32,
80 pub node_features: NodeFeatures,
81}
82
83impl<BlockNumber: Default + From<u32>> Default for V10HostConfiguration<BlockNumber> {
84 fn default() -> Self {
85 Self {
86 async_backing_params: AsyncBackingParams {
87 max_candidate_depth: 0,
88 allowed_ancestry_len: 0,
89 },
90 group_rotation_frequency: 1u32.into(),
91 paras_availability_period: 1u32.into(),
92 no_show_slots: 1u32.into(),
93 validation_upgrade_cooldown: Default::default(),
94 validation_upgrade_delay: 2u32.into(),
95 code_retention_period: Default::default(),
96 max_code_size: Default::default(),
97 max_pov_size: Default::default(),
98 max_head_data_size: Default::default(),
99 on_demand_cores: Default::default(),
100 on_demand_retries: Default::default(),
101 scheduling_lookahead: 1,
102 max_validators_per_core: Default::default(),
103 max_validators: None,
104 dispute_period: 6,
105 dispute_post_conclusion_acceptance_period: 100.into(),
106 n_delay_tranches: Default::default(),
107 zeroth_delay_tranche_width: Default::default(),
108 needed_approvals: Default::default(),
109 relay_vrf_modulo_samples: Default::default(),
110 max_upward_queue_count: Default::default(),
111 max_upward_queue_size: Default::default(),
112 max_downward_message_size: Default::default(),
113 max_upward_message_size: Default::default(),
114 max_upward_message_num_per_candidate: Default::default(),
115 hrmp_sender_deposit: Default::default(),
116 hrmp_recipient_deposit: Default::default(),
117 hrmp_channel_max_capacity: Default::default(),
118 hrmp_channel_max_total_size: Default::default(),
119 hrmp_max_parachain_inbound_channels: Default::default(),
120 hrmp_channel_max_message_size: Default::default(),
121 hrmp_max_parachain_outbound_channels: Default::default(),
122 hrmp_max_message_num_per_candidate: Default::default(),
123 pvf_voting_ttl: 2u32.into(),
124 minimum_validation_upgrade_delay: 2.into(),
125 executor_params: Default::default(),
126 on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE,
127 on_demand_base_fee: 10_000_000u128,
128 on_demand_fee_variability: Perbill::from_percent(3),
129 on_demand_target_queue_utilization: Perbill::from_percent(25),
130 on_demand_ttl: 5u32.into(),
131 minimum_backing_votes: LEGACY_MIN_BACKING_VOTES,
132 node_features: NodeFeatures::EMPTY,
133 }
134 }
135}
136
137mod v9 {
138 use super::*;
139
140 #[frame_support::storage_alias]
141 pub(crate) type ActiveConfig<T: Config> =
142 StorageValue<Pallet<T>, V9HostConfiguration<BlockNumberFor<T>>, OptionQuery>;
143
144 #[frame_support::storage_alias]
145 pub(crate) type PendingConfigs<T: Config> = StorageValue<
146 Pallet<T>,
147 Vec<(SessionIndex, V9HostConfiguration<BlockNumberFor<T>>)>,
148 OptionQuery,
149 >;
150}
151
152mod v10 {
153 use super::*;
154
155 #[frame_support::storage_alias]
156 pub(crate) type ActiveConfig<T: Config> =
157 StorageValue<Pallet<T>, V10HostConfiguration<BlockNumberFor<T>>, OptionQuery>;
158
159 #[frame_support::storage_alias]
160 pub(crate) type PendingConfigs<T: Config> = StorageValue<
161 Pallet<T>,
162 Vec<(SessionIndex, V10HostConfiguration<BlockNumberFor<T>>)>,
163 OptionQuery,
164 >;
165}
166
167pub struct VersionUncheckedMigrateToV10<T>(core::marker::PhantomData<T>);
168impl<T: Config> UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateToV10<T> {
169 #[cfg(feature = "try-runtime")]
170 fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
171 log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade() for HostConfiguration MigrateToV10");
172 Ok(Vec::new())
173 }
174
175 fn on_runtime_upgrade() -> Weight {
176 migrate_to_v10::<T>()
177 }
178
179 #[cfg(feature = "try-runtime")]
180 fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
181 log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade() for HostConfiguration MigrateToV10");
182 ensure!(
183 Pallet::<T>::on_chain_storage_version() >= StorageVersion::new(10),
184 "Storage version should be >= 10 after the migration"
185 );
186
187 Ok(())
188 }
189}
190
191pub type MigrateToV10<T> = frame_support::migrations::VersionedMigration<
192 9,
193 10,
194 VersionUncheckedMigrateToV10<T>,
195 Pallet<T>,
196 <T as frame_system::Config>::DbWeight,
197>;
198
199#[rustfmt::skip]
204fn translate<T: Config>(pre: V9HostConfiguration<BlockNumberFor<T>>) -> V10HostConfiguration<BlockNumberFor<T>> {
205 V10HostConfiguration {
206 max_code_size : pre.max_code_size,
207 max_head_data_size : pre.max_head_data_size,
208 max_upward_queue_count : pre.max_upward_queue_count,
209 max_upward_queue_size : pre.max_upward_queue_size,
210 max_upward_message_size : pre.max_upward_message_size,
211 max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate,
212 hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate,
213 validation_upgrade_cooldown : pre.validation_upgrade_cooldown,
214 validation_upgrade_delay : pre.validation_upgrade_delay,
215 max_pov_size : pre.max_pov_size,
216 max_downward_message_size : pre.max_downward_message_size,
217 hrmp_sender_deposit : pre.hrmp_sender_deposit,
218 hrmp_recipient_deposit : pre.hrmp_recipient_deposit,
219 hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity,
220 hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size,
221 hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels,
222 hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels,
223 hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size,
224 code_retention_period : pre.code_retention_period,
225 on_demand_cores : pre.on_demand_cores,
226 on_demand_retries : pre.on_demand_retries,
227 group_rotation_frequency : pre.group_rotation_frequency,
228 paras_availability_period : pre.paras_availability_period,
229 scheduling_lookahead : pre.scheduling_lookahead,
230 max_validators_per_core : pre.max_validators_per_core,
231 max_validators : pre.max_validators,
232 dispute_period : pre.dispute_period,
233 dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period,
234 no_show_slots : pre.no_show_slots,
235 n_delay_tranches : pre.n_delay_tranches,
236 zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width,
237 needed_approvals : pre.needed_approvals,
238 relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples,
239 pvf_voting_ttl : pre.pvf_voting_ttl,
240 minimum_validation_upgrade_delay : pre.minimum_validation_upgrade_delay,
241 async_backing_params : pre.async_backing_params,
242 executor_params : pre.executor_params,
243 on_demand_queue_max_size : pre.on_demand_queue_max_size,
244 on_demand_base_fee : pre.on_demand_base_fee,
245 on_demand_fee_variability : pre.on_demand_fee_variability,
246 on_demand_target_queue_utilization : pre.on_demand_target_queue_utilization,
247 on_demand_ttl : pre.on_demand_ttl,
248 minimum_backing_votes : pre.minimum_backing_votes,
249 node_features : NodeFeatures::EMPTY
250 }
251}
252
253fn migrate_to_v10<T: Config>() -> Weight {
254 let v9 = v9::ActiveConfig::<T>::get()
255 .defensive_proof("Could not decode old config")
256 .unwrap_or_default();
257 let v10 = translate::<T>(v9);
258 v10::ActiveConfig::<T>::set(Some(v10));
259
260 let pending_v9 = v9::PendingConfigs::<T>::get().unwrap_or_default();
262 let mut pending_v10 = Vec::new();
263
264 for (session, v9) in pending_v9.into_iter() {
265 let v10 = translate::<T>(v9);
266 pending_v10.push((session, v10));
267 }
268 v10::PendingConfigs::<T>::set(Some(pending_v10.clone()));
269
270 let num_configs = (pending_v10.len() + 1) as u64;
271 T::DbWeight::get().reads_writes(num_configs, num_configs)
272}
273
274#[cfg(test)]
275mod tests {
276 use super::*;
277 use crate::mock::{new_test_ext, Test};
278 use polkadot_primitives::LEGACY_MIN_BACKING_VOTES;
279
280 #[test]
281 fn v10_deserialized_from_actual_data() {
282 let raw_config =
302 hex_literal::hex!["
303 0000300000800000080000000000100000c8000005000000050000000200000002000000000000000000000000005000000010000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000000100000b004000000000000000000001027000080b2e60e80c3c90180969800000000000000000000000000050000001400000004000000010000000101000000000600000064000000020000001900000000000000020000000200000002000000050000000200000000"
304 ];
305
306 let v10 =
307 V10HostConfiguration::<polkadot_primitives::BlockNumber>::decode(&mut &raw_config[..])
308 .unwrap();
309
310 assert_eq!(v10.max_code_size, 3_145_728);
313 assert_eq!(v10.validation_upgrade_cooldown, 2);
314 assert_eq!(v10.max_pov_size, 5_242_880);
315 assert_eq!(v10.hrmp_channel_max_message_size, 1_048_576);
316 assert_eq!(v10.n_delay_tranches, 25);
317 assert_eq!(v10.minimum_validation_upgrade_delay, 5);
318 assert_eq!(v10.group_rotation_frequency, 20);
319 assert_eq!(v10.on_demand_cores, 0);
320 assert_eq!(v10.on_demand_base_fee, 10_000_000);
321 assert_eq!(v10.minimum_backing_votes, LEGACY_MIN_BACKING_VOTES);
322 assert_eq!(v10.node_features, NodeFeatures::EMPTY);
323 }
324
325 #[test]
328 fn test_migrate_to_v10() {
329 let v9 = V9HostConfiguration::<polkadot_primitives::BlockNumber> {
338 needed_approvals: 69,
339 paras_availability_period: 55,
340 hrmp_recipient_deposit: 1337,
341 max_pov_size: 1111,
342 minimum_validation_upgrade_delay: 20,
343 ..Default::default()
344 };
345
346 let mut pending_configs = Vec::new();
347 pending_configs.push((100, v9.clone()));
348 pending_configs.push((300, v9.clone()));
349
350 new_test_ext(Default::default()).execute_with(|| {
351 v9::ActiveConfig::<Test>::set(Some(v9.clone()));
353 v9::PendingConfigs::<Test>::set(Some(pending_configs));
354
355 migrate_to_v10::<Test>();
356
357 let v10 = translate::<Test>(v9);
358 let mut configs_to_check = v10::PendingConfigs::<Test>::get().unwrap();
359 configs_to_check.push((0, v10::ActiveConfig::<Test>::get().unwrap()));
360
361 for (_, config) in configs_to_check {
362 assert_eq!(config, v10);
363 assert_eq!(config.node_features, NodeFeatures::EMPTY);
364 }
365 });
366 }
367
368 #[test]
371 fn test_migrate_to_v10_no_pending() {
372 let v9 = V9HostConfiguration::<polkadot_primitives::BlockNumber>::default();
373
374 new_test_ext(Default::default()).execute_with(|| {
375 v9::ActiveConfig::<Test>::set(Some(v9));
377 v9::PendingConfigs::<Test>::set(None);
379
380 migrate_to_v10::<Test>();
382 });
383 }
384}