From a0504f47f7fcb41fde3a23322ad40722f860be27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal=20Murray?= Date: Tue, 7 May 2024 10:50:11 +0100 Subject: [PATCH] Remove one-shot migrations from Kusama Coretime (#300) Several one-shot (single use) migrations were used in the launch of Coretime on Kusama. This PR removes them from the codebase since they are no longer relevant. I've intentionally not bumped the spec_version, since I'm not suggesting this be released. - [ ] Does not require a CHANGELOG entry --- CHANGELOG.md | 4 + .../coretime/coretime-kusama/src/lib.rs | 3 - .../coretime-kusama/src/migrations.rs | 263 ------------------ 3 files changed, 4 insertions(+), 266 deletions(-) delete mode 100644 system-parachains/coretime/coretime-kusama/src/migrations.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index afbc92f51b..ac195fd95d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Include patch to release stuck collator bonds ([polkadot-fellows/runtimes#289](https://github.com/polkadot-fellows/runtimes/pull/289)) - Kusama chains: allow arbitrary XCM execution ([polkadot-fellows/runtimes#261](https://github.com/polkadot-fellows/runtimes/pull/261)) +### Removed + +- Remove one-shot migrations from Kusama Coretime ([polkadot-fellows/runtimes#300](https://github.com/polkadot-fellows/runtimes/pull/300)) + ## [1.2.3] 29.04.2024 ### Added diff --git a/system-parachains/coretime/coretime-kusama/src/lib.rs b/system-parachains/coretime/coretime-kusama/src/lib.rs index ec946250ac..a0871ce399 100644 --- a/system-parachains/coretime/coretime-kusama/src/lib.rs +++ b/system-parachains/coretime/coretime-kusama/src/lib.rs @@ -23,7 +23,6 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod coretime; -mod migrations; #[cfg(test)] mod tests; mod weights; @@ -110,8 +109,6 @@ pub type UncheckedExtrinsic = pub type Migrations = ( pallet_xcm::migration::MigrateToLatestXcmVersion, pallet_collator_selection::migration::v2::MigrationToV2, - migrations::bootstrapping::RemoveOutdatedPoolAssignment, - migrations::bootstrapping::OnboardPeople, ); /// Executive: handles dispatch to the various modules. diff --git a/system-parachains/coretime/coretime-kusama/src/migrations.rs b/system-parachains/coretime/coretime-kusama/src/migrations.rs deleted file mode 100644 index 5caa111580..0000000000 --- a/system-parachains/coretime/coretime-kusama/src/migrations.rs +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright (C) Parity Technologies and the various Polkadot contributors, see Contributions.md -// for a list of specific contributors. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// The Kusama Coretime chain had some launch issues. These migrations clean up state and enable -/// immediate onboarding of system parachains. -/// -/// None of these migrations affect storage structure, only values. -pub mod bootstrapping { - use crate::{weights, Runtime, RuntimeOrigin}; - use frame_support::{pallet_prelude::*, traits::OnRuntimeUpgrade}; - #[cfg(feature = "try-runtime")] - use pallet_broker::StatusRecord; - use pallet_broker::{ - AllowedRenewals, - CoreAssignment::{Pool, Task}, - CoreIndex, CoreMask, Leases, Reservations, SaleInfo, Schedule, ScheduleItem, Status, - Timeslice, WeightInfo, Workplan, - }; - #[cfg(feature = "try-runtime")] - use sp_runtime::TryRuntimeError; - use sp_std::vec::Vec; - - /// The log target. - const TARGET: &str = "runtime::bootstrapping::onboard-people"; - - // The key in Workplan with the outdated assignment. - const WORKPLAN_KEY: (Timeslice, CoreIndex) = (289960, 4); - - // Alias to the broker weights for this runtime. - type BrokerWeights = weights::pallet_broker::WeightInfo; - type RuntimeDbWeight = ::DbWeight; - - /// This migration cleans up an outdated pool assignment in state from the update to Kusama - /// Coretime 1002002. - pub struct RemoveOutdatedPoolAssignment; - - impl OnRuntimeUpgrade for RemoveOutdatedPoolAssignment { - fn on_runtime_upgrade() -> Weight { - let schedule_pool = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Pool, - }])); - if Workplan::::get(WORKPLAN_KEY) != Some(schedule_pool) { - // Erroneous pool core assignment is not in state. Bailing. - log::error!(target: TARGET, "This migration includes hardcoded values not relevant to this runtime. Bailing."); - return RuntimeDbWeight::get().reads(1); - } - - // Overwrite outdated pool core assignment to keep parachain 2000 on core. - let schedule_2000 = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Task(2000), - }])); - Workplan::::insert(WORKPLAN_KEY, schedule_2000); - - log::info!(target: TARGET, "Outdated Workplan entry has been overwritten."); - - RuntimeDbWeight::get().reads(1).saturating_add(RuntimeDbWeight::get().writes(1)) - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result, TryRuntimeError> { - let schedule_pool = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Pool, - }])); - if Workplan::::get(WORKPLAN_KEY) != Some(schedule_pool) { - return Ok(Vec::new()) - } - let sale_info = SaleInfo::::get().unwrap(); - Ok(sale_info.encode()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { - if state.is_empty() { - return Ok(()) - } - log::info!(target: TARGET, "Checking migration."); - - // Check that cores 0-4 are now all reassigned to themselves at the end of the original - // period 0 before sales were restarted. - let expected_assignments = [Task(1000), Task(1001), Task(1002), Task(1005), Task(2000)]; - for (core, assignment) in expected_assignments.into_iter().enumerate() { - assert_eq!( - Workplan::::get((289960, core as u16)), - Some(Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment - }]))) - ); - } - - // There are no more surprise entries in the Workplan - the only cores which have - // reassignments before start sales kicks in are the five checked above. - assert_eq!( - Workplan::::iter_keys() - .filter(|(timeslice, _)| *timeslice != 290808) - .count(), - 5 - ); - - Ok(()) - } - } - - /// The People Chain should be onboarded ASAP to Kusama, however the reserve extrinsic - /// takes two sale period boundaries to actually put new reservations on core. This - /// migration adds the People Chain immediately. - /// - /// This is achieved in three steps: - /// 1. Reserve a core for People (from period 2) - /// 2. Add People Chain to the workplan for period 1 - /// 3. Add People Chain to the workplan for the remainder of period 0 - pub struct OnboardPeople; - - impl OnRuntimeUpgrade for OnboardPeople { - fn on_runtime_upgrade() -> Weight { - // Make sure People Chain is not already reserved. - let schedule_people = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Task(1004), - }])); - if Reservations::::get().iter().any(|res| *res == schedule_people) { - log::error!(target: TARGET, "The people chain is already reserved. Bailing."); - return RuntimeDbWeight::get().reads(1); - } - - let next_period = SaleInfo::::get() - .map(|sale_info| sale_info.region_begin) - .expect("Sales have started on Kusama."); - - // Request an extra core for the People Chain. - let core_count = Reservations::::decode_len().unwrap_or(0) as u16 + - Leases::::decode_len().unwrap_or(0) as u16 + - AllowedRenewals::::iter_keys() - .filter(|renewal| renewal.when >= next_period) - .count() as u16 + 4; - - match pallet_broker::Pallet::::request_core_count( - RuntimeOrigin::root(), - core_count, - ) { - Ok(_) => log::info!(target: TARGET, "Request for 56 cores sent."), - Err(_) => log::error!(target: TARGET, "Request for 56 cores failed to send."), - } - - // People core should be assigned the new core to avoid clashes with the cores sold in - // period 0. - let people_core = core_count.saturating_sub(1); - - // 1. Schedule People Chain for period 2 and beyond. - let schedule_people = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Task(1004), - }])); - match pallet_broker::Pallet::::reserve( - RuntimeOrigin::root(), - schedule_people.clone(), - ) { - Ok(_) => log::info!(target: TARGET, "People Chain reserved"), - Err(_) => log::error!(target: TARGET, "People Chain reservation failed!"), - } - - // 2. Schedule People Chain for period 1. - Workplan::::insert((next_period, people_core), schedule_people.clone()); - - // 3. Schedule People for the rest of period 0. Take the timeslice after the next tick - // so we the core definitely gets processed. - let now_ish = Status::::get() - .map(|status| status.last_committed_timeslice.saturating_add(2)) - .expect("Sales have started on Kusama."); - Workplan::::insert((now_ish, people_core), schedule_people); - - BrokerWeights::reserve() - .saturating_add(BrokerWeights::request_core_count(56)) - .saturating_add(RuntimeDbWeight::get().reads(6)) - .saturating_add(RuntimeDbWeight::get().writes(2)) - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - let schedule_people = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Task(1004), - }])); - if Reservations::::get().iter().any(|res| *res == schedule_people) { - return Ok(Vec::new()) - } - let status = Status::::get().unwrap(); - Ok(status.encode()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { - if state.is_empty() { - return Ok(()) - } - log::info!(target: TARGET, "Checking migration."); - - let prev_status = ::decode(&mut &state[..]).unwrap(); - - // People Chain is reserved exactly once. - let schedule_people = Schedule::truncate_from(Vec::from([ScheduleItem { - mask: CoreMask::complete(), - assignment: Task(1004), - }])); - assert_eq!( - Reservations::::get() - .iter() - .filter(|&res| *res == schedule_people.clone()) - .count(), - 1 - ); - - // And is in the Workplan for periods 0 and 1. - assert_eq!( - Workplan::::get((prev_status.last_committed_timeslice + 2, 55)), - Some(schedule_people.clone()) - ); - - let next_period = - SaleInfo::::get().map(|sale_info| sale_info.region_begin).unwrap(); - - assert_eq!(Workplan::::get((next_period, 55)), Some(schedule_people.clone())); - - // Ensure we have requested the correct number of cores. - assert!(frame_system::Pallet::::read_events_no_consensus().any(|e| { - match e.event { - crate::RuntimeEvent::Broker( - pallet_broker::Event::::CoreCountRequested { core_count }, - ) => { - log::info!(target: TARGET, "Reserved {core_count:?} cores."); - - // Ensure that both of these are correct as a sanity check since we hardcode - // core 55 elsewhere. - core_count == prev_status.core_count + 1 && core_count == 56 - }, - _ => false, - } - })); - - // And ensure this core isn't overwritten at any stage, it should only have the two - // entries in the workload that we just checked. - assert_eq!(Workplan::::iter_keys().filter(|(_, core)| *core == 55).count(), 2); - - Ok(()) - } - } -}