Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[coretime-kusama] Bump broker and add migration to import leases to fix launch issues #276

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/runtimes-matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"name": "coretime-kusama",
"package": "coretime-kusama-runtime",
"path": "system-parachains/coretime/coretime-kusama",
"uri": "wss://kusama-coretime-rpc.polkadot.io:443",
"is_relay": false
},
{
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]

- Add `pallet-vesting` to Asset Hubs ([polkadot-fellows/runtimes#269](https://github.com/polkadot-fellows/runtimes/pull/269))
- Fix Kusama Coretime launch issues: import leases and fix renewals for short leases ([polkadot-fellows/runtimes#276](https://github.com/polkadot-fellows/runtimes/pull/276))

### Fixed

Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pallet-bridge-grandpa = { version = "0.8.0", default-features = false }
pallet-bridge-messages = { version = "0.8.0", default-features = false }
pallet-bridge-parachains = { version = "0.8.0", default-features = false }
pallet-bridge-relayers = { version = "0.8.0", default-features = false }
pallet-broker = { version = "0.7.0", default-features = false }
pallet-broker = { version = "0.7.1", default-features = false }
pallet-child-bounties = { version = "28.0.0", default-features = false }
pallet-collator-selection = { version = "10.0.0", default-features = false }
pallet-collective = { version = "29.0.0", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion relay/kusama/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ kusama-runtime-constants = { package = "kusama-runtime-constants", path = "const
sp-api = { workspace = true }
inherents = { package = "sp-inherents", default-features = false , version = "27.0.0" }
offchain-primitives = { package = "sp-offchain", default-features = false , version = "27.0.0" }
sp-std = { package = "sp-std", workspace = true }
sp-std = { workspace = true }
sp-application-crypto = { workspace = true }
sp-arithmetic = { workspace = true }
sp-genesis-builder = { workspace = true }
Expand Down
8 changes: 6 additions & 2 deletions system-parachains/coretime/coretime-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

mod coretime;
mod migrations;
#[cfg(test)]
mod tests;
mod weights;
Expand Down Expand Up @@ -106,7 +107,10 @@ pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;

/// Migrations to apply on runtime upgrade.
pub type Migrations = (pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,);
pub type Migrations = (
pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
migrations::bootstrapping::ImportLeases,
);

/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
Expand All @@ -129,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("coretime-kusama"),
impl_name: create_runtime_str!("coretime-kusama"),
authoring_version: 1,
spec_version: 1_002_000,
spec_version: 1_002_002,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 0,
Expand Down
253 changes: 253 additions & 0 deletions system-parachains/coretime/coretime-kusama/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
// 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 XCM Transact which was meant to set the leases as part of the Kusama relay runtime upgrade
/// did not have enough weight. Therefore the leases were not migrated.
///
/// This migration populates the leases and restarts the sale from whichever timeslice it runs.
///
/// This does not 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::{
AllowedRenewalId, AllowedRenewalRecord, AllowedRenewals, Configuration,
CoreAssignment::{Pool, Task},
CoreMask, LeaseRecordItem, SaleInfo, SaleInfoRecordOf, Schedule, ScheduleItem, Workplan,
};
use pallet_broker::{Leases, WeightInfo};
#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;
#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;

/// The log target.
const TARGET: &str = "runtime::bootstrapping::import-leases";

// Alias into the broker weights for this runtime.
type BrokerWeights = weights::pallet_broker::WeightInfo<Runtime>;

pub struct ImportLeases;

impl OnRuntimeUpgrade for ImportLeases {
fn on_runtime_upgrade() -> Weight {
// This migration contains hardcoded values only relevant to Kusama Coretime
// 1002000 before it has any leases. These checks could be tightened.
if Leases::<Runtime>::decode_len().unwrap_or(0) > 0 {
// Already has leases, bail
log::error!(target: TARGET, "This migration includes hardcoded values not relevant to this runtime. Bailing.");
return <Runtime as frame_system::Config>::DbWeight::get().reads(1);
}

for (para_id, end) in LEASES {
match pallet_broker::Pallet::<Runtime>::set_lease(
RuntimeOrigin::root(),
para_id,
end,
) {
Ok(_) =>
log::info!(target: TARGET, "Importing lease for parachain {}", &para_id),
Err(_) =>
log::error!(target: TARGET, "Importing lease for parachain {} failed!", &para_id),
}
}

// The values used in referendum 375 included 52 cores. Replaying this here shifts the
// start of the sale, while crucially populating the workplan with the leases and
// recalculating the number of cores to be offered. However, there are 4 system
// parachains + 1 pool core + 47 leases + 3 cores for the open market, therefore we need
// to start sales with 55 cores.
seadanda marked this conversation as resolved.
Show resolved Hide resolved
let core_count = pallet_broker::Reservations::<Runtime>::decode_len().unwrap_or(0)
as u16 + pallet_broker::Leases::<Runtime>::decode_len().unwrap_or(0)
as u16 + 3;

match pallet_broker::Pallet::<Runtime>::request_core_count(
RuntimeOrigin::root(),
core_count,
) {
Ok(_) => log::info!(target: TARGET, "Request for 55 cores sent."),
Err(_) => log::error!(target: TARGET, "Request for 55 cores failed to send."),
}
match pallet_broker::Pallet::<Runtime>::start_sales(
RuntimeOrigin::root(),
5_000_000_000_000,
core_count,
) {
Ok(_) => log::info!(target: TARGET, "Sales started"),
Err(_) => log::error!(target: TARGET, "Start sales failed!"),
}

// Weight for setting every lease and starting the sales, plus one read for leases
// check.
BrokerWeights::set_lease()
.saturating_mul(LEASES.len() as u64)
.saturating_add(BrokerWeights::request_core_count(55))
.saturating_add(BrokerWeights::start_sales(55))
.saturating_add(<Runtime as frame_system::Config>::DbWeight::get().reads(1))
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
if Leases::<Runtime>::decode_len().unwrap_or(0) > 0 {
return Ok(Vec::new())
}
let sale_info = SaleInfo::<Runtime>::get().unwrap();
Ok(sale_info.encode())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(state: Vec<u8>) -> Result<(), TryRuntimeError> {
if state.is_empty() {
return Ok(())
}
let prev_sale_info = <SaleInfoRecordOf<Runtime>>::decode(&mut &state[..]).unwrap();

log::info!(target: TARGET, "Checking migration.");

let sale_info = SaleInfo::<Runtime>::get().unwrap();
let now = frame_system::Pallet::<Runtime>::block_number();
let config = Configuration::<Runtime>::get().unwrap();

// Check the sale start has changed as expected and the cores_offered is the correct
// number.
assert_eq!(sale_info.sale_start, now + config.interlude_length);
assert!(sale_info.region_begin > prev_sale_info.region_begin);
assert_eq!(sale_info.cores_offered, 3);

// The workplan entries start from the region begin reported by the new SaleInfo.
let workplan_start = sale_info.region_begin;

// Check the reservations are still in the workplan out of an abundance of caution.
for (core_id, task) in
[Task(1000), Task(1001), Task(1002), Task(1005), Pool].into_iter().enumerate()
{
assert_eq!(
Workplan::<Runtime>::get((workplan_start, core_id as u16)),
Some(Schedule::truncate_from(Vec::from([ScheduleItem {
mask: CoreMask::complete(),
assignment: task,
}])))
);
}

// Because we also run start_sales, 12 expiring leases are removed from the original 47,
// leaving 35.
let leases = Leases::<Runtime>::get();
assert_eq!(
leases.len(),
LEASES.iter().filter(|(_, l)| sale_info.region_end <= *l).count()
);

// Iterate through hardcoded leases and check they're all correctly in state (leases or
// allowedrenewals) and scheduled in the workplan.
for (i, (para_id, until)) in LEASES.iter().enumerate() {
// Add the system parachains and pool core as an offset - these should come before
// the leases.
let core_id = i as u16 + 5;
// This is the entry found in Workplan and AllowedRenewal
let workload = Schedule::truncate_from(Vec::from([ScheduleItem {
mask: CoreMask::complete(),
assignment: Task(*para_id),
}]));

// Check that the 12 who no longer have a lease can renew.
if !leases.contains(&LeaseRecordItem { until: *until, task: *para_id }) {
assert_eq!(
AllowedRenewals::<Runtime>::get(AllowedRenewalId {
core: core_id,
when: sale_info.region_end,
}),
Some(AllowedRenewalRecord {
price: 5_000_000_000_000,
completion: pallet_broker::CompletionStatus::Complete(workload.clone())
})
);
}
// They should all be in the workplan for next sale.
assert_eq!(Workplan::<Runtime>::get((workplan_start, core_id)), Some(workload));
}

// Ensure we have requested the correct number of events.
assert!(frame_system::Pallet::<Runtime>::read_events_no_consensus().any(|e| {
match e.event {
crate::RuntimeEvent::Broker(
pallet_broker::Event::<Runtime>::CoreCountRequested { core_count },
) => {
log::info!("{core_count:?}");

core_count == 55
},
_ => false,
}
}));

Ok(())
}
}

// Hardcoded para ids and their end timeslice.
// Calculated using https://github.com/seadanda/coretime-scripts/blob/main/get_leases.py
seadanda marked this conversation as resolved.
Show resolved Hide resolved
const LEASES: [(u32, u32); 47] = [
(2000, 340200),
(2001, 302400),
(2004, 332640),
(2007, 317520),
(2011, 325080),
(2012, 309960),
(2015, 287280),
(2023, 309960),
(2024, 309960),
(2048, 302400),
(2084, 340200),
(2085, 294840),
(2087, 340200),
(2088, 287280),
(2090, 340200),
(2092, 287280),
(2095, 332640),
(2096, 332640),
(2105, 325080),
(2106, 325080),
(2110, 317520),
(2113, 332640),
(2114, 317520),
(2119, 340200),
(2121, 332640),
(2123, 294840),
(2124, 287280),
(2125, 294840),
(2222, 302400),
(2233, 294840),
(2236, 317520),
(2239, 332640),
(2241, 325080),
(2274, 294840),
(2275, 294840),
(2281, 302400),
(3334, 309960),
(3336, 317520),
(3338, 317520),
(3339, 325080),
(3340, 325080),
(3343, 317520),
(3344, 340200),
(3345, 325080),
(3347, 287280),
(3348, 287280),
(3350, 340200),
];
}
Loading