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

Cleanup XCMP QueueConfigData #2142

Merged
merged 18 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
21 changes: 1 addition & 20 deletions cumulus/pallets/xcmp-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use cumulus_primitives_core::{
use frame_support::{
defensive, defensive_assert,
traits::{EnqueueMessage, EnsureOrigin, Get, QueueFootprint, QueuePausedQuery},
weights::{constants::WEIGHT_REF_TIME_PER_MILLIS, Weight, WeightMeter},
weights::{Weight, WeightMeter},
BoundedVec,
};
use pallet_message_queue::OnQueueChanged;
Expand Down Expand Up @@ -387,18 +387,6 @@ pub struct QueueConfigData {
/// The number of pages which the queue must be reduced to before it signals that
/// message sending may recommence after it has been suspended.
resume_threshold: u32,
/// UNUSED - The amount of remaining weight under which we stop processing messages.
#[deprecated(note = "Will be removed")]
threshold_weight: Weight,
/// UNUSED - The speed to which the available weight approaches the maximum weight. A lower
/// number results in a faster progression. A value of 1 makes the entire weight available
/// initially.
#[deprecated(note = "Will be removed")]
weight_restrict_decay: Weight,
/// UNUSED - The maximum amount of weight any individual message may consume. Messages above
/// this weight go into the overweight queue and may only be serviced explicitly.
#[deprecated(note = "Will be removed")]
xcmp_max_individual_weight: Weight,
}

impl Default for QueueConfigData {
Expand All @@ -410,13 +398,6 @@ impl Default for QueueConfigData {
drop_threshold: 48, // 64KiB * 48 = 3MiB
suspend_threshold: 32, // 64KiB * 32 = 2MiB
resume_threshold: 8, // 64KiB * 8 = 512KiB
// unused:
threshold_weight: Weight::from_parts(100_000, 0),
weight_restrict_decay: Weight::from_parts(2, 0),
xcmp_max_individual_weight: Weight::from_parts(
20u64 * WEIGHT_REF_TIME_PER_MILLIS,
DEFAULT_POV_SIZE,
),
}
}
}
Expand Down
210 changes: 174 additions & 36 deletions cumulus/pallets/xcmp-queue/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

//! A module that is responsible for migration of storage.

use crate::{Config, OverweightIndex, Pallet, ParaId, QueueConfig, DEFAULT_POV_SIZE};
use crate::{
Config, OverweightIndex, Pallet, ParaId, QueueConfig, QueueConfigData, DEFAULT_POV_SIZE,
};
use cumulus_primitives_core::XcmpMessageFormat;
use frame_support::{
pallet_prelude::*,
Expand All @@ -25,14 +27,14 @@ use frame_support::{
};

/// The current storage version.
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(4);

pub const LOG: &str = "runtime::xcmp-queue-migration";

/// Migrates the pallet storage to the most recent version.
pub struct MigrationToV3<T: Config>(PhantomData<T>);
pub struct MigrationToV4<T: Config>(PhantomData<T>);
serban300 marked this conversation as resolved.
Show resolved Hide resolved

impl<T: Config> OnRuntimeUpgrade for MigrationToV3<T> {
impl<T: Config> OnRuntimeUpgrade for MigrationToV4<T> {
fn on_runtime_upgrade() -> Weight {
let mut weight = T::DbWeight::get().reads(1);

Expand All @@ -48,6 +50,12 @@ impl<T: Config> OnRuntimeUpgrade for MigrationToV3<T> {
weight.saturating_accrue(T::DbWeight::get().writes(1));
}

if StorageVersion::get::<Pallet<T>>() == 3 {
serban300 marked this conversation as resolved.
Show resolved Hide resolved
weight.saturating_accrue(migrate_to_v4::<T>());
StorageVersion::new(4).put::<Pallet<T>>();
weight.saturating_accrue(T::DbWeight::get().writes(1));
serban300 marked this conversation as resolved.
Show resolved Hide resolved
}

weight
}
}
Expand All @@ -56,6 +64,9 @@ mod v1 {
use super::*;
use codec::{Decode, Encode};

#[frame_support::storage_alias]
pub(crate) type QueueConfig<T: Config> = StorageValue<Pallet<T>, QueueConfigData, ValueQuery>;

#[derive(Encode, Decode, Debug)]
pub struct QueueConfigData {
pub suspend_threshold: u32,
Expand All @@ -80,6 +91,76 @@ mod v1 {
}
}

mod v2 {
use super::*;

#[frame_support::storage_alias]
pub(crate) type QueueConfig<T: Config> = StorageValue<Pallet<T>, QueueConfigData, ValueQuery>;

#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
pub struct QueueConfigData {
pub suspend_threshold: u32,
pub drop_threshold: u32,
pub resume_threshold: u32,
#[deprecated(note = "Will be removed")]
pub threshold_weight: Weight,
#[deprecated(note = "Will be removed")]
pub weight_restrict_decay: Weight,
#[deprecated(note = "Will be removed")]
pub xcmp_max_individual_weight: Weight,
}

impl Default for QueueConfigData {
fn default() -> Self {
#![allow(deprecated)]
Self {
drop_threshold: 48, // 64KiB * 48 = 3MiB
suspend_threshold: 32, // 64KiB * 32 = 2MiB
resume_threshold: 8, // 64KiB * 8 = 512KiB
// unused:
threshold_weight: Weight::from_parts(100_000, 0),
weight_restrict_decay: Weight::from_parts(2, 0),
xcmp_max_individual_weight: Weight::from_parts(
20u64 * WEIGHT_REF_TIME_PER_MILLIS,
DEFAULT_POV_SIZE,
),
}
}
}
}

/// Migrates `QueueConfigData` from v1 (using only reference time weights) to v2 (with
/// 2D weights).
///
/// NOTE: Only use this function if you know what you're doing. Default to using
/// `migrate_to_latest`.
#[allow(deprecated)]
pub fn migrate_to_v2<T: Config>() -> Weight {
let translate = |pre: v1::QueueConfigData| -> v2::QueueConfigData {
v2::QueueConfigData {
suspend_threshold: pre.suspend_threshold,
drop_threshold: pre.drop_threshold,
resume_threshold: pre.resume_threshold,
threshold_weight: Weight::from_parts(pre.threshold_weight, 0),
weight_restrict_decay: Weight::from_parts(pre.weight_restrict_decay, 0),
xcmp_max_individual_weight: Weight::from_parts(
pre.xcmp_max_individual_weight,
DEFAULT_POV_SIZE,
),
}
};

if v2::QueueConfig::<T>::translate(|pre| pre.map(translate)).is_err() {
log::error!(
target: super::LOG_TARGET,
"unexpected error when performing translation of the QueueConfig type \
during storage upgrade to v2"
);
}

T::DbWeight::get().reads_writes(1, 1)
}

pub mod v3 {
use super::*;
use crate::*;
Expand All @@ -101,6 +182,10 @@ pub mod v3 {
OptionQuery,
>;

#[frame_support::storage_alias]
pub(crate) type QueueConfig<T: Config> =
StorageValue<Pallet<T>, v2::QueueConfigData, ValueQuery>;

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)]
pub struct InboundChannelDetails {
/// The `ParaId` of the parachain that this channel is connected with.
Expand All @@ -123,37 +208,6 @@ pub mod v3 {
}
}

/// Migrates `QueueConfigData` from v1 (using only reference time weights) to v2 (with
/// 2D weights).
///
/// NOTE: Only use this function if you know what you're doing. Default to using
/// `migrate_to_latest`.
#[allow(deprecated)]
pub fn migrate_to_v2<T: Config>() -> Weight {
let translate = |pre: v1::QueueConfigData| -> super::QueueConfigData {
super::QueueConfigData {
suspend_threshold: pre.suspend_threshold,
drop_threshold: pre.drop_threshold,
resume_threshold: pre.resume_threshold,
threshold_weight: Weight::from_parts(pre.threshold_weight, 0),
weight_restrict_decay: Weight::from_parts(pre.weight_restrict_decay, 0),
xcmp_max_individual_weight: Weight::from_parts(
pre.xcmp_max_individual_weight,
DEFAULT_POV_SIZE,
),
}
};

if QueueConfig::<T>::translate(|pre| pre.map(translate)).is_err() {
log::error!(
target: super::LOG_TARGET,
"unexpected error when performing translation of the QueueConfig type during storage upgrade to v2"
);
}

T::DbWeight::get().reads_writes(1, 1)
}

pub fn migrate_to_v3<T: Config>() -> Weight {
#[frame_support::storage_alias]
type Overweight<T: Config> =
Expand Down Expand Up @@ -212,6 +266,36 @@ pub fn lazy_migrate_inbound_queue<T: Config>() {
v3::InboundXcmpStatus::<T>::put(states);
}

/// Migrates `QueueConfigData` to v4, removing deprecated fields and bumping page
/// thresholds to at least the default values.
///
/// NOTE: Only use this function if you know what you're doing. Default to using
/// `migrate_to_latest`.
#[allow(deprecated)]
pub fn migrate_to_v4<T: Config>() -> Weight {
let translate = |pre: v2::QueueConfigData| -> QueueConfigData {
use sp_std::cmp::max;

let default = QueueConfigData::default();
let post = QueueConfigData {
suspend_threshold: max(pre.suspend_threshold, default.suspend_threshold),
drop_threshold: max(pre.drop_threshold, default.drop_threshold),
resume_threshold: max(pre.resume_threshold, default.resume_threshold),
};
post
};

if QueueConfig::<T>::translate(|pre| pre.map(translate)).is_err() {
log::error!(
target: super::LOG_TARGET,
"unexpected error when performing translation of the QueueConfig type \
during storage upgrade to v4"
);
}

T::DbWeight::get().reads_writes(1, 1)
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -237,7 +321,7 @@ mod tests {

migrate_to_v2::<Test>();

let v2 = crate::QueueConfig::<Test>::get();
let v2 = v2::QueueConfig::<Test>::get();

assert_eq!(v1.suspend_threshold, v2.suspend_threshold);
assert_eq!(v1.drop_threshold, v2.drop_threshold);
Expand All @@ -247,4 +331,58 @@ mod tests {
assert_eq!(v1.xcmp_max_individual_weight, v2.xcmp_max_individual_weight.ref_time());
});
}

#[test]
#[allow(deprecated)]
fn test_migration_to_v4() {
new_test_ext().execute_with(|| {
let v2 = v2::QueueConfigData {
drop_threshold: 5,
suspend_threshold: 2,
resume_threshold: 1,
..Default::default()
};

frame_support::storage::unhashed::put_raw(
&crate::QueueConfig::<Test>::hashed_key(),
&v2.encode(),
);

migrate_to_v4::<Test>();

let v4 = QueueConfig::<Test>::get();

assert_eq!(
v4,
QueueConfigData { suspend_threshold: 32, drop_threshold: 48, resume_threshold: 8 }
);
});

new_test_ext().execute_with(|| {
let v2 = v2::QueueConfigData {
drop_threshold: 100,
suspend_threshold: 50,
resume_threshold: 40,
..Default::default()
};

frame_support::storage::unhashed::put_raw(
&crate::QueueConfig::<Test>::hashed_key(),
&v2.encode(),
);

migrate_to_v4::<Test>();

let v4 = QueueConfig::<Test>::get();

assert_eq!(
v4,
QueueConfigData {
suspend_threshold: 50,
drop_threshold: 100,
resume_threshold: 40
}
);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ pub type Migrations = (
pallet_multisig::migrations::v1::MigrateToV1<Runtime>,
// unreleased
InitStorageVersions,
cumulus_pallet_xcmp_queue::migration::MigrationToV4<Runtime>,
);

/// Migration to initialize storage versions for pallets added after genesis.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub type Migrations = (
pallet_collator_selection::migration::v1::MigrateToV1<Runtime>,
pallet_multisig::migrations::v1::MigrateToV1<Runtime>,
InitStorageVersions,
cumulus_pallet_xcmp_queue::migration::MigrationToV4<Runtime>,
);

/// Migration to initialize storage versions for pallets added after genesis.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub type UncheckedExtrinsic =
/// Migrations to apply on runtime upgrade.
pub type Migrations = (
cumulus_pallet_parachain_system::migration::Migration<Runtime>,
cumulus_pallet_xcmp_queue::migration::MigrationToV3<Runtime>,
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
cumulus_pallet_xcmp_queue::migration::MigrationToV4<Runtime>,
pallet_contracts::Migration<Runtime>,
// unreleased
);
Expand Down
Loading