From 1266de3919dcc9b100c80752ad0158e26ff0fabb Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Mon, 4 Dec 2023 13:16:20 +0100 Subject: [PATCH] Cleanup XCMP `QueueConfigData` (#2142) Removes obsolete fields from the `QueueConfigData` structure. For the remaining fields, if they use the old defaults, we replace them with the new defaults. Resolves: https://github.com/paritytech/polkadot-sdk/issues/1795 --- cumulus/pallets/xcmp-queue/src/lib.rs | 24 +- cumulus/pallets/xcmp-queue/src/migration.rs | 381 +++++++++++++----- .../assets/asset-hub-rococo/src/lib.rs | 8 +- .../assets/asset-hub-westend/src/lib.rs | 2 + .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 1 + .../bridge-hubs/bridge-hub-westend/src/lib.rs | 2 + .../collectives-westend/src/lib.rs | 2 + .../contracts/contracts-rococo/src/lib.rs | 4 +- prdoc/pr_2142.prdoc | 14 + 9 files changed, 308 insertions(+), 130 deletions(-) create mode 100644 prdoc/pr_2142.prdoc diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs index d687f83d8b3e..d3443163d086 100644 --- a/cumulus/pallets/xcmp-queue/src/lib.rs +++ b/cumulus/pallets/xcmp-queue/src/lib.rs @@ -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; @@ -255,7 +255,7 @@ pub mod pallet { return meter.consumed() } - migration::lazy_migrate_inbound_queue::(); + migration::v3::lazy_migrate_inbound_queue::(); meter.consumed() } @@ -387,36 +387,16 @@ 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 { fn default() -> Self { // NOTE that these default values are only used on genesis. They should give a rough idea of // what to set these values to, but is in no way a requirement. - #![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, - ), } } } diff --git a/cumulus/pallets/xcmp-queue/src/migration.rs b/cumulus/pallets/xcmp-queue/src/migration.rs index 6d7f434b041a..6c86c3011d23 100644 --- a/cumulus/pallets/xcmp-queue/src/migration.rs +++ b/cumulus/pallets/xcmp-queue/src/migration.rs @@ -16,7 +16,7 @@ //! A module that is responsible for migration of storage. -use crate::{Config, OverweightIndex, Pallet, ParaId, QueueConfig, DEFAULT_POV_SIZE}; +use crate::{Config, OverweightIndex, Pallet, QueueConfig, QueueConfigData, DEFAULT_POV_SIZE}; use cumulus_primitives_core::XcmpMessageFormat; use frame_support::{ pallet_prelude::*, @@ -25,37 +25,17 @@ 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(PhantomData); - -impl OnRuntimeUpgrade for MigrationToV3 { - fn on_runtime_upgrade() -> Weight { - let mut weight = T::DbWeight::get().reads(1); - - if StorageVersion::get::>() == 1 { - weight.saturating_accrue(migrate_to_v2::()); - StorageVersion::new(2).put::>(); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - - if StorageVersion::get::>() == 2 { - weight.saturating_accrue(migrate_to_v3::()); - StorageVersion::new(3).put::>(); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - - weight - } -} - mod v1 { use super::*; use codec::{Decode, Encode}; + #[frame_support::storage_alias] + pub(crate) type QueueConfig = StorageValue, QueueConfigData, ValueQuery>; + #[derive(Encode, Decode, Debug)] pub struct QueueConfigData { pub suspend_threshold: u32, @@ -80,6 +60,84 @@ mod v1 { } } +pub mod v2 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type QueueConfig = StorageValue, 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, + pub threshold_weight: Weight, + pub weight_restrict_decay: Weight, + pub xcmp_max_individual_weight: Weight, + } + + impl Default for QueueConfigData { + fn default() -> Self { + Self { + suspend_threshold: 2, + drop_threshold: 5, + resume_threshold: 1, + 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). + pub struct UncheckedMigrationToV2(PhantomData); + + impl OnRuntimeUpgrade for UncheckedMigrationToV2 { + #[allow(deprecated)] + fn on_runtime_upgrade() -> 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::::translate(|pre| pre.map(translate)).is_err() { + log::error!( + target: crate::LOG_TARGET, + "unexpected error when performing translation of the QueueConfig type \ + during storage upgrade to v2" + ); + } + + T::DbWeight::get().reads_writes(1, 1) + } + } + + /// [`UncheckedMigrationToV2`] wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the + /// migration is only performed when on-chain version is 1. + #[allow(dead_code)] + pub type MigrationToV2 = frame_support::migrations::VersionedMigration< + 1, + 2, + UncheckedMigrationToV2, + Pallet, + ::DbWeight, + >; +} + pub mod v3 { use super::*; use crate::*; @@ -101,6 +159,10 @@ pub mod v3 { OptionQuery, >; + #[frame_support::storage_alias] + pub(crate) type QueueConfig = + StorageValue, 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. @@ -121,98 +183,135 @@ pub mod v3 { Ok, Suspended, } -} -/// 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() -> 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, - ), - } - }; + /// Migrates the pallet storage to v3. + pub struct UncheckedMigrationToV3(PhantomData); - if QueueConfig::::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" - ); + impl OnRuntimeUpgrade for UncheckedMigrationToV3 { + fn on_runtime_upgrade() -> Weight { + #[frame_support::storage_alias] + type Overweight = + CountedStorageMap, Twox64Concat, OverweightIndex, ParaId>; + let overweight_messages = Overweight::::initialize_counter() as u64; + + T::DbWeight::get().reads_writes(overweight_messages, 1) + } } - T::DbWeight::get().reads_writes(1, 1) -} + /// [`UncheckedMigrationToV3`] wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the + /// migration is only performed when on-chain version is 2. + pub type MigrationToV3 = frame_support::migrations::VersionedMigration< + 2, + 3, + UncheckedMigrationToV3, + Pallet, + ::DbWeight, + >; -pub fn migrate_to_v3() -> Weight { - #[frame_support::storage_alias] - type Overweight = - CountedStorageMap, Twox64Concat, OverweightIndex, ParaId>; - let overweight_messages = Overweight::::initialize_counter() as u64; + pub fn lazy_migrate_inbound_queue() { + let Some(mut states) = v3::InboundXcmpStatus::::get() else { + log::debug!(target: LOG, "Lazy migration finished: item gone"); + return + }; + let Some(ref mut next) = states.first_mut() else { + log::debug!(target: LOG, "Lazy migration finished: item empty"); + v3::InboundXcmpStatus::::kill(); + return + }; + log::debug!( + "Migrating inbound HRMP channel with sibling {:?}, msgs left {}.", + next.sender, + next.message_metadata.len() + ); + // We take the last element since the MQ is a FIFO and we want to keep the order. + let Some((block_number, format)) = next.message_metadata.pop() else { + states.remove(0); + v3::InboundXcmpStatus::::put(states); + return + }; + if format != XcmpMessageFormat::ConcatenatedVersionedXcm { + log::warn!(target: LOG, + "Dropping message with format {:?} (not ConcatenatedVersionedXcm)", + format + ); + v3::InboundXcmpMessages::::remove(&next.sender, &block_number); + v3::InboundXcmpStatus::::put(states); + return + } - T::DbWeight::get().reads_writes(overweight_messages, 1) -} + let Some(msg) = v3::InboundXcmpMessages::::take(&next.sender, &block_number) else { + defensive!("Storage corrupted: HRMP message missing:", (next.sender, block_number)); + v3::InboundXcmpStatus::::put(states); + return + }; -pub fn lazy_migrate_inbound_queue() { - let Some(mut states) = v3::InboundXcmpStatus::::get() else { - log::debug!(target: LOG, "Lazy migration finished: item gone"); - return - }; - let Some(ref mut next) = states.first_mut() else { - log::debug!(target: LOG, "Lazy migration finished: item empty"); - v3::InboundXcmpStatus::::kill(); - return - }; - log::debug!( - "Migrating inbound HRMP channel with sibling {:?}, msgs left {}.", - next.sender, - next.message_metadata.len() - ); - // We take the last element since the MQ is a FIFO and we want to keep the order. - let Some((block_number, format)) = next.message_metadata.pop() else { - states.remove(0); - v3::InboundXcmpStatus::::put(states); - return - }; - if format != XcmpMessageFormat::ConcatenatedVersionedXcm { - log::warn!(target: LOG, - "Dropping message with format {:?} (not ConcatenatedVersionedXcm)", - format - ); - v3::InboundXcmpMessages::::remove(&next.sender, &block_number); + let Ok(msg): Result, _> = msg.try_into() else { + log::error!(target: LOG, "Message dropped: too big"); + v3::InboundXcmpStatus::::put(states); + return + }; + + // Finally! We have a proper message. + T::XcmpQueue::enqueue_message(msg.as_bounded_slice(), next.sender); + log::debug!(target: LOG, "Migrated HRMP message to MQ: {:?}", (next.sender, block_number)); v3::InboundXcmpStatus::::put(states); - return } +} - let Some(msg) = v3::InboundXcmpMessages::::take(&next.sender, &block_number) else { - defensive!("Storage corrupted: HRMP message missing:", (next.sender, block_number)); - v3::InboundXcmpStatus::::put(states); - return - }; +pub mod v4 { + use super::*; - let Ok(msg): Result, _> = msg.try_into() else { - log::error!(target: LOG, "Message dropped: too big"); - v3::InboundXcmpStatus::::put(states); - return - }; + /// Migrates `QueueConfigData` to v4, removing deprecated fields and bumping page + /// thresholds to at least the default values. + pub struct UncheckedMigrationToV4(PhantomData); + + impl OnRuntimeUpgrade for UncheckedMigrationToV4 { + fn on_runtime_upgrade() -> Weight { + let translate = |pre: v2::QueueConfigData| -> QueueConfigData { + let pre_default = v2::QueueConfigData::default(); + // If the previous values are the default ones, let's replace them with the new + // default. + if pre.suspend_threshold == pre_default.suspend_threshold && + pre.drop_threshold == pre_default.drop_threshold && + pre.resume_threshold == pre_default.resume_threshold + { + return QueueConfigData::default() + } + + // If the previous values are not the default ones, let's leave them as they are. + QueueConfigData { + suspend_threshold: pre.suspend_threshold, + drop_threshold: pre.drop_threshold, + resume_threshold: pre.resume_threshold, + } + }; + + if QueueConfig::::translate(|pre| pre.map(translate)).is_err() { + log::error!( + target: crate::LOG_TARGET, + "unexpected error when performing translation of the QueueConfig type \ + during storage upgrade to v4" + ); + } - // Finally! We have a proper message. - T::XcmpQueue::enqueue_message(msg.as_bounded_slice(), next.sender); - log::debug!(target: LOG, "Migrated HRMP message to MQ: {:?}", (next.sender, block_number)); - v3::InboundXcmpStatus::::put(states); + T::DbWeight::get().reads_writes(1, 1) + } + } + + /// [`UncheckedMigrationToV4`] wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the + /// migration is only performed when on-chain version is 3. + pub type MigrationToV4 = frame_support::migrations::VersionedMigration< + 3, + 4, + UncheckedMigrationToV4, + Pallet, + ::DbWeight, + >; } -#[cfg(test)] +#[cfg(all(feature = "try-runtime", test))] mod tests { use super::*; use crate::mock::{new_test_ext, Test}; @@ -230,14 +329,20 @@ mod tests { }; new_test_ext().execute_with(|| { + let storage_version = StorageVersion::new(1); + storage_version.put::>(); + frame_support::storage::unhashed::put_raw( &crate::QueueConfig::::hashed_key(), &v1.encode(), ); - migrate_to_v2::(); + let bytes = v2::MigrationToV2::::pre_upgrade(); + assert!(bytes.is_ok()); + v2::MigrationToV2::::on_runtime_upgrade(); + assert!(v2::MigrationToV2::::post_upgrade(bytes.unwrap()).is_ok()); - let v2 = crate::QueueConfig::::get(); + let v2 = v2::QueueConfig::::get(); assert_eq!(v1.suspend_threshold, v2.suspend_threshold); assert_eq!(v1.drop_threshold, v2.drop_threshold); @@ -247,4 +352,70 @@ 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 storage_version = StorageVersion::new(3); + storage_version.put::>(); + + let v2 = v2::QueueConfigData { + drop_threshold: 5, + suspend_threshold: 2, + resume_threshold: 1, + ..Default::default() + }; + + frame_support::storage::unhashed::put_raw( + &crate::QueueConfig::::hashed_key(), + &v2.encode(), + ); + + let bytes = v4::MigrationToV4::::pre_upgrade(); + assert!(bytes.is_ok()); + v4::MigrationToV4::::on_runtime_upgrade(); + assert!(v4::MigrationToV4::::post_upgrade(bytes.unwrap()).is_ok()); + + let v4 = QueueConfig::::get(); + + assert_eq!( + v4, + QueueConfigData { suspend_threshold: 32, drop_threshold: 48, resume_threshold: 8 } + ); + }); + + new_test_ext().execute_with(|| { + let storage_version = StorageVersion::new(3); + storage_version.put::>(); + + let v2 = v2::QueueConfigData { + drop_threshold: 100, + suspend_threshold: 50, + resume_threshold: 40, + ..Default::default() + }; + + frame_support::storage::unhashed::put_raw( + &crate::QueueConfig::::hashed_key(), + &v2.encode(), + ); + + let bytes = v4::MigrationToV4::::pre_upgrade(); + assert!(bytes.is_ok()); + v4::MigrationToV4::::on_runtime_upgrade(); + assert!(v4::MigrationToV4::::post_upgrade(bytes.unwrap()).is_ok()); + + let v4 = QueueConfig::::get(); + + assert_eq!( + v4, + QueueConfigData { + suspend_threshold: 50, + drop_threshold: 100, + resume_threshold: 40 + } + ); + }); + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index c6c9735ecb1e..6b1948e7125b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -954,8 +954,12 @@ pub type SignedExtra = ( pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. -pub type Migrations = - (pallet_collator_selection::migration::v1::MigrateToV1, InitStorageVersions); +pub type Migrations = ( + pallet_collator_selection::migration::v1::MigrateToV1, + InitStorageVersions, + // unreleased + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, +); /// Migration to initialize storage versions for pallets added after genesis. /// diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 4eb3e2471ce5..bd97c1c2ca53 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -941,6 +941,8 @@ pub type Migrations = ( InitStorageVersions, // unreleased DeleteUndecodableStorage, + // unreleased + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, ); /// Asset Hub Westend has some undecodable storage, delete it. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 152e071a26a5..2fcc7121c0c6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -118,6 +118,7 @@ pub type Migrations = ( pallet_collator_selection::migration::v1::MigrateToV1, pallet_multisig::migrations::v1::MigrateToV1, InitStorageVersions, + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, ); /// Migration to initialize storage versions for pallets added after genesis. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 7b8ea1b7734e..121aa5f0e863 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -118,6 +118,8 @@ pub type Migrations = ( pallet_collator_selection::migration::v1::MigrateToV1, pallet_multisig::migrations::v1::MigrateToV1, InitStorageVersions, + // unreleased + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, ); /// Migration to initialize storage versions for pallets added after genesis. diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 1017ac30499b..be82cf32fbb2 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -707,6 +707,8 @@ pub type UncheckedExtrinsic = type Migrations = ( // unreleased pallet_collator_selection::migration::v1::MigrateToV1, + // unreleased + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, ); /// Executive: handles dispatch to the various modules. diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 77bc93fb9684..33c2e26573ec 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -100,9 +100,11 @@ pub type UncheckedExtrinsic = /// Migrations to apply on runtime upgrade. pub type Migrations = ( cumulus_pallet_parachain_system::migration::Migration, - cumulus_pallet_xcmp_queue::migration::MigrationToV3, + cumulus_pallet_xcmp_queue::migration::v2::MigrationToV2, + cumulus_pallet_xcmp_queue::migration::v3::MigrationToV3, pallet_contracts::Migration, // unreleased + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, ); type EventRecord = frame_system::EventRecord< diff --git a/prdoc/pr_2142.prdoc b/prdoc/pr_2142.prdoc new file mode 100644 index 000000000000..ae2ac3db9ddc --- /dev/null +++ b/prdoc/pr_2142.prdoc @@ -0,0 +1,14 @@ +title: Cleanup XCMP `QueueConfigData` + +doc: + - audience: Parachain Dev + description: Removes obsolete fields from the `QueueConfigData` structure. For the remaining fields, if they use the old defaults, we replace them with the new defaults. + +migrations: + runtime: + - pallet: "cumulus_pallet_xcmp_queue" + description: "v4: Removes obsolete fields from the `QueueConfigData` structure. For the remaining fields, if they use the old defaults, we replace them with the new defaults." + +crates: [] + +host_functions: []