diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a71f0ca47..9a352c6103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Core-Fellowship: new `promote_fast` call ([runtimes#381](https://github.com/polkadot-fellows/runtimes/pull/381), [SDK v1.14 #4877](https://github.com/paritytech/polkadot-sdk/pull/4877)). - Pallet ranked collective: max member count per rank ([runtimes#381](https://github.com/polkadot-fellows/runtimes/pull/381), [SDK v1.14 #4807](https://github.com/paritytech/polkadot-sdk/pull/4807)). - Pallet assets: optional auto-increment for the asset ID ([runtimes#381](https://github.com/polkadot-fellows/runtimes/pull/381), [SDK v1.14 #4757](https://github.com/paritytech/polkadot-sdk/pull/4757)). +- Enable Agile Coretime on Polkadot ([polkadot-fellows/runtimes#322](https://github.com/polkadot-fellows/runtimes/pull/322)) +- Enable Elastic Scaling node side feature for Polkadot ([polkadot-fellows/runtimes#322](https://github.com/polkadot-fellows/runtimes/pull/322)) #### From [#322](https://github.com/polkadot-fellows/runtimes/pull/322): diff --git a/relay/polkadot/constants/src/lib.rs b/relay/polkadot/constants/src/lib.rs index 58254291f5..9b490fb8b7 100644 --- a/relay/polkadot/constants/src/lib.rs +++ b/relay/polkadot/constants/src/lib.rs @@ -131,9 +131,22 @@ pub mod system_parachain { pub const BRIDGE_HUB_ID: u32 = 1002; /// People parachain ID. pub const PEOPLE_ID: u32 = 1004; + /// Brokerage parachain ID. + pub const BROKER_ID: u32 = 1005; // System parachains from Polkadot point of view. pub type SystemParachains = IsChildSystemParachain; + + /// Coretime constants + pub mod coretime { + /// Coretime timeslice period in blocks + /// WARNING: This constant is used across chains, so additional care should be taken + /// when changing it. + #[cfg(feature = "fast-runtime")] + pub const TIMESLICE_PERIOD: u32 = 20; + #[cfg(not(feature = "fast-runtime"))] + pub const TIMESLICE_PERIOD: u32 = 80; + } } /// Polkadot Treasury pallet instance. diff --git a/relay/polkadot/src/lib.rs b/relay/polkadot/src/lib.rs index d507c06fd2..4e6ff9103e 100644 --- a/relay/polkadot/src/lib.rs +++ b/relay/polkadot/src/lib.rs @@ -31,10 +31,10 @@ use polkadot_runtime_common::{ }; use runtime_parachains::{ - assigner_parachains as parachains_assigner_parachains, - configuration as parachains_configuration, + assigner_coretime as parachains_assigner_coretime, + assigner_on_demand as parachains_assigner_on_demand, configuration as parachains_configuration, configuration::ActiveConfigHrmpChannelSizeAndCapacityRatio, - disputes as parachains_disputes, + coretime, disputes as parachains_disputes, disputes::slashing as parachains_slashing, dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion, inclusion::{AggregateMessageOrigin, UmpQueueId}, @@ -62,10 +62,10 @@ use frame_support::{ parameter_types, traits::{ fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut, - Get, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, - ProcessMessageError, WithdrawReasons, + Get, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, OnRuntimeUpgrade, + PrivilegeCmp, ProcessMessage, ProcessMessageError, WithdrawReasons, }, - weights::{ConstantMultiplier, WeightMeter}, + weights::{constants, ConstantMultiplier, WeightMeter}, PalletId, }; use frame_system::EnsureRoot; @@ -87,8 +87,9 @@ use sp_runtime::{ curve::PiecewiseLinear, generic, impl_opaque_keys, traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, - IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Verify, + AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, + Extrinsic as ExtrinsicT, IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, + Verify, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug, @@ -119,7 +120,9 @@ pub use pallet_timestamp::Call as TimestampCall; pub use sp_runtime::BuildStorage; /// Constant values used within the runtime. -use polkadot_runtime_constants::{currency::*, fee::*, time::*, TREASURY_PALLET_ID}; +use polkadot_runtime_constants::{ + currency::*, fee::*, system_parachain, time::*, TREASURY_PALLET_ID, +}; // Weights used in the runtime. mod weights; @@ -1374,16 +1377,63 @@ impl parachains_paras_inherent::Config for Runtime { } impl parachains_scheduler::Config for Runtime { - type AssignmentProvider = ParaAssignmentProvider; + // If you change this, make sure the `Assignment` type of the new provider is binary compatible, + // otherwise provide a migration. + type AssignmentProvider = CoretimeAssignmentProvider; +} + +parameter_types! { + pub const BrokerId: u32 = system_parachain::BROKER_ID; + pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); + pub MaxXcmTransactWeight: Weight = Weight::from_parts(constants::WEIGHT_REF_TIME_PER_MILLIS, 20 * constants::WEIGHT_PROOF_SIZE_PER_KB); +} + +pub struct BrokerPot; +impl Get for BrokerPot { + fn get() -> InteriorLocation { + Junction::AccountId32 { network: None, id: BrokerPalletId::get().into_account_truncating() } + .into() + } +} + +impl coretime::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type BrokerId = BrokerId; + type WeightInfo = weights::runtime_parachains_coretime::WeightInfo; + type SendXcm = crate::xcm_config::XcmRouter; + type MaxXcmTransactWeight = MaxXcmTransactWeight; + type BrokerPotLocation = BrokerPot; + type AssetTransactor = crate::xcm_config::LocalAssetTransactor; + type AccountToLocation = xcm_builder::AliasesIntoAccountId32< + xcm_config::ThisNetwork, + ::AccountId, + >; +} + +parameter_types! { + pub const OnDemandTrafficDefaultValue: FixedU128 = FixedU128::from_u32(1); + pub const MaxHistoricalRevenue: BlockNumber = 2 * system_parachain::coretime::TIMESLICE_PERIOD; + pub const OnDemandPalletId: PalletId = PalletId(*b"py/ondmd"); +} + +impl parachains_assigner_on_demand::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type TrafficDefaultValue = OnDemandTrafficDefaultValue; + type WeightInfo = weights::runtime_parachains_assigner_on_demand::WeightInfo; + type MaxHistoricalRevenue = MaxHistoricalRevenue; + type PalletId = OnDemandPalletId; } -impl parachains_assigner_parachains::Config for Runtime {} +impl parachains_assigner_coretime::Config for Runtime {} impl parachains_initializer::Config for Runtime { type Randomness = pallet_babe::RandomnessFromOneEpochAgo; type ForceOrigin = EnsureRoot; type WeightInfo = weights::runtime_parachains_initializer::WeightInfo; - type CoretimeOnNewSession = (); + type CoretimeOnNewSession = Coretime; } impl parachains_disputes::Config for Runtime { @@ -1708,13 +1758,15 @@ construct_runtime! { ParaSessionInfo: parachains_session_info = 61, ParasDisputes: parachains_disputes = 62, ParasSlashing: parachains_slashing = 63, - ParaAssignmentProvider: parachains_assigner_parachains = 64, + OnDemandAssignmentProvider: parachains_assigner_on_demand = 64, + CoretimeAssignmentProvider: parachains_assigner_coretime = 65, // Parachain Onboarding Pallets. Start indices at 70 to leave room. Registrar: paras_registrar = 70, Slots: slots = 71, Auctions: auctions = 72, Crowdloan: crowdloan = 73, + Coretime: coretime = 74, // State trie migration pallet, only temporary. StateTrieMigration: pallet_state_trie_migration = 98, @@ -1780,12 +1832,94 @@ 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::*; parameter_types! { pub const ImOnlinePalletName: &'static str = "ImOnline"; } + 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 + } + // Lease not yet started/or having holes, refund (coretime can't handle this): + if lease.iter().any(Option::is_none) { + if let Err(err) = slots::Pallet::::clear_all_leases( + frame_system::RawOrigin::Root.into(), + para, + ) { + log::error!( + target: "runtime", + "Clearing lease for para: {:?} failed, with error: {:?}", + para, + err + ); + }; + return None + } + let (index, _) = + as Leaser>::lease_period_index(now)?; + Some(index.saturating_add(lease.len() as u32).saturating_mul(LeasePeriod::get())) + } + } + + /// Enable the elastic scaling node side feature. + /// + /// This is required for Coretime to ensure the relay chain processes parachains that are + /// assigned to multiple cores. + pub struct EnableElasticScalingNodeFeature; + impl OnRuntimeUpgrade for EnableElasticScalingNodeFeature { + fn on_runtime_upgrade() -> Weight { + use runtime_parachains::configuration::WeightInfo as _; + let _ = Configuration::set_node_feature(frame_system::RawOrigin::Root.into(), 1, true); + weights::runtime_parachains_configuration::WeightInfo::::set_node_feature() + } + } + + /// 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( + // TODO: Fix this key for Polkadot! + pallet_custom_origins::Origin::AuctionAdmin.into(), + [ + 0x5c, 0x68, 0xbf, 0x0c, 0x2d, 0x11, 0x04, 0x91, 0x6b, 0xa5, 0xa4, 0xde, 0xe6, + 0xb8, 0x14, 0xe8, 0x2b, 0x27, 0x93, 0x78, 0x4c, 0xb6, 0xe7, 0x69, 0x04, 0x00, + 0x1a, 0x59, 0x49, 0xc1, 0x63, 0xb1, + ], + ) { + 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(), + )) + } + } + /// Unreleased migrations. Add new ones here: pub type Unreleased = ( // Remove `im-online` pallet on-chain storage @@ -1796,6 +1930,14 @@ pub mod migrations { parachains_configuration::migration::v12::MigrateToV12, parachains_inclusion::migration::MigrateToV1, pallet_staking::migrations::v15::MigrateV14ToV15, + // Migrate from legacy lease to coretime. Needs to run after configuration v11 + coretime::migration::MigrateToCoretime< + Runtime, + crate::xcm_config::XcmRouter, + GetLegacyLeaseImpl, + >, + EnableElasticScalingNodeFeature, + CancelAuctions, ); /// Migrations/checks that do not need to be versioned and can run on every update. @@ -1836,6 +1978,8 @@ mod benches { [runtime_parachains::initializer, Initializer] [runtime_parachains::paras, Paras] [runtime_parachains::paras_inherent, ParaInherent] + [runtime_parachains::assigner_on_demand, OnDemandAssignmentProvider] + [runtime_parachains::coretime, Coretime] // Substrate [pallet_bags_list, VoterList] [pallet_balances, Balances]