diff --git a/pallets/transaction-storage/README.md b/pallets/transaction-storage/README.md index 0ed3ba279..b2b22fe44 100644 --- a/pallets/transaction-storage/README.md +++ b/pallets/transaction-storage/README.md @@ -2,8 +2,8 @@ Indexes transactions and manages storage proofs. -Allows storing arbitrary data on the chain. Data is automatically removed after `StoragePeriod` blocks, unless the storage is renewed. -Validators must submit proof of storing a random chunk of data for block `N - StoragePeriod` when producing block `N`. +Allows storing arbitrary data on the chain. Data is automatically removed after `RetentionPeriod` blocks, unless the storage is renewed. +Validators must submit proof of storing a random chunk of data for block `N - RetentionPeriod` when producing block `N`. # Running a chain @@ -16,7 +16,7 @@ cargo run --release -- build-spec --chain=local > sc_init.json ``` Edit the json chain spec file to customise the chain. The storage chain genesis params are configured in the `transactionStorage` section. -Note that `storagePeriod` is specified in blocks and changing it also requires code changes at the moment. +Note that `retentionPeriod` is specified in blocks and changing it also requires code changes at the moment. Build a raw spec from the init spec. @@ -32,7 +32,7 @@ cargo run --release -- --chain=sc.json -d /tmp/bob --storage-chain --keep-blocks ``` `--storage-chain` enables transaction indexing. -`--keep-blocks=100800` enables block pruning. The value here should be greater or equal than the storage period. +`--keep-blocks=100800` enables block pruning. The value here should be greater or equal than the retention period. `--ipfs-server` enables serving stored content over IPFS. Once the network is started, any other joining nodes need to sync with `--sync=fast`. Regular sync will fail because block pruning removes old blocks. The chain does not keep full block history. @@ -75,7 +75,7 @@ ipfs swarm connect ipfs block get /ipfs/ > kitten.jpeg ``` -To renew data and prevent it from being disposed after the storage period, use `transactionStorage.renew(block, index)` +To renew data and prevent it from being disposed after the retention period, use `transactionStorage.renew(block, index)` where `block` is the block number of the previous store or renew transction, and index is the index of that transaction in the block. diff --git a/pallets/transaction-storage/src/benchmarking.rs b/pallets/transaction-storage/src/benchmarking.rs index b276598ec..bcad7d936 100644 --- a/pallets/transaction-storage/src/benchmarking.rs +++ b/pallets/transaction-storage/src/benchmarking.rs @@ -157,7 +157,7 @@ mod benchmarks { vec![0u8; T::MaxTransactionSize::get() as usize], )?; } - run_to_block::(T::StoragePeriod::get() + BlockNumberFor::::one()); + run_to_block::(crate::Pallet::::retention_period() + BlockNumberFor::::one()); let encoded_proof = proof(); let proof = TransactionStorageProof::decode(&mut &*encoded_proof).unwrap(); diff --git a/pallets/transaction-storage/src/lib.rs b/pallets/transaction-storage/src/lib.rs index 420828c0b..a641aed72 100644 --- a/pallets/transaction-storage/src/lib.rs +++ b/pallets/transaction-storage/src/lib.rs @@ -24,19 +24,26 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + mod benchmarking; pub mod weights; +pub mod migrations; #[cfg(test)] mod mock; #[cfg(test)] mod tests; use codec::{Decode, Encode, MaxEncodedLen}; +use core::fmt::Debug; use polkadot_sdk_frame::{ deps::{sp_core::sp_std::prelude::*, *}, prelude::*, - traits::fungible::{Balanced, Credit, Inspect, Mutate, MutateHold}, + traits::{ + fungible::{Balanced, Credit, Inspect, Mutate, MutateHold}, + parameter_types, + }, }; use sp_transaction_storage_proof::{ encode_index, num_chunks, random_chunk, ChunkIndex, InherentError, TransactionStorageProof, @@ -54,12 +61,16 @@ pub use weights::WeightInfo; const LOG_TARGET: &str = "runtime::transaction-storage"; +/// Default retention period for data (in blocks). +pub const DEFAULT_RETENTION_PERIOD: u32 = 100800; +parameter_types! { + pub const DefaultRetentionPeriod: u32 = DEFAULT_RETENTION_PERIOD; +} + +// TODO: https://github.com/paritytech/polkadot-bulletin-chain/issues/139 - Clarify purpose of allocator limits and decide whether to remove or use these constants. /// Maximum bytes that can be stored in one transaction. -// TODO: find out what is "allocator" and "allocator limit" // Setting higher limit also requires raising the allocator limit. -// TODO: not used, can we remove or use? pub const DEFAULT_MAX_TRANSACTION_SIZE: u32 = 8 * 1024 * 1024; -// TODO: not used, can we remove or use? pub const DEFAULT_MAX_BLOCK_TRANSACTIONS: u32 = 512; /// Encountered an impossible situation, implies a bug. @@ -74,7 +85,7 @@ pub const AUTHORIZATION_NOT_FOUND: InvalidTransaction = InvalidTransaction::Cust pub const AUTHORIZATION_NOT_EXPIRED: InvalidTransaction = InvalidTransaction::Custom(4); /// Number of transactions and bytes covered by an authorization. -#[derive(PartialEq, Eq, RuntimeDebug, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] +#[derive(PartialEq, Eq, Debug, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] pub struct AuthorizationExtent { /// Number of transactions. pub transactions: u32, @@ -108,9 +119,7 @@ struct Authorization { type AuthorizationFor = Authorization>; /// State data for a stored transaction. -#[derive( - Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq, scale_info::TypeInfo, MaxEncodedLen, -)] +#[derive(Encode, Decode, Clone, Debug, PartialEq, Eq, scale_info::TypeInfo, MaxEncodedLen)] pub struct TransactionInfo { /// Chunk trie root. chunk_root: ::Output, @@ -122,7 +131,7 @@ pub struct TransactionInfo { /// is used to find transaction info by block chunk index using binary search. /// /// Cumulative value of all previous transactions in the block; the last transaction holds the - /// total chunk value. + /// total chunks. block_chunks: ChunkIndex, } @@ -194,11 +203,6 @@ pub mod pallet { /// Maximum data set in a single transaction in bytes. #[pallet::constant] type MaxTransactionSize: Get; - /// Storage period for data in blocks. Should match - /// [`DEFAULT_STORAGE_PERIOD`](sp_transaction_storage_proof::DEFAULT_STORAGE_PERIOD) for - /// block authoring. - #[pallet::constant] - type StoragePeriod: Get>; /// Authorizations expire after this many blocks. #[pallet::constant] type AuthorizationPeriod: Get>; @@ -258,13 +262,14 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(n: BlockNumberFor) -> Weight { + // TODO: https://github.com/paritytech/polkadot-sdk/issues/10203 - Replace this with benchmarked weights. let mut weight = Weight::zero(); let db_weight = T::DbWeight::get(); // Drop obsolete roots. The proof for `obsolete` will be checked later // in this block, so we drop `obsolete` - 1. weight.saturating_accrue(db_weight.reads(1)); - let period = T::StoragePeriod::get(); + let period = Self::retention_period(); let obsolete = n.saturating_sub(period.saturating_add(One::one())); if obsolete > Zero::zero() { weight.saturating_accrue(db_weight.writes(2)); @@ -282,7 +287,7 @@ pub mod pallet { >::take() || { // Proof is not required for early or empty blocks. let number = >::block_number(); - let period = T::StoragePeriod::get(); + let period = Self::retention_period(); let target_number = number.saturating_sub(period); target_number.is_zero() || { @@ -294,7 +299,7 @@ pub mod pallet { "Storage proof must be checked once in the block" ); - // Insert new transactions + // Insert new transactions, iff they have chunks. let transactions = >::take(); let total_chunks = transactions.last().map_or(0, |t| t.block_chunks); if total_chunks != 0 { @@ -305,22 +310,30 @@ pub mod pallet { fn integrity_test() { assert!( !T::MaxBlockTransactions::get().is_zero(), - "Not useful if data cannot be stored" + "MaxTransactionSize must be greater than zero" + ); + assert!( + !T::MaxTransactionSize::get().is_zero(), + "MaxTransactionSize must be greater than zero" + ); + let default_period = DEFAULT_RETENTION_PERIOD.into(); + let retention_period = GenesisConfig::::default().retention_period; + assert_eq!( + retention_period, default_period, + "GenesisConfig.retention_period must match DEFAULT_RETENTION_PERIOD" ); - assert!(!T::MaxTransactionSize::get().is_zero(), "Not useful if data cannot be stored"); - assert!(!T::StoragePeriod::get().is_zero(), "Not useful if data is not stored"); assert!( !T::AuthorizationPeriod::get().is_zero(), - "Not useful if authorizations are never valid" + "AuthorizationPeriod must be greater than zero" ); } } #[pallet::call] impl Pallet { - /// Index and store data off chain. Minimum data size is 1 bytes, maximum is - /// `MaxTransactionSize`. Data will be removed after `StoragePeriod` blocks, unless `renew` - /// is called. + /// Index and store data off chain. Minimum data size is 1 byte, maximum is + /// `MaxTransactionSize`. Data will be removed after `RetentionPeriod` blocks, unless + /// `renew` is called. /// /// Authorization is required to store data using regular signed/unsigned transactions. /// Regular signed transactions require account authorization (see @@ -346,9 +359,9 @@ pub mod pallet { debug_assert_eq!(chunk_count, num_chunks(data.len() as u32) as usize); let root = sp_io::trie::blake2_256_ordered_root(chunks, sp_runtime::StateVersion::V1); + let content_hash = sp_io::hashing::blake2_256(&data); let extrinsic_index = >::extrinsic_index().ok_or(Error::::BadContext)?; - let content_hash = sp_io::hashing::blake2_256(&data); sp_io::transaction_index::index(extrinsic_index, data.len() as u32, content_hash); let mut index = 0; @@ -418,7 +431,7 @@ pub mod pallet { Ok(().into()) } - /// Check storage proof for block number `block_number() - StoragePeriod`. If such a block + /// Check storage proof for block number `block_number() - RetentionPeriod`. If such a block /// does not exist, the proof is expected to be `None`. /// /// ## Complexity @@ -436,7 +449,7 @@ pub mod pallet { // Get the target block metadata. let number = >::block_number(); - let period = T::StoragePeriod::get(); + let period = Self::retention_period(); let target_number = number.saturating_sub(period); ensure!(!target_number.is_zero(), Error::::UnexpectedProof); let transactions = @@ -639,6 +652,14 @@ pub mod pallet { /// Storage fee per transaction. pub type EntryFee = StorageValue<_, BalanceOf>; + /// Number of blocks for which stored data must be retained. + /// + /// Data older than `RetentionPeriod` blocks is eligible for removal unless it + /// has been explicitly renewed. Validators are required to prove possession of + /// data corresponding to block `N - RetentionPeriod` when producing block `N`. + #[pallet::storage] + pub type RetentionPeriod = StorageValue<_, BlockNumberFor, ValueQuery>; + // Intermediates #[pallet::storage] pub(super) type BlockTransactions = @@ -648,6 +669,32 @@ pub mod pallet { #[pallet::storage] pub(super) type ProofChecked = StorageValue<_, bool, ValueQuery>; + #[pallet::genesis_config] + pub struct GenesisConfig { + pub byte_fee: BalanceOf, + pub entry_fee: BalanceOf, + pub retention_period: BlockNumberFor, + } + + impl Default for GenesisConfig { + fn default() -> Self { + Self { + byte_fee: 10u32.into(), + entry_fee: 1000u32.into(), + retention_period: DEFAULT_RETENTION_PERIOD.into(), + } + } + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + ByteFee::::put(self.byte_fee); + EntryFee::::put(self.entry_fee); + RetentionPeriod::::put(self.retention_period); + } + } + #[pallet::inherent] impl ProvideInherent for Pallet { type Call = Call; @@ -835,6 +882,11 @@ pub mod pallet { Self::check_signed(who, call, CheckContext::PreDispatch).map(|_| ()) } + /// Get RetentionPeriod storage information from the outside of this pallet. + pub fn retention_period() -> BlockNumberFor { + RetentionPeriod::::get() + } + /// Returns `true` if a blob of the given size can be stored. fn data_size_ok(size: usize) -> bool { (size > 0) && (size <= T::MaxTransactionSize::get() as usize) diff --git a/pallets/transaction-storage/src/migrations.rs b/pallets/transaction-storage/src/migrations.rs new file mode 100644 index 000000000..69289eb75 --- /dev/null +++ b/pallets/transaction-storage/src/migrations.rs @@ -0,0 +1,61 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// 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. + +use crate::{Config, RetentionPeriod, LOG_TARGET}; +use core::marker::PhantomData; +use polkadot_sdk_frame::{ + prelude::{BlockNumberFor, Weight}, + traits::{Get, OnRuntimeUpgrade, Zero}, +}; + +/// Runtime migration that sets the `RetentionPeriod` storage item to a +/// non-zero `NewValue` value **only if it is currently zero**. +/// +/// Idempotent migration: safe to run multiple times +pub struct SetRetentionPeriodIfZero(PhantomData<(T, NewValue)>); +impl>> OnRuntimeUpgrade + for SetRetentionPeriodIfZero +{ + fn on_runtime_upgrade() -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + // If zero, let's reset. + if RetentionPeriod::::get().is_zero() { + RetentionPeriod::::set(NewValue::get()); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + tracing::warn!( + target: LOG_TARGET, + new_value = ?NewValue::get(), + "[SetRetentionPeriodIfZero] RetentionPeriod was zero, resetting to:", + ); + } + + weight + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade( + _state: alloc::vec::Vec, + ) -> Result<(), polkadot_sdk_frame::deps::sp_runtime::DispatchError> { + polkadot_sdk_frame::prelude::ensure!( + !RetentionPeriod::::get().is_zero(), + "must be migrate to the `NewValue`." + ); + + tracing::info!(target: LOG_TARGET, "SetRetentionPeriodIfZero is OK!"); + Ok(()) + } +} diff --git a/pallets/transaction-storage/src/mock.rs b/pallets/transaction-storage/src/mock.rs index 2d673e801..96afcbadf 100644 --- a/pallets/transaction-storage/src/mock.rs +++ b/pallets/transaction-storage/src/mock.rs @@ -43,7 +43,6 @@ impl frame_system::Config for Test { } parameter_types! { - pub const StoragePeriod: BlockNumberFor = 10; pub const AuthorizationPeriod: BlockNumberFor = 10; pub const StoreRenewPriority: TransactionPriority = TransactionPriority::MAX; pub const StoreRenewLongevity: TransactionLongevity = 10; @@ -60,7 +59,6 @@ impl pallet_transaction_storage::Config for Test { type WeightInfo = (); type MaxBlockTransactions = ConstU32<{ DEFAULT_MAX_BLOCK_TRANSACTIONS }>; type MaxTransactionSize = ConstU32<{ DEFAULT_MAX_TRANSACTION_SIZE }>; - type StoragePeriod = StoragePeriod; type AuthorizationPeriod = AuthorizationPeriod; type Authorizer = EnsureRoot; type StoreRenewPriority = StoreRenewPriority; @@ -70,19 +68,26 @@ impl pallet_transaction_storage::Config for Test { } pub fn new_test_ext() -> TestExternalities { - let t = RuntimeGenesisConfig { system: Default::default() }.build_storage().unwrap(); + let t = RuntimeGenesisConfig { + system: Default::default(), + transaction_storage: pallet_transaction_storage::GenesisConfig:: { + retention_period: 10, + byte_fee: 2, + entry_fee: 200, + }, + } + .build_storage() + .unwrap(); t.into() } -pub fn run_to_block(n: u64, f: impl Fn() -> Option) { - while System::block_number() < n { - if let Some(proof) = f() { - TransactionStorage::check_proof(RuntimeOrigin::none(), proof).unwrap(); - } - TransactionStorage::on_finalize(System::block_number()); - System::on_finalize(System::block_number()); - System::set_block_number(System::block_number() + 1); - System::on_initialize(System::block_number()); - TransactionStorage::on_initialize(System::block_number()); - } +pub fn run_to_block(n: u64, f: impl Fn() -> Option + 'static) { + System::run_to_block_with::( + n, + RunToBlockHooks::default().before_finalize(|_| { + if let Some(proof) = f() { + TransactionStorage::check_proof(RuntimeOrigin::none(), proof).unwrap(); + } + }), + ); } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 9bd1ff274..43f61e9d0 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -191,9 +191,6 @@ parameter_types! { pub const EquivocationReportPeriodInBlocks: u64 = EquivocationReportPeriodInEpochs::get() * (EPOCH_DURATION_IN_BLOCKS as u64); - - // This currently _must_ be set to DEFAULT_STORAGE_PERIOD - pub const StoragePeriod: BlockNumber = sp_transaction_storage_proof::DEFAULT_STORAGE_PERIOD; pub const AuthorizationPeriod: BlockNumber = 7 * DAYS; pub const StoreRenewPriority: TransactionPriority = RemoveExpiredAuthorizationPriority::get() - 1; pub const StoreRenewLongevity: TransactionLongevity = DAYS as TransactionLongevity; @@ -250,6 +247,9 @@ impl frame_system::Config for Runtime { /// This is used as an identifier of the chain. 42 is the generic substrate prefix. type SS58Prefix = SS58Prefix; type MaxConsumers = frame_support::traits::ConstU32<16>; + + type SingleBlockMigrations = migrations::SingleBlockMigrations; + type MultiBlockMigrator = migrations::MbmMigrations; } impl pallet_validator_set::Config for Runtime { @@ -352,7 +352,6 @@ impl pallet_transaction_storage::Config for Runtime { type WeightInfo = pallet_transaction_storage::weights::SubstrateWeight; type MaxBlockTransactions = ConstU32<512>; type MaxTransactionSize = ConstU32<{ 8 * 1024 * 1024 }>; - type StoragePeriod = StoragePeriod; type AuthorizationPeriod = AuthorizationPeriod; type Authorizer = EnsureRoot; type StoreRenewPriority = StoreRenewPriority; @@ -641,6 +640,27 @@ pub type Executive = frame_executive::Executive< AllPalletsWithSystem, >; +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + /// Unreleased migrations. Add new ones here: + pub type Unreleased = (); + + /// Migrations/checks that do not need to be versioned and can run on every update. + pub type Permanent = ( + pallet_transaction_storage::migrations::SetRetentionPeriodIfZero< + crate::Runtime, + pallet_transaction_storage::DefaultRetentionPeriod, + >, + ); + + /// All single block migrations that will run on the next runtime upgrade. + pub type SingleBlockMigrations = (Unreleased, Permanent); + + /// MBM migrations to apply on runtime upgrade. + pub type MbmMigrations = (); +} + #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( diff --git a/runtimes/bulletin-polkadot/src/lib.rs b/runtimes/bulletin-polkadot/src/lib.rs index 8b0aa1abc..03936301d 100644 --- a/runtimes/bulletin-polkadot/src/lib.rs +++ b/runtimes/bulletin-polkadot/src/lib.rs @@ -193,8 +193,6 @@ parameter_types! { EquivocationReportPeriodInEpochs::get() * (EPOCH_DURATION_IN_BLOCKS as u64); - // This currently _must_ be set to DEFAULT_STORAGE_PERIOD - pub const StoragePeriod: BlockNumber = sp_transaction_storage_proof::DEFAULT_STORAGE_PERIOD; pub const AuthorizationPeriod: BlockNumber = 7 * DAYS; pub const StoreRenewPriority: TransactionPriority = RemoveExpiredAuthorizationPriority::get() - 1; pub const StoreRenewLongevity: TransactionLongevity = DAYS as TransactionLongevity; @@ -254,6 +252,9 @@ impl frame_system::Config for Runtime { /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; + + type SingleBlockMigrations = migrations::SingleBlockMigrations; + type MultiBlockMigrator = migrations::MbmMigrations; } impl pallet_validator_set::Config for Runtime { @@ -351,7 +352,6 @@ impl pallet_transaction_storage::Config for Runtime { type MaxBlockTransactions = ConstU32<512>; /// Max transaction size per block needs to be aligned with [`BlockLength`]. type MaxTransactionSize = ConstU32<{ 8 * 1024 * 1024 }>; - type StoragePeriod = StoragePeriod; type AuthorizationPeriod = AuthorizationPeriod; type Authorizer = EnsureRoot; type StoreRenewPriority = StoreRenewPriority; @@ -717,6 +717,27 @@ pub type Executive = frame_executive::Executive< AllPalletsWithSystem, >; +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + /// Unreleased migrations. Add new ones here: + pub type Unreleased = (); + + /// Migrations/checks that do not need to be versioned and can run on every update. + pub type Permanent = ( + pallet_transaction_storage::migrations::SetRetentionPeriodIfZero< + crate::Runtime, + pallet_transaction_storage::DefaultRetentionPeriod, + >, + ); + + /// All single block migrations that will run on the next runtime upgrade. + pub type SingleBlockMigrations = (Unreleased, Permanent); + + /// MBM migrations to apply on runtime upgrade. + pub type MbmMigrations = (); +} + #[cfg(feature = "runtime-benchmarks")] mod benches { use super::*; diff --git a/runtimes/bulletin-westend/src/lib.rs b/runtimes/bulletin-westend/src/lib.rs index 46972ec4f..0b1e427c9 100644 --- a/runtimes/bulletin-westend/src/lib.rs +++ b/runtimes/bulletin-westend/src/lib.rs @@ -122,19 +122,38 @@ pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim< pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -/// Migrations to apply on runtime upgrade. -pub type Migrations = ( - pallet_collator_selection::migration::v2::MigrationToV2, - cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, - cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5, - pallet_session::migrations::v1::MigrateV0ToV1< - Runtime, - pallet_session::migrations::v1::InitOffenceSeverity, - >, - // permanent - pallet_xcm::migration::MigrateToLatestXcmVersion, - cumulus_pallet_aura_ext::migration::MigrateV0ToV1, -); +/// The runtime migrations per release. +#[allow(deprecated, missing_docs)] +pub mod migrations { + use super::*; + + /// Unreleased migrations. Add new ones here: + pub type Unreleased = ( + pallet_collator_selection::migration::v2::MigrationToV2, + cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, + cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5, + pallet_session::migrations::v1::MigrateV0ToV1< + Runtime, + pallet_session::migrations::v1::InitOffenceSeverity, + >, + cumulus_pallet_aura_ext::migration::MigrateV0ToV1, + ); + + /// Migrations/checks that do not need to be versioned and can run on every update. + pub type Permanent = ( + pallet_xcm::migration::MigrateToLatestXcmVersion, + pallet_transaction_storage::migrations::SetRetentionPeriodIfZero< + Runtime, + pallet_transaction_storage::DefaultRetentionPeriod, + >, + ); + + /// All single block migrations that will run on the next runtime upgrade. + pub type SingleBlockMigrations = (Unreleased, Permanent); + + /// MBM migrations to apply on runtime upgrade. + pub type MbmMigrations = (); +} /// Executive: handles dispatch to the various modules. #[allow(deprecated)] @@ -227,6 +246,9 @@ impl frame_system::Config for Runtime { /// The action to take on a Runtime Upgrade type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = ConstU32<16>; + + type SingleBlockMigrations = migrations::SingleBlockMigrations; + type MultiBlockMigrator = migrations::MbmMigrations; } impl cumulus_pallet_weight_reclaim::Config for Runtime { diff --git a/runtimes/bulletin-westend/src/storage.rs b/runtimes/bulletin-westend/src/storage.rs index 648c0f193..900fe541a 100644 --- a/runtimes/bulletin-westend/src/storage.rs +++ b/runtimes/bulletin-westend/src/storage.rs @@ -27,8 +27,6 @@ use sp_runtime::transaction_validity::{TransactionLongevity, TransactionPriority use testnet_parachains_constants::westend::locations::PeopleLocation; parameter_types! { - // This currently _must_ be set to DEFAULT_STORAGE_PERIOD - pub const StoragePeriod: crate::BlockNumber = sp_transaction_storage_proof::DEFAULT_STORAGE_PERIOD; pub const AuthorizationPeriod: crate::BlockNumber = 7 * crate::DAYS; // Priorities and longevities used by the transaction storage pallet extrinsics. pub const SudoPriority: TransactionPriority = TransactionPriority::MAX; @@ -51,7 +49,6 @@ impl pallet_transaction_storage::Config for Runtime { type MaxBlockTransactions = crate::ConstU32<512>; /// Max transaction size per block needs to be aligned with `BlockLength`. type MaxTransactionSize = crate::ConstU32<{ 8 * 1024 * 1024 }>; - type StoragePeriod = StoragePeriod; type AuthorizationPeriod = AuthorizationPeriod; type Authorizer = EitherOfDiverse< // Root can do whatever.