Skip to content

Commit

Permalink
Add generic HostConfiguration struct migration
Browse files Browse the repository at this point in the history
  • Loading branch information
tmpolaczyk committed Nov 29, 2024
1 parent 7720c6c commit d62d1fb
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 92 deletions.
128 changes: 41 additions & 87 deletions runtime/common/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
//! This module acts as a registry where each migration is defined. Each migration should implement
//! the "Migration" trait declared in the pallet-migrations crate.

use crate::migrations::generic_migrations::{GenericMigrateConfiguration, MigrateStructToLatest};
#[cfg(feature = "try-runtime")]
use frame_support::ensure;
use frame_support::migration::move_pallet;
Expand All @@ -49,7 +50,7 @@ use {
weights::Weight,
Blake2_128Concat, BoundedVec, StoragePrefixedMap,
},
pallet_configuration::{weights::WeightInfo as _, HostConfiguration},
pallet_configuration::HostConfiguration,
pallet_foreign_asset_creator::{AssetId, AssetIdToForeignAsset, ForeignAssetToAssetId},
pallet_migrations::{GetMigrations, Migration},
pallet_registrar::HoldReason,
Expand All @@ -58,6 +59,8 @@ use {
sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*},
};

mod generic_migrations;

#[derive(
Default,
Clone,
Expand All @@ -67,6 +70,7 @@ use {
sp_core::RuntimeDebug,
scale_info::TypeInfo,
)]

pub struct HostConfigurationV3 {
pub max_collators: u32,
pub min_orchestrator_collators: u32,
Expand All @@ -79,93 +83,43 @@ pub struct HostConfigurationV3 {
pub max_parachain_cores_percentage: Option<Perbill>,
}

pub struct MigrateConfigurationAddFullRotationMode<T>(pub PhantomData<T>);
impl<T> Migration for MigrateConfigurationAddFullRotationMode<T>
where
T: pallet_configuration::Config,
{
fn friendly_name(&self) -> &str {
"TM_MigrateConfigurationAddFullRotationMode"
}

fn migrate(&self, _available_weight: Weight) -> Weight {
let default_config = HostConfiguration::default();

// Modify active config
let old_config: HostConfigurationV3 = frame_support::storage::unhashed::get(
&pallet_configuration::ActiveConfig::<T>::hashed_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: old_config.max_parachain_cores_percentage,
// TODO: derive this impl using a macro
impl MigrateStructToLatest<HostConfiguration> for HostConfigurationV3 {
fn expand_with_default_values(self, default_config: &HostConfiguration) -> HostConfiguration {
#[deny(unused)]
let Self {
max_collators,
min_orchestrator_collators,
max_orchestrator_collators,
collators_per_container,
full_rotation_period,
collators_per_parathread,
parathreads_per_collator,
target_container_chain_fullness,
max_parachain_cores_percentage,
} = self;

HostConfiguration {
max_collators,
min_orchestrator_collators,
max_orchestrator_collators,
collators_per_container,
full_rotation_period,
collators_per_parathread,
parathreads_per_collator,
target_container_chain_fullness,
max_parachain_cores_percentage,
full_rotation_mode: default_config.full_rotation_mode.clone(),
};
frame_support::storage::unhashed::put(
&pallet_configuration::ActiveConfig::<T>::hashed_key(),
&new_config,
);

// Modify pending configs, if any
let old_pending_configs: Vec<(u32, HostConfigurationV3)> =
frame_support::storage::unhashed::get(
&pallet_configuration::PendingConfigs::<T>::hashed_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: old_config.max_parachain_cores_percentage,
full_rotation_mode: default_config.full_rotation_mode.clone(),
};
new_pending_configs.push((session_index, new_config));
}

if !new_pending_configs.is_empty() {
frame_support::storage::unhashed::put(
&pallet_configuration::PendingConfigs::<T>::hashed_key(),
&new_pending_configs,
);
}

<T as pallet_configuration::Config>::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<Vec<u8>, sp_runtime::DispatchError> {
Ok(vec![])
}
}

/// 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<u8>,
) -> Result<(), sp_runtime::DispatchError> {
let new_config = pallet_configuration::Pallet::<T>::config();
let default_config = HostConfiguration::default();
assert_eq!(
new_config.max_parachain_cores_percentage,
default_config.max_parachain_cores_percentage
);
Ok(())
pub fn migrate_configuration_add_full_rotation_mode<T>(
) -> GenericMigrateConfiguration<T, HostConfigurationV3> {
GenericMigrateConfiguration {
name: "TM_MigrateConfigurationAddFullRotationMode",
default: Default::default(),
phantom: Default::default(),
}
}

Expand Down Expand Up @@ -846,7 +800,7 @@ where
// DataPreserversAssignmentsMigration::<Runtime>(Default::default());
//let migrate_registrar_reserves = RegistrarReserveToHoldMigration::<Runtime>(Default::default());
//let migrate_config_max_parachain_percentage = MigrateConfigurationAddParachainPercentage::<Runtime>(Default::default());
let migrate_config_full_rotation_mode = MigrateConfigurationAddFullRotationMode::<Runtime>(Default::default());
let migrate_config_full_rotation_mode = migrate_configuration_add_full_rotation_mode::<Runtime>();

vec![
// Applied in runtime 400
Expand Down Expand Up @@ -917,7 +871,7 @@ where
//let foreign_asset_creator_migration =
// ForeignAssetCreatorMigration::<Runtime>(Default::default());
//let migrate_registrar_reserves = RegistrarReserveToHoldMigration::<Runtime>(Default::default());
let migrate_config_full_rotation_mode = MigrateConfigurationAddFullRotationMode::<Runtime>(Default::default());
let migrate_config_full_rotation_mode = migrate_configuration_add_full_rotation_mode::<Runtime>();

vec![
// Applied in runtime 200
Expand Down Expand Up @@ -1001,7 +955,7 @@ where
let migrate_external_validators =
ExternalValidatorsInitialMigration::<Runtime>(Default::default());
let migrate_config_full_rotation_mode =
MigrateConfigurationAddFullRotationMode::<Runtime>(Default::default());
migrate_configuration_add_full_rotation_mode::<Runtime>();

vec![
Box::new(migrate_mmr_leaf_pallet),
Expand Down
121 changes: 121 additions & 0 deletions runtime/common/src/migrations/generic_migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright (C) Moondance Labs Ltd.
// This file is part of Tanssi.

// Tanssi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Tanssi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see <http://www.gnu.org/licenses/>
// Copyright (C) Moondance Labs Ltd.
// This file is part of Tanssi.

// Tanssi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Tanssi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see <http://www.gnu.org/licenses/>

use cumulus_primitives_core::Weight;
use pallet_configuration::{HostConfiguration, WeightInfo as _};
use pallet_migrations::Migration;
use parity_scale_codec::Decode;
use sp_std::marker::PhantomData;
use sp_std::vec::Vec;

// Separate
use sp_std::vec;

pub trait MigrateStructToLatest<T> {
fn expand_with_default_values(self, default_config: &T) -> T;
}

pub struct GenericMigrateConfiguration<T, HostConfigurationV> {
pub name: &'static str,
pub default: HostConfiguration,
pub phantom: PhantomData<(T, HostConfigurationV)>,
}

impl<T, HostConfigurationV> Migration for GenericMigrateConfiguration<T, HostConfigurationV>
where
T: pallet_configuration::Config,
HostConfigurationV: Decode + MigrateStructToLatest<HostConfiguration>,
{
fn friendly_name(&self) -> &str {
self.name
}

fn migrate(&self, _available_weight: Weight) -> Weight {
// Modify active config
let old_config: HostConfigurationV = frame_support::storage::unhashed::get(
&pallet_configuration::ActiveConfig::<T>::hashed_key(),
)
.expect("configuration.activeConfig should have value");
let new_config = HostConfigurationV::expand_with_default_values(old_config, &self.default);
frame_support::storage::unhashed::put(
&pallet_configuration::ActiveConfig::<T>::hashed_key(),
&new_config,
);

// Modify pending configs, if any
let old_pending_configs: Vec<(u32, HostConfigurationV)> =
frame_support::storage::unhashed::get(
&pallet_configuration::PendingConfigs::<T>::hashed_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 =
HostConfigurationV::expand_with_default_values(old_config, &self.default);
new_pending_configs.push((session_index, new_config));
}

if !new_pending_configs.is_empty() {
frame_support::storage::unhashed::put(
&pallet_configuration::PendingConfigs::<T>::hashed_key(),
&new_pending_configs,
);
}

<T as pallet_configuration::Config>::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<Vec<u8>, sp_runtime::DispatchError> {
Ok(vec![])
}

/// 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<u8>,
) -> Result<(), sp_runtime::DispatchError> {
// TODO: add a generic callback here?
/*
let new_config = pallet_configuration::Pallet::<T>::config();
let default_config = HostConfiguration::default();
assert_eq!(
new_config.max_parachain_cores_percentage,
default_config.max_parachain_cores_percentage
);
*/
Ok(())
}
}
7 changes: 4 additions & 3 deletions runtime/dancebox/src/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ use {
},
std::marker::PhantomData,
tanssi_runtime_common::migrations::{
ForeignAssetCreatorMigration, HostConfigurationV3, MigrateConfigurationAddFullRotationMode,
MigrateServicesPaymentAddCollatorAssignmentCredits, RegistrarPendingVerificationValueToMap,
migrate_configuration_add_full_rotation_mode, ForeignAssetCreatorMigration,
HostConfigurationV3, MigrateServicesPaymentAddCollatorAssignmentCredits,
RegistrarPendingVerificationValueToMap,
},
test_relay_sproof_builder::{HeaderAs, ParaHeaderSproofBuilder, ParaHeaderSproofBuilderItem},
tp_traits::{ContainerChainBlockInfo, SlotFrequency},
Expand Down Expand Up @@ -3956,7 +3957,7 @@ fn test_migration_config_add_full_rotation_mode() {
.encode(),
);

let migration = MigrateConfigurationAddFullRotationMode::<Runtime>(Default::default());
let migration = migrate_configuration_add_full_rotation_mode::<Runtime>();
migration.migrate(Default::default());

let expected_active = pallet_configuration::HostConfiguration {
Expand Down
4 changes: 2 additions & 2 deletions solo-chains/runtime/dancelight/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use {crate::*, std::collections::HashSet};

use crate::tests::common::ExtBuilder;
use tanssi_runtime_common::migrations::{
HostConfigurationV3, MigrateConfigurationAddFullRotationMode,
migrate_configuration_add_full_rotation_mode, HostConfigurationV3,
};
use {frame_support::traits::WhitelistedStorageKeys, sp_core::hexdisplay::HexDisplay};

Expand Down Expand Up @@ -134,7 +134,7 @@ fn test_migration_config_add_full_rotation_mode() {
.encode(),
);

let migration = MigrateConfigurationAddFullRotationMode::<Runtime>(Default::default());
let migration = migrate_configuration_add_full_rotation_mode::<Runtime>();
migration.migrate(Default::default());

let expected_active = pallet_configuration::HostConfiguration {
Expand Down

0 comments on commit d62d1fb

Please sign in to comment.