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 6 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))

## [1.2.1] 09.04.2024

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
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_001,
seadanda marked this conversation as resolved.
Show resolved Hide resolved
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 0,
Expand Down
232 changes: 232 additions & 0 deletions system-parachains/coretime/coretime-kusama/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
// 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};
use pallet_broker::WeightInfo;
#[cfg(feature = "try-runtime")]
use pallet_broker::{
AllowedRenewalId, AllowedRenewalRecord, AllowedRenewals, Configuration,
CoreAssignment::{Pool, Task},
CoreMask, LeaseRecordItem, Leases, SaleInfo, SaleInfoRecordOf, Schedule, ScheduleItem,
Workplan,
};
#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;
#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;

/// The log target.
const TARGET: &'static 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>::get().len() > 0 {
seadanda marked this conversation as resolved.
Show resolved Hide resolved
// 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
match pallet_broker::Pallet::<Runtime>::request_core_count(RuntimeOrigin::root(), 55) {
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_0000,
seadanda marked this conversation as resolved.
Show resolved Hide resolved
seadanda marked this conversation as resolved.
Show resolved Hide resolved
55,
) {
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> {
let sale_info = SaleInfo::<Runtime>::get().unwrap();
seadanda marked this conversation as resolved.
Show resolved Hide resolved
Ok(sale_info.encode())
}

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

// Idempotency hack - sorry. This just checks that the migration has run in the correct
// sale period, because the following checks only matter in that case. A bit of a "trust
// me bro", but this is the first sale for coretime-kusama.
if prev_sale_info.sale_start != 104193 {
log::info!(target: TARGET, "Idempotency hack has filtered checks for this run.");
return Ok(());
}
seadanda marked this conversation as resolved.
Show resolved Hide resolved

log::info!(target: TARGET, "Idempotency hack has not affected us for this run.");

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(), 35);
seadanda marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert_eq!(leases.len(), 35);
assert_eq!(leases.len(), LEASES.iter().filter(|(_, l)| sale_info.region_length * Timeslice::get() > l).count());

This should achieve the same?


// 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_0000,
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));
}

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