diff --git a/runtime/common/src/migrations.rs b/runtime/common/src/migrations.rs index 71efdd7ce..ddcbe2fde 100644 --- a/runtime/common/src/migrations.rs +++ b/runtime/common/src/migrations.rs @@ -36,7 +36,7 @@ #[cfg(feature = "try-runtime")] use frame_support::ensure; - +use sp_runtime::Perbill; use { cumulus_primitives_core::ParaId, frame_support::{ @@ -57,6 +57,125 @@ use { sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*}, }; +#[derive( + Default, + Clone, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + PartialEq, + sp_core::RuntimeDebug, + scale_info::TypeInfo, +)] +pub struct HostConfigurationV2 { + pub max_collators: u32, + pub min_orchestrator_collators: u32, + pub max_orchestrator_collators: u32, + pub collators_per_container: u32, + pub full_rotation_period: u32, + pub collators_per_parathread: u32, + pub parathreads_per_collator: u32, + pub target_container_chain_fullness: Perbill, +} + +pub struct MigrateConfigurationAddParachainPercentage(pub PhantomData); +impl Migration for MigrateConfigurationAddParachainPercentage +where + T: pallet_configuration::Config, +{ + fn friendly_name(&self) -> &str { + "TM_MigrateConfigurationAddParachainPercentage" + } + + fn migrate(&self, _available_weight: Weight) -> Weight { + const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"); + const CONFIGURATION_PENDING_CONFIGS_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22d53b4123b2e186e07fb7bad5dda5f55c0"); + let default_config = HostConfiguration::default(); + + // Modify active config + let old_config: HostConfigurationV2 = + frame_support::storage::unhashed::get(CONFIGURATION_ACTIVE_CONFIG_KEY) + .expect("configuration.activeConfig should have value"); + let new_config = HostConfiguration { + max_collators: old_config.max_collators, + min_orchestrator_collators: old_config.min_orchestrator_collators, + max_orchestrator_collators: old_config.max_orchestrator_collators, + collators_per_container: old_config.collators_per_container, + full_rotation_period: old_config.full_rotation_period, + collators_per_parathread: old_config.collators_per_parathread, + parathreads_per_collator: old_config.parathreads_per_collator, + target_container_chain_fullness: old_config.target_container_chain_fullness, + max_parachain_cores_percentage: default_config.max_parachain_cores_percentage, + }; + frame_support::storage::unhashed::put(CONFIGURATION_ACTIVE_CONFIG_KEY, &new_config); + + // Modify pending configs, if any + let old_pending_configs: Vec<(u32, HostConfigurationV2)> = + frame_support::storage::unhashed::get(CONFIGURATION_PENDING_CONFIGS_KEY) + .unwrap_or_default(); + let mut new_pending_configs: Vec<(u32, HostConfiguration)> = vec![]; + + for (session_index, old_config) in old_pending_configs { + let new_config = HostConfiguration { + max_collators: old_config.max_collators, + min_orchestrator_collators: old_config.min_orchestrator_collators, + max_orchestrator_collators: old_config.max_orchestrator_collators, + collators_per_container: old_config.collators_per_container, + full_rotation_period: old_config.full_rotation_period, + collators_per_parathread: old_config.collators_per_parathread, + parathreads_per_collator: old_config.parathreads_per_collator, + target_container_chain_fullness: old_config.target_container_chain_fullness, + max_parachain_cores_percentage: default_config.max_parachain_cores_percentage, + }; + new_pending_configs.push((session_index, new_config)); + } + + if !new_pending_configs.is_empty() { + frame_support::storage::unhashed::put( + CONFIGURATION_PENDING_CONFIGS_KEY, + &new_pending_configs, + ); + } + + ::WeightInfo::set_config_with_u32() + } + + /// Run a standard pre-runtime test. This works the same way as in a normal runtime upgrade. + #[cfg(feature = "try-runtime")] + fn pre_upgrade(&self) -> Result, sp_runtime::DispatchError> { + const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"); + + let old_config_bytes = + frame_support::storage::unhashed::get_raw(CONFIGURATION_ACTIVE_CONFIG_KEY) + .expect("configuration.activeConfig should have value"); + // This works because there is no enum in the v2 + assert_eq!( + old_config_bytes.len(), + HostConfigurationV2::default().encoded_size() + ); + + use parity_scale_codec::Encode; + Ok((old_config_bytes).encode()) + } + + /// Run a standard post-runtime test. This works the same way as in a normal runtime upgrade. + #[cfg(feature = "try-runtime")] + fn post_upgrade( + &self, + _number_of_invulnerables: Vec, + ) -> Result<(), sp_runtime::DispatchError> { + let new_config = pallet_configuration::Pallet::::config(); + let default_config = HostConfiguration::default(); + assert_eq!( + new_config.max_parachain_cores_percentage, + default_config.max_parachain_cores_percentage + ); + Ok(()) + } +} + #[derive( Clone, parity_scale_codec::Encode, @@ -808,6 +927,7 @@ where let migrate_data_preservers_assignments = DataPreserversAssignmentsMigration::(Default::default()); let migrate_registrar_reserves = RegistrarReserveToHoldMigration::(Default::default()); + let migrate_config_max_parachain_percentage = MigrateConfigurationAddParachainPercentage::(Default::default()); vec![ // Applied in runtime 400 @@ -821,6 +941,7 @@ where Box::new(migrate_registrar_manager), Box::new(migrate_data_preservers_assignments), Box::new(migrate_registrar_reserves), + Box::new(migrate_config_max_parachain_percentage), ] } } @@ -876,6 +997,7 @@ where let foreign_asset_creator_migration = ForeignAssetCreatorMigration::(Default::default()); let migrate_registrar_reserves = RegistrarReserveToHoldMigration::(Default::default()); + let migrate_config_max_parachain_percentage = MigrateConfigurationAddParachainPercentage::(Default::default()); vec![ // Applied in runtime 200 @@ -902,7 +1024,8 @@ where Box::new(migrate_pallet_xcm_v4), Box::new(foreign_asset_creator_migration), Box::new(migrate_data_preservers_assignments), - Box::new(migrate_registrar_reserves) + Box::new(migrate_registrar_reserves), + Box::new(migrate_config_max_parachain_percentage) ] } } diff --git a/runtime/dancebox/src/tests/integration_test.rs b/runtime/dancebox/src/tests/integration_test.rs index 465c435e1..83267f232 100644 --- a/runtime/dancebox/src/tests/integration_test.rs +++ b/runtime/dancebox/src/tests/integration_test.rs @@ -16,6 +16,7 @@ #![cfg(test)] +use rococo_runtime_constants::fee::Perbill; use { crate::tests::common::*, crate::{ @@ -60,7 +61,8 @@ use { }, std::marker::PhantomData, tanssi_runtime_common::migrations::{ - ForeignAssetCreatorMigration, MigrateConfigurationParathreads, + ForeignAssetCreatorMigration, HostConfigurationV2, + MigrateConfigurationAddParachainPercentage, MigrateConfigurationParathreads, MigrateServicesPaymentAddCollatorAssignmentCredits, RegistrarPendingVerificationValueToMap, }, test_relay_sproof_builder::{HeaderAs, ParaHeaderSproofBuilder, ParaHeaderSproofBuilderItem}, @@ -3896,6 +3898,113 @@ fn test_reward_to_invulnerable_with_key_change() { }); } +#[test] +fn test_migration_config_add_parachain_percentage() { + ExtBuilder::default().build().execute_with(|| { + const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"); + const CONFIGURATION_PENDING_CONFIGS_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22d53b4123b2e186e07fb7bad5dda5f55c0"); + + // Modify active config + frame_support::storage::unhashed::put_raw( + CONFIGURATION_ACTIVE_CONFIG_KEY, + &HostConfigurationV2 { + max_collators: 5, + min_orchestrator_collators: 2, + max_orchestrator_collators: 1, + collators_per_container: 3, + full_rotation_period: 4, + collators_per_parathread: 2, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(45), + } + .encode(), + ); + // Modify pending configs + frame_support::storage::unhashed::put_raw( + CONFIGURATION_PENDING_CONFIGS_KEY, + &vec![ + ( + 1234u32, + HostConfigurationV2 { + max_collators: 1, + min_orchestrator_collators: 4, + max_orchestrator_collators: 45, + collators_per_container: 5, + full_rotation_period: 1, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(65), + }, + ), + ( + 5678u32, + HostConfigurationV2 { + max_collators: 1, + min_orchestrator_collators: 4, + max_orchestrator_collators: 45, + collators_per_container: 5, + full_rotation_period: 1, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(65), + }, + ), + ] + .encode(), + ); + + let migration = MigrateConfigurationAddParachainPercentage::(Default::default()); + migration.migrate(Default::default()); + + let expected_active = pallet_configuration::HostConfiguration { + max_collators: 5, + min_orchestrator_collators: 2, + max_orchestrator_collators: 1, + collators_per_container: 3, + full_rotation_period: 4, + collators_per_parathread: 2, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(45), + ..Default::default() + }; + assert_eq!(Configuration::config(), expected_active); + + let expected_pending = vec![ + ( + 1234u32, + pallet_configuration::HostConfiguration { + max_collators: 1, + min_orchestrator_collators: 4, + max_orchestrator_collators: 45, + collators_per_container: 5, + full_rotation_period: 1, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(65), + ..Default::default() + }, + ), + ( + 5678u32, + pallet_configuration::HostConfiguration { + max_collators: 1, + min_orchestrator_collators: 4, + max_orchestrator_collators: 45, + collators_per_container: 5, + full_rotation_period: 1, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(65), + ..Default::default() + }, + ), + ]; + assert_eq!(Configuration::pending_configs(), expected_pending); + }); +} + #[test] fn test_migration_config_full_rotation_period() { ExtBuilder::default()