diff --git a/relay/polkadot/src/coretime_migration.rs b/relay/polkadot/src/coretime_migration.rs deleted file mode 100644 index e303ae05d8..0000000000 --- a/relay/polkadot/src/coretime_migration.rs +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot 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. - -// Polkadot 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 Polkadot. If not, see . - -//! Coretime migration for Polkadot runtime - -use crate::{ - coretime::{Config, WeightInfo}, - parachains_assigner_coretime, - parachains_assigner_coretime::PartsOf57600, - OriginKind, -}; -use alloc::{vec, vec::Vec}; -use codec::{Decode, Encode}; -use core::{iter, result}; -#[cfg(feature = "try-runtime")] -use frame_support::{ - traits::{OnRuntimeUpgrade, PalletInfoAccess, StorageVersion}, - weights::Weight, -}; -use frame_system::pallet_prelude::BlockNumberFor; -use pallet_broker::{CoreAssignment, CoreMask, ScheduleItem}; -use polkadot_parachain_primitives::primitives::IsSystem; -use polkadot_primitives::{Balance, BlockNumber, CoreIndex, Id as ParaId}; -use polkadot_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD; -use runtime_parachains::configuration; - -use sp_arithmetic::traits::SaturatedConversion; -use sp_core::Get; -use sp_runtime::BoundedVec; -use xcm::prelude::{send_xcm, Instruction, Junction, Location, SendError, WeightLimit, Xcm}; - -/// Return information about a legacy lease of a parachain. -pub trait GetLegacyLease { - /// If parachain is a lease holding parachain, return the block at which the lease expires. - fn get_parachain_lease_in_blocks(para: ParaId) -> Option; - // All parachains holding a lease, no matter if there are gaps in the slots or not. - fn get_all_parachains_with_leases() -> Vec; -} - -#[derive(Encode, Decode)] -enum CoretimeCalls { - #[codec(index = 1)] - Reserve(pallet_broker::Schedule), - #[codec(index = 3)] - SetLease(pallet_broker::TaskId, pallet_broker::Timeslice), - #[codec(index = 19)] - NotifyCoreCount(u16), - #[codec(index = 20)] - NotifyRevenue((BlockNumber, Balance)), - #[codec(index = 99)] - SwapLeases(ParaId, ParaId), -} - -#[derive(Encode, Decode)] -enum BrokerRuntimePallets { - #[codec(index = 50)] - Broker(CoretimeCalls), -} - -/// Migrate a chain to use coretime. -/// -/// This assumes that the `Coretime` and the `AssignerCoretime` pallets are added at the same -/// time to a runtime. -pub struct MigrateToCoretime( - core::marker::PhantomData<(T, SendXcm, LegacyLease)>, -); - -impl>> - MigrateToCoretime -{ - fn already_migrated() -> bool { - // We are using the assigner coretime because the coretime pallet doesn't has any - // storage data. But both pallets are introduced at the same time, so this is fine. - let name_hash = parachains_assigner_coretime::Pallet::::name_hash(); - let mut next_key = name_hash.to_vec(); - let storage_version_key = - StorageVersion::storage_key::>(); - - loop { - match sp_io::storage::next_key(&next_key) { - // StorageVersion is initialized before, so we need to ignore it. - Some(key) if key == storage_version_key => { - next_key = key; - }, - // If there is any other key with the prefix of the pallet, - // we already have executed the migration. - Some(key) if key.starts_with(&name_hash) => { - log::info!("`MigrateToCoretime` already executed!"); - return true - }, - // Any other key/no key means that we did not yet have migrated. - None | Some(_) => return false, - } - } - } -} - -impl< - T: Config + runtime_parachains::dmp::Config, - SendXcm: xcm::v5::SendXcm, - LegacyLease: GetLegacyLease>, - > OnRuntimeUpgrade for MigrateToCoretime -{ - fn on_runtime_upgrade() -> Weight { - if Self::already_migrated() { - return Weight::zero() - } - - log::info!("Migrating existing parachains to coretime."); - migrate_to_coretime::() - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result, sp_runtime::DispatchError> { - if Self::already_migrated() { - return Ok(Vec::new()) - } - - let legacy_paras = LegacyLease::get_all_parachains_with_leases(); - let config = configuration::ActiveConfig::::get(); - let total_core_count = config.scheduler_params.num_cores + legacy_paras.len() as u32; - - Ok(total_core_count.encode()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade(state: Vec) -> Result<(), sp_runtime::DispatchError> { - if state.is_empty() { - return Ok(()) - } - - log::trace!("Running post_upgrade()"); - - // TODO @alindima: Are these migrations expected to remain? - // let prev_core_count = ::decode(&mut &state[..]).unwrap(); - // let new_core_count = parachains_assigner_coretime::Pallet::::session_core_count(); - // ensure!(new_core_count == prev_core_count, "Total number of cores need to not change."); - - Ok(()) - } -} - -// Migrate to Coretime. -// -// NOTE: Also migrates `num_cores` config value in configuration::ActiveConfig. -fn migrate_to_coretime< - T: Config, - SendXcm: xcm::v5::SendXcm, - LegacyLease: GetLegacyLease>, ->() -> Weight { - let legacy_paras = LegacyLease::get_all_parachains_with_leases(); - let legacy_count = legacy_paras.len() as u32; - let now = frame_system::Pallet::::block_number(); - for (core, para_id) in legacy_paras.into_iter().enumerate() { - let r = parachains_assigner_coretime::Pallet::::assign_core( - CoreIndex(core as u32), - now, - vec![(CoreAssignment::Task(para_id.into()), PartsOf57600::FULL)], - None, - ); - if let Err(err) = r { - log::error!( - "Creating assignment for existing para failed: {:?}, error: {:?}", - para_id, - err - ); - } - } - - let config = configuration::ActiveConfig::::get(); - for on_demand in 0..config.scheduler_params.num_cores { - let core = CoreIndex(legacy_count.saturating_add(on_demand as _)); - let r = parachains_assigner_coretime::Pallet::::assign_core( - core, - now, - vec![(CoreAssignment::Pool, PartsOf57600::FULL)], - None, - ); - if let Err(err) = r { - log::error!("Creating assignment for existing on-demand core, failed: {:?}", err); - } - } - let total_cores = config.scheduler_params.num_cores + legacy_count; - configuration::ActiveConfig::::mutate(|c| { - c.scheduler_params.num_cores = total_cores; - }); - - if let Err(err) = migrate_send_assignments_to_coretime_chain::() { - log::error!("Sending legacy chain data to coretime chain failed: {:?}", err); - } - - let single_weight = ::WeightInfo::assign_core(1); - single_weight - .saturating_mul(u64::from(legacy_count.saturating_add(config.scheduler_params.num_cores))) - // Second read from sending assignments to the coretime chain. - .saturating_add(T::DbWeight::get().reads_writes(2, 1)) -} - -fn migrate_send_assignments_to_coretime_chain< - T: Config, - SendXcm: xcm::v5::SendXcm, - LegacyLease: GetLegacyLease>, ->() -> result::Result<(), SendError> { - let legacy_paras = LegacyLease::get_all_parachains_with_leases(); - let legacy_paras_count = legacy_paras.len(); - let (system_chains, lease_holding): (Vec<_>, Vec<_>) = - legacy_paras.into_iter().partition(IsSystem::is_system); - - let reservations = system_chains.into_iter().map(|p| { - let schedule = BoundedVec::truncate_from(vec![ScheduleItem { - mask: CoreMask::complete(), - assignment: CoreAssignment::Task(p.into()), - }]); - mk_coretime_call::(CoretimeCalls::Reserve(schedule)) - }); - - let mut leases = lease_holding.into_iter().filter_map(|p| { - log::trace!(target: "coretime-migration", "Preparing sending of lease holding para {:?}", p); - let Some(valid_until) = LegacyLease::get_parachain_lease_in_blocks(p) else { - log::error!("Lease holding chain with no lease information?!"); - return None - }; - - let valid_until: u32 = match BlockNumberFor::::try_into(valid_until) { - Ok(val) => val, - Err(_) => { - log::error!("Converting block number to u32 failed!"); - return None - }, - }; - - let time_slice = (valid_until + TIMESLICE_PERIOD - 1).div_ceil(TIMESLICE_PERIOD); - log::trace!(target: "coretime-migration", "Sending of lease holding para {:?}, valid_until: {:?}, time_slice: {:?}", p, valid_until, time_slice); - Some(mk_coretime_call::(CoretimeCalls::SetLease(p.into(), time_slice))) - }); - - let core_count: u16 = configuration::ActiveConfig::::get() - .scheduler_params - .num_cores - .saturated_into(); - let set_core_count = - iter::once(mk_coretime_call::(CoretimeCalls::NotifyCoreCount(core_count))); - log::trace!(target: "coretime-migration", "Set core count to {:?}. legacy paras count is {:?}",core_count, legacy_paras_count); - - let pool = (legacy_paras_count..core_count.into()).map(|_| { - let schedule = BoundedVec::truncate_from(vec![ScheduleItem { - mask: CoreMask::complete(), - assignment: CoreAssignment::Pool, - }]); - // Reserved cores will come before lease cores, so cores will change their assignments - // when coretime chain sends us their assign_core calls -> Good test. - mk_coretime_call::(CoretimeCalls::Reserve(schedule)) - }); - - let message_content = iter::once(Instruction::UnpaidExecution { - weight_limit: WeightLimit::Unlimited, - check_origin: None, - }); - - let reservation_content = message_content.clone().chain(reservations).collect(); - let leases_content_1 = message_content - .clone() - .chain(leases.by_ref().take(legacy_paras_count / 2)) // split in two messages to avoid overweighted XCM - .collect(); - let leases_content_2 = message_content.clone().chain(leases).collect(); - let set_core_count_content = message_content.clone().chain(set_core_count).collect(); - - // If `pool_content` is empty don't send a blank XCM message - let messages = if core_count as usize > legacy_paras_count { - let pool_content = message_content.clone().chain(pool).collect(); - vec![ - Xcm(reservation_content), - Xcm(pool_content), - Xcm(leases_content_1), - Xcm(leases_content_2), - Xcm(set_core_count_content), - ] - } else { - vec![ - Xcm(reservation_content), - Xcm(leases_content_1), - Xcm(leases_content_2), - Xcm(set_core_count_content), - ] - }; - - for message in messages { - send_xcm::(Location::new(0, Junction::Parachain(T::BrokerId::get())), message)?; - } - - Ok(()) -} - -fn mk_coretime_call(call: CoretimeCalls) -> Instruction<()> { - Instruction::Transact { - origin_kind: OriginKind::Superuser, - fallback_max_weight: Some(T::MaxXcmTransactWeight::get()), - call: BrokerRuntimePallets::Broker(call).encode().into(), - } -} diff --git a/relay/polkadot/src/lib.rs b/relay/polkadot/src/lib.rs index 117d2d99d8..ec0b5f3fb8 100644 --- a/relay/polkadot/src/lib.rs +++ b/relay/polkadot/src/lib.rs @@ -151,8 +151,6 @@ use governance::{ pub mod impls; pub mod xcm_config; -mod coretime_migration; - /// Default logging target. pub const LOG_TARGET: &str = "runtime::polkadot"; @@ -1134,8 +1132,7 @@ impl InstanceFilter for ProxyType { matches!( c, RuntimeCall::Staking(..) | - RuntimeCall::Session(..) | - RuntimeCall::Utility(..) | + RuntimeCall::Session(..) | RuntimeCall::Utility(..) | RuntimeCall::FastUnstake(..) | RuntimeCall::VoterList(..) | RuntimeCall::NominationPools(..) @@ -1931,68 +1928,8 @@ pub type Migrations = (migrations::Unreleased, migrations::Permanent); /// The runtime migrations per release. #[allow(deprecated, missing_docs)] pub mod migrations { - use polkadot_runtime_common::traits::Leaser; - use super::*; - pub struct GetLegacyLeaseImpl; - impl coretime_migration::GetLegacyLease for GetLegacyLeaseImpl { - fn get_parachain_lease_in_blocks(para: ParaId) -> Option { - let now = frame_system::Pallet::::block_number(); - let lease = slots::Leases::::get(para); - if lease.is_empty() { - return None; - } - let (index, _) = - as Leaser>::lease_period_index(now)?; - Some(index.saturating_add(lease.len() as u32).saturating_mul(LeasePeriod::get())) - } - - fn get_all_parachains_with_leases() -> Vec { - slots::Leases::::iter() - .filter(|(_, lease)| !lease.is_empty()) - .map(|(para, _)| para) - .collect::>() - } - } - - /// Cancel all ongoing auctions. - /// - /// Any leases that come into existence after coretime was launched will not be served. Yet, - /// any ongoing auctions must be cancelled. - /// - /// Safety: - /// - /// - After coretime is launched, there are no auctions anymore. So if this forgotten to be - /// removed after the runtime upgrade, running this again on the next one is harmless. - /// - I am assuming scheduler `TaskName`s are unique, so removal of the scheduled entry multiple - /// times should also be fine. - pub struct CancelAuctions; - impl OnRuntimeUpgrade for CancelAuctions { - fn on_runtime_upgrade() -> Weight { - if let Err(err) = Auctions::cancel_auction(frame_system::RawOrigin::Root.into()) { - log::debug!(target: "runtime", "Cancelling auctions failed: {:?}", err); - } - // Cancel scheduled auction as well: - if let Err(err) = Scheduler::cancel_named( - pallet_custom_origins::Origin::AuctionAdmin.into(), - [ - 0x87, 0xa8, 0x71, 0xb4, 0xd6, 0x21, 0xf0, 0xb9, 0x73, 0x47, 0x5a, 0xaf, 0xcc, - 0x32, 0x61, 0x0b, 0xd7, 0x68, 0x8f, 0x15, 0x02, 0x33, 0x8a, 0xcd, 0x00, 0xee, - 0x48, 0x8a, 0xc3, 0x62, 0x0f, 0x4c, - ], - ) { - log::debug!(target: "runtime", "Cancelling scheduled auctions failed: {:?}", err); - } - use pallet_scheduler::WeightInfo as _; - use polkadot_runtime_common::auctions::WeightInfo as _; - weights::polkadot_runtime_common_auctions::WeightInfo::::cancel_auction() - .saturating_add(weights::pallet_scheduler::WeightInfo::::cancel_named( - ::MaxScheduledPerBlock::get(), - )) - } - } - parameter_types! { // This is used to bound number of pools migrating in the runtime upgrade. This is set to // ~existing_pool_count * 2 to also account for any new pools getting created before the @@ -2014,13 +1951,6 @@ pub mod migrations { ::DbWeight, >, clear_judgement_proxies::Migration, - // Migrate from legacy lease to coretime. Needs to run after configuration v11 - coretime_migration::MigrateToCoretime< - Runtime, - crate::xcm_config::XcmRouter, - GetLegacyLeaseImpl, - >, - CancelAuctions, // Migrate NominationPools to `DelegateStake` adapter. pallet_nomination_pools::migration::unversioned::DelegationStakeMigration< Runtime,