From 5db22237759eb2a38a95f8780a31406f7e6c735b Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 15 Dec 2025 16:06:40 +0100 Subject: [PATCH 01/19] Add `TransactionStorageApi` definition --- Cargo.lock | 1 + .../transaction-storage-proof/Cargo.toml | 2 ++ .../transaction-storage-proof/src/lib.rs | 2 ++ .../src/runtime_api.rs | 28 +++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 substrate/primitives/transaction-storage-proof/src/runtime_api.rs diff --git a/Cargo.lock b/Cargo.lock index 80f8578ff0034..ea37c3521ca1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23564,6 +23564,7 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", + "sp-api", "sp-core 28.0.0", "sp-inherents", "sp-runtime", diff --git a/substrate/primitives/transaction-storage-proof/Cargo.toml b/substrate/primitives/transaction-storage-proof/Cargo.toml index a9040c1249a15..32edaa7e8a24e 100644 --- a/substrate/primitives/transaction-storage-proof/Cargo.toml +++ b/substrate/primitives/transaction-storage-proof/Cargo.toml @@ -20,6 +20,7 @@ async-trait = { optional = true, workspace = true } codec = { features = ["derive"], workspace = true } scale-info = { features = ["derive"], workspace = true } sp-core = { optional = true, workspace = true } +sp-api = { workspace = true } sp-inherents = { workspace = true } sp-runtime = { workspace = true } sp-trie = { optional = true, workspace = true } @@ -30,6 +31,7 @@ std = [ "async-trait", "codec/std", "scale-info/std", + "sp-api/std", "sp-core/std", "sp-inherents/std", "sp-runtime/std", diff --git a/substrate/primitives/transaction-storage-proof/src/lib.rs b/substrate/primitives/transaction-storage-proof/src/lib.rs index c92197a3fc308..268d130afce83 100644 --- a/substrate/primitives/transaction-storage-proof/src/lib.rs +++ b/substrate/primitives/transaction-storage-proof/src/lib.rs @@ -20,6 +20,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +pub mod runtime_api; + extern crate alloc; use core::result::Result; diff --git a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs new file mode 100644 index 0000000000000..a0236ed1d56cc --- /dev/null +++ b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs @@ -0,0 +1,28 @@ +// This file is part of Polkadot Sdk. + +// 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. + +//! Runtime API definition for the transaction storage proof processing. + +use sp_runtime::traits::NumberFor; + +sp_api::decl_runtime_apis! { + /// Runtime API trait for transaction storage support. + pub trait TransactionStorageApi { + /// Get the actual value of a storage period in blocks. + fn storage_period() -> NumberFor; + } +} From 8a5316542625992df49447419126331915988a27 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 15 Dec 2025 16:12:39 +0100 Subject: [PATCH 02/19] Add pub getter `storage_period` to transaction-storage pallet --- .../frame/transaction-storage/src/benchmarking.rs | 2 +- substrate/frame/transaction-storage/src/lib.rs | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/substrate/frame/transaction-storage/src/benchmarking.rs b/substrate/frame/transaction-storage/src/benchmarking.rs index d65fd667d4ea5..ff6cf626e6372 100644 --- a/substrate/frame/transaction-storage/src/benchmarking.rs +++ b/substrate/frame/transaction-storage/src/benchmarking.rs @@ -169,7 +169,7 @@ mod benchmarks { vec![0u8; T::MaxTransactionSize::get() as usize], )?; } - run_to_block::(StoragePeriod::::get() + BlockNumberFor::::one()); + run_to_block::(crate::Pallet::::storage_period() + BlockNumberFor::::one()); let encoded_proof = proof(); let proof = TransactionStorageProof::decode(&mut &*encoded_proof).unwrap(); diff --git a/substrate/frame/transaction-storage/src/lib.rs b/substrate/frame/transaction-storage/src/lib.rs index 62040c9d8966c..d0bd8ff77e325 100644 --- a/substrate/frame/transaction-storage/src/lib.rs +++ b/substrate/frame/transaction-storage/src/lib.rs @@ -218,7 +218,7 @@ pub mod pallet { // 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 = StoragePeriod::::get(); + let period = Self::storage_period(); let obsolete = n.saturating_sub(period.saturating_add(One::one())); if obsolete > Zero::zero() { weight.saturating_accrue(db_weight.writes(1)); @@ -235,7 +235,7 @@ pub mod pallet { ProofChecked::::take() || { // Proof is not required for early or empty blocks. let number = frame_system::Pallet::::block_number(); - let period = StoragePeriod::::get(); + let period = Self::storage_period(); let target_number = number.saturating_sub(period); target_number.is_zero() || { @@ -394,7 +394,7 @@ pub mod pallet { // Get the target block metadata. let number = frame_system::Pallet::::block_number(); - let period = StoragePeriod::::get(); + let period = Self::storage_period(); let target_number = number.saturating_sub(period); ensure!(!target_number.is_zero(), Error::::UnexpectedProof); let transactions = @@ -525,14 +525,18 @@ pub mod pallet { ) -> Option> { Transactions::::get(block) } - /// Get ByteFee storage information from outside of this pallet. + /// Get ByteFee storage information from the outside of this pallet. pub fn byte_fee() -> Option> { ByteFee::::get() } - /// Get EntryFee storage information from outside of this pallet. + /// Get EntryFee storage information from the outside of this pallet. pub fn entry_fee() -> Option> { EntryFee::::get() } + /// Get StoragePeriod storage information from the outside of this pallet. + pub fn storage_period() -> BlockNumberFor { + StoragePeriod::::get() + } fn apply_fee(sender: T::AccountId, size: u32) -> DispatchResult { let byte_fee = ByteFee::::get().ok_or(Error::::NotConfigured)?; From 3c1e6372576f2d53d7b62502e16c3fb499fb5b32 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 01:41:27 +0100 Subject: [PATCH 03/19] Add TransactionStorageApi to the kithchensink --- Cargo.lock | 1 + substrate/bin/node/cli/Cargo.toml | 1 + .../bin/node/cli/tests/runtime_api_works.rs | 56 +++++++++++++++++++ substrate/bin/node/runtime/src/lib.rs | 6 ++ 4 files changed, 64 insertions(+) create mode 100644 substrate/bin/node/cli/tests/runtime_api_works.rs diff --git a/Cargo.lock b/Cargo.lock index ea37c3521ca1b..5f3101c07612d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23994,6 +23994,7 @@ dependencies = [ "sp-keyring", "staging-node-inspect", "substrate-cli-test-utils", + "substrate-rpc-client", "subxt-signer 0.43.0", "tempfile", "tokio", diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 091b6123c5c38..ecd00a58eec8a 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -169,6 +169,7 @@ wat = { workspace = true } node-testing = { workspace = true } sc-service-test = { workspace = true } substrate-cli-test-utils = { workspace = true } +substrate-rpc-client = { workspace = true } [build-dependencies] clap = { optional = true, workspace = true } diff --git a/substrate/bin/node/cli/tests/runtime_api_works.rs b/substrate/bin/node/cli/tests/runtime_api_works.rs new file mode 100644 index 0000000000000..38d48e77b05e9 --- /dev/null +++ b/substrate/bin/node/cli/tests/runtime_api_works.rs @@ -0,0 +1,56 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(unix)] +use codec::Decode; +use polkadot_sdk::sp_runtime::traits::NumberFor; +use std::time::Duration; +use substrate_cli_test_utils as common; +use substrate_rpc_client::{ws_client, StateApi}; + +#[tokio::test] +async fn transaction_storage_runtime_api_call_works() { + common::run_with_timeout(Duration::from_secs(60 * 10), async move { + // Run the node. + let mut node = common::KillChildOnDrop(common::start_node()); + let stderr = node.stderr.take().unwrap(); + let ws_url = common::extract_info_from_output(stderr).0.ws_url; + common::wait_n_finalized_blocks(1, &ws_url).await; + let block_hash = common::block_hash(1, &ws_url).await.unwrap(); + node.assert_still_running(); + + // Call the runtime API. + let rpc = ws_client(ws_url).await.unwrap(); + let result = rpc + .call( + String::from("TransactionStorageApi_storage_period"), + vec![].into(), + Some(block_hash), + ) + .await + .unwrap(); + + // Decode and assert the received value. + let storage_period: NumberFor = + Decode::decode(&mut &result.0[..]).unwrap(); + assert_eq!(storage_period, 100800); + + node.stop(); + }) + .await; +} diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 72e8d1e1f6c0f..1bf2d466157b6 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -3776,6 +3776,12 @@ pallet_revive::impl_runtime_apis_plus_revive_traits!( } } + impl sp_transaction_storage_proof::runtime_api::TransactionStorageApi for Runtime { + fn storage_period() -> NumberFor { + TransactionStorage::storage_period() + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { From 26214febd148163427ad14719b14e61e6c96e212 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 01:45:40 +0100 Subject: [PATCH 04/19] Move `DEFAULT_STORAGE_PERIOD` Nit --- substrate/frame/transaction-storage/src/lib.rs | 10 ++++++---- .../primitives/transaction-storage-proof/src/lib.rs | 7 ++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/substrate/frame/transaction-storage/src/lib.rs b/substrate/frame/transaction-storage/src/lib.rs index d0bd8ff77e325..b58543732e000 100644 --- a/substrate/frame/transaction-storage/src/lib.rs +++ b/substrate/frame/transaction-storage/src/lib.rs @@ -57,6 +57,9 @@ pub type CreditOf = Credit<::AccountId, ::default().storage_period; assert_eq!( storage_period, default_period, @@ -456,8 +459,7 @@ pub mod pallet { /// Storage fee per transaction. pub type EntryFee = StorageValue<_, BalanceOf>; - /// Storage period for data in blocks. Should match `sp_storage_proof::DEFAULT_STORAGE_PERIOD` - /// for block authoring. + /// Storage period for data in blocks. #[pallet::storage] pub type StoragePeriod = StorageValue<_, BlockNumberFor, ValueQuery>; @@ -482,7 +484,7 @@ pub mod pallet { Self { byte_fee: 10u32.into(), entry_fee: 1000u32.into(), - storage_period: sp_transaction_storage_proof::DEFAULT_STORAGE_PERIOD.into(), + storage_period: DEFAULT_STORAGE_PERIOD.into(), } } } diff --git a/substrate/primitives/transaction-storage-proof/src/lib.rs b/substrate/primitives/transaction-storage-proof/src/lib.rs index 268d130afce83..ed81233f9c76b 100644 --- a/substrate/primitives/transaction-storage-proof/src/lib.rs +++ b/substrate/primitives/transaction-storage-proof/src/lib.rs @@ -35,8 +35,6 @@ pub use sp_inherents::Error; /// The identifier for the proof inherent. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"tx_proof"; -/// Storage period for data. -pub const DEFAULT_STORAGE_PERIOD: u32 = 100800; /// Proof trie value size. pub const CHUNK_SIZE: usize = 256; @@ -170,15 +168,14 @@ pub mod registration { pub fn new_data_provider( client: &C, parent: &B::Hash, + storage_period: NumberFor, ) -> Result where B: BlockT, C: IndexedBody, { let parent_number = client.number(*parent)?.unwrap_or(Zero::zero()); - let number = parent_number - .saturating_add(One::one()) - .saturating_sub(DEFAULT_STORAGE_PERIOD.into()); + let number = parent_number.saturating_add(One::one()).saturating_sub(storage_period); if number.is_zero() { // Too early to collect proofs. return Ok(InherentDataProvider::new(None)); From e4bb2e5231a92fe010f8da85b58388d023affd33 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 01:50:46 +0100 Subject: [PATCH 05/19] Call runtime API to get the storage_period for inherent data provider for substrate-node --- substrate/bin/node/cli/src/service.rs | 10 ++-- .../src/runtime_api.rs | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 0ec655e3fa6ac..19bede34cf6e4 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -627,11 +627,11 @@ pub fn new_full_base::Hash>>( slot_duration, ); - let storage_proof = - sp_transaction_storage_proof::registration::new_data_provider( - &*client_clone, - &parent, - )?; + let storage_proof = sp_transaction_storage_proof::registration::new_data_provider( + &*client_clone, + &parent, + sp_transaction_storage_proof::runtime_api::client::retrieve_storage_period(&client_clone, parent)?, + )?; Ok((slot, timestamp, storage_proof)) } diff --git a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs index a0236ed1d56cc..d910225c0321e 100644 --- a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs +++ b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs @@ -26,3 +26,52 @@ sp_api::decl_runtime_apis! { fn storage_period() -> NumberFor; } } + +#[cfg(feature = "std")] +pub mod client { + use codec::Decode; + use sp_api::{ApiError, CallApiAt, CallApiAtParams}; + use sp_core::traits::CallContext; + use sp_runtime::traits::Block as BlockT; + use sp_runtime::traits::NumberFor; + + /// An expected state call key. + pub const TRANSACTION_STORAGE_API_STORAGE_PERIOD: &'static str = + "TransactionStorageApi_storage_period"; + + /// Fetches the storage period value for a specific block from the runtime API. + /// + /// This function interacts with the `TRANSACTION_STORAGE_API_STORAGE_PERIOD` API + /// provided by the runtime. + /// + /// # Arguments + /// - `client`: A reference to an object implementing the `CallApiAt` trait, + /// used to interact with the runtime API. + /// - `at_block`: The hash of the specific block for which the storage period is queried. + pub fn retrieve_storage_period( + client: &C, + at_block: B::Hash, + ) -> Result, ApiError> + where + B: BlockT, + C: CallApiAt, + { + // Call the expected runtime API. + let result = client.call_api_at(CallApiAtParams { + at: at_block, + function: TRANSACTION_STORAGE_API_STORAGE_PERIOD, + arguments: vec![], + overlayed_changes: &Default::default(), + call_context: CallContext::Onchain, + recorder: &None, + extensions: &Default::default(), + })?; + + // Decode to `NumberFor`. + Decode::decode(&mut &result[..]).map_err(|e| ApiError::FailedToDecodeReturnValue { + function: TRANSACTION_STORAGE_API_STORAGE_PERIOD, + error: e, + raw: result, + }) + } +} From 432f85bdc096e2e7095a5fce68f3c30a115729f5 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 02:24:52 +0100 Subject: [PATCH 06/19] Licence --- .../primitives/transaction-storage-proof/src/runtime_api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs index d910225c0321e..6323ce1b3ab58 100644 --- a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs +++ b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs @@ -1,4 +1,4 @@ -// This file is part of Polkadot Sdk. +// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 From 7c5931c5a04d42a9ce05b0c2f37df483e64e805a Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 01:26:44 +0000 Subject: [PATCH 07/19] Update from github-actions[bot] running command 'prdoc --audience runtime_dev node_dev --bump patch' --- prdoc/pr_10656.prdoc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 prdoc/pr_10656.prdoc diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc new file mode 100644 index 0000000000000..43b59737d10a8 --- /dev/null +++ b/prdoc/pr_10656.prdoc @@ -0,0 +1,33 @@ +title: '[pallet-transaction-storage] Configurable StoragePeriod' +doc: +- audience: + - Runtime Dev + - Node Dev + description: "Relates to: https://github.com/paritytech/polkadot-sdk/pull/10494\n\ + Relates to: https://github.com/paritytech/polkadot-bulletin-chain/issues/82\n\ + Relates to: https://github.com/paritytech/polkadot-bulletin-chain/issues/60\n\n\ + ## Context/Problem\n\nThis PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof`\ + \ (the `new_data_provider` inherent provider), both of which rely on a hard-coded\ + \ `DEFAULT_STORAGE_PERIOD`.\n\nThe `new_data_provider` uses a hard-coded `pub\ + \ const DEFAULT_STORAGE_PERIOD: u32 = 100800;`, which forces the runtime to use\ + \ the same value. This value corresponds to 7 days for 6-second blocks. We want\ + \ to make this constant configurable and driven by the runtime \u2014 exposed\ + \ via a runtime API. For example, if we switch to 2-second blocks but still want\ + \ to keep the 7-day period, we won\u2019t need to coordinate and restart the collators\ + \ with a new hard-coded constant and so on. Basically, we want to have possibility\ + \ to set this constant with arbitrary value without affecting the collators or\ + \ anything.\n\n## Solution\n\nThis PR:\n* adds a new argument `storage_period`\ + \ to the `new_data_provider`\n* introduces the `TransactionStorageApi::storage_period`\ + \ runtime API, which the runtime can specify arbitrary\n* provides an example\ + \ of using `new_data_provider`, with the node client calling the runtime API when\ + \ constructing inherent provider data\n * I didn't want to complicate the node\ + \ client traits, so `retrieve_storage_period` uses just direct `call_api_at(\"\ + TransactionStorageApi_storage_period\", at_block)`\n\n## TODO\n- [ ] Is there\ + \ any alternative to `call_api_at` for how a node\u2019s custom inherent data\ + \ provider can call a runtime API declared via `decl_runtime_apis`?\n\n## Follow-up\n\ + \nIt will be used for Bulletin setup here: https://github.com/paritytech/polkadot-sdk/pull/10494" +crates: +- name: sp-transaction-storage-proof + bump: patch +- name: pallet-transaction-storage + bump: patch From 5dc936408ad215f551964c0c732a5695c94d7139 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 10:13:07 +0100 Subject: [PATCH 08/19] Update substrate/frame/transaction-storage/src/lib.rs --- substrate/frame/transaction-storage/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/transaction-storage/src/lib.rs b/substrate/frame/transaction-storage/src/lib.rs index b58543732e000..98c1f36a2bb52 100644 --- a/substrate/frame/transaction-storage/src/lib.rs +++ b/substrate/frame/transaction-storage/src/lib.rs @@ -57,7 +57,7 @@ pub type CreditOf = Credit<::AccountId, Date: Tue, 16 Dec 2025 10:17:16 +0100 Subject: [PATCH 09/19] Update prdoc/pr_10656.prdoc --- prdoc/pr_10656.prdoc | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc index 43b59737d10a8..e25b194ef630e 100644 --- a/prdoc/pr_10656.prdoc +++ b/prdoc/pr_10656.prdoc @@ -3,29 +3,11 @@ doc: - audience: - Runtime Dev - Node Dev - description: "Relates to: https://github.com/paritytech/polkadot-sdk/pull/10494\n\ - Relates to: https://github.com/paritytech/polkadot-bulletin-chain/issues/82\n\ - Relates to: https://github.com/paritytech/polkadot-bulletin-chain/issues/60\n\n\ - ## Context/Problem\n\nThis PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof`\ - \ (the `new_data_provider` inherent provider), both of which rely on a hard-coded\ - \ `DEFAULT_STORAGE_PERIOD`.\n\nThe `new_data_provider` uses a hard-coded `pub\ - \ const DEFAULT_STORAGE_PERIOD: u32 = 100800;`, which forces the runtime to use\ - \ the same value. This value corresponds to 7 days for 6-second blocks. We want\ - \ to make this constant configurable and driven by the runtime \u2014 exposed\ - \ via a runtime API. For example, if we switch to 2-second blocks but still want\ - \ to keep the 7-day period, we won\u2019t need to coordinate and restart the collators\ - \ with a new hard-coded constant and so on. Basically, we want to have possibility\ - \ to set this constant with arbitrary value without affecting the collators or\ - \ anything.\n\n## Solution\n\nThis PR:\n* adds a new argument `storage_period`\ - \ to the `new_data_provider`\n* introduces the `TransactionStorageApi::storage_period`\ - \ runtime API, which the runtime can specify arbitrary\n* provides an example\ - \ of using `new_data_provider`, with the node client calling the runtime API when\ - \ constructing inherent provider data\n * I didn't want to complicate the node\ - \ client traits, so `retrieve_storage_period` uses just direct `call_api_at(\"\ - TransactionStorageApi_storage_period\", at_block)`\n\n## TODO\n- [ ] Is there\ - \ any alternative to `call_api_at` for how a node\u2019s custom inherent data\ - \ provider can call a runtime API declared via `decl_runtime_apis`?\n\n## Follow-up\n\ - \nIt will be used for Bulletin setup here: https://github.com/paritytech/polkadot-sdk/pull/10494" + description: |- + This PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof` (the `new_data_provider` inherent provider), both of which rely on a hard-coded `DEFAULT_STORAGE_PERIOD`. This PR: + - adds a new configurable argument `storage_period` to the `new_data_provider` + - introduces the `TransactionStorageApi::storage_period` runtime API, which the runtime can specify arbitrary + - provides an example of using `new_data_provider`, with the node client calling the runtime API when constructing inherent provider data crates: - name: sp-transaction-storage-proof bump: patch From 6f32290525e6ba3eb9b7c01f02e3364d48923d96 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 09:19:56 +0000 Subject: [PATCH 10/19] Update from github-actions[bot] running command 'fmt' --- substrate/primitives/transaction-storage-proof/Cargo.toml | 2 +- .../transaction-storage-proof/src/runtime_api.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/substrate/primitives/transaction-storage-proof/Cargo.toml b/substrate/primitives/transaction-storage-proof/Cargo.toml index 32edaa7e8a24e..d404875e08b12 100644 --- a/substrate/primitives/transaction-storage-proof/Cargo.toml +++ b/substrate/primitives/transaction-storage-proof/Cargo.toml @@ -19,8 +19,8 @@ targets = ["x86_64-unknown-linux-gnu"] async-trait = { optional = true, workspace = true } codec = { features = ["derive"], workspace = true } scale-info = { features = ["derive"], workspace = true } -sp-core = { optional = true, workspace = true } sp-api = { workspace = true } +sp-core = { optional = true, workspace = true } sp-inherents = { workspace = true } sp-runtime = { workspace = true } sp-trie = { optional = true, workspace = true } diff --git a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs index 6323ce1b3ab58..1132990975908 100644 --- a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs +++ b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs @@ -32,8 +32,7 @@ pub mod client { use codec::Decode; use sp_api::{ApiError, CallApiAt, CallApiAtParams}; use sp_core::traits::CallContext; - use sp_runtime::traits::Block as BlockT; - use sp_runtime::traits::NumberFor; + use sp_runtime::traits::{Block as BlockT, NumberFor}; /// An expected state call key. pub const TRANSACTION_STORAGE_API_STORAGE_PERIOD: &'static str = @@ -45,8 +44,8 @@ pub mod client { /// provided by the runtime. /// /// # Arguments - /// - `client`: A reference to an object implementing the `CallApiAt` trait, - /// used to interact with the runtime API. + /// - `client`: A reference to an object implementing the `CallApiAt` trait, used to interact + /// with the runtime API. /// - `at_block`: The hash of the specific block for which the storage period is queried. pub fn retrieve_storage_period( client: &C, From 1806e308d9143c8efa16f0be97f711581c12a1de Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 10:25:32 +0100 Subject: [PATCH 11/19] Update prdoc/pr_10656.prdoc --- prdoc/pr_10656.prdoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc index e25b194ef630e..f43c267a867fc 100644 --- a/prdoc/pr_10656.prdoc +++ b/prdoc/pr_10656.prdoc @@ -1,8 +1,6 @@ title: '[pallet-transaction-storage] Configurable StoragePeriod' doc: -- audience: - - Runtime Dev - - Node Dev +- audience: [Node Dev, Runtime Dev] description: |- This PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof` (the `new_data_provider` inherent provider), both of which rely on a hard-coded `DEFAULT_STORAGE_PERIOD`. This PR: - adds a new configurable argument `storage_period` to the `new_data_provider` From 27c42bae37b9c1656d86d6b1c11c9ce80cdbec1a Mon Sep 17 00:00:00 2001 From: EgorPopelyaev Date: Tue, 16 Dec 2025 10:43:08 +0100 Subject: [PATCH 12/19] Fix indentation in the prdoc --- prdoc/pr_10656.prdoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc index f43c267a867fc..6a41f6ba9ada5 100644 --- a/prdoc/pr_10656.prdoc +++ b/prdoc/pr_10656.prdoc @@ -2,10 +2,10 @@ title: '[pallet-transaction-storage] Configurable StoragePeriod' doc: - audience: [Node Dev, Runtime Dev] description: |- - This PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof` (the `new_data_provider` inherent provider), both of which rely on a hard-coded `DEFAULT_STORAGE_PERIOD`. This PR: - - adds a new configurable argument `storage_period` to the `new_data_provider` - - introduces the `TransactionStorageApi::storage_period` runtime API, which the runtime can specify arbitrary - - provides an example of using `new_data_provider`, with the node client calling the runtime API when constructing inherent provider data + This PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof` (the `new_data_provider` inherent provider), both of which rely on a hard-coded `DEFAULT_STORAGE_PERIOD`. This PR: + - adds a new configurable argument `storage_period` to the `new_data_provider` + - introduces the `TransactionStorageApi::storage_period` runtime API, which the runtime can specify arbitrary + - provides an example of using `new_data_provider`, with the node client calling the runtime API when constructing inherent provider data crates: - name: sp-transaction-storage-proof bump: patch From 58113e4457a2d2c956e597f57b14bac24f5597b5 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 11:39:40 +0100 Subject: [PATCH 13/19] Fix CI? --- substrate/frame/transaction-storage/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/transaction-storage/Cargo.toml b/substrate/frame/transaction-storage/Cargo.toml index c3ee687bda0a9..f5a2e8923e4eb 100644 --- a/substrate/frame/transaction-storage/Cargo.toml +++ b/substrate/frame/transaction-storage/Cargo.toml @@ -46,6 +46,7 @@ std = [ "sp-inherents/std", "sp-io/std", "sp-runtime/std", + "sp-transaction-storage-proof/std", "tracing/std", ] runtime-benchmarks = [ From 3e2b9eaca25828e2109205a65e5392517e8618fd Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 12:19:38 +0100 Subject: [PATCH 14/19] Update prdoc/pr_10656.prdoc --- prdoc/pr_10656.prdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc index 6a41f6ba9ada5..1fad9ff83793c 100644 --- a/prdoc/pr_10656.prdoc +++ b/prdoc/pr_10656.prdoc @@ -8,6 +8,6 @@ doc: - provides an example of using `new_data_provider`, with the node client calling the runtime API when constructing inherent provider data crates: - name: sp-transaction-storage-proof - bump: patch + bump: major - name: pallet-transaction-storage - bump: patch + bump: minor From d0e55e8bc676444f8142424c0091414194d081de Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 16 Dec 2025 14:45:47 +0100 Subject: [PATCH 15/19] Removed transaction_storage_runtime_api_call_works --- Cargo.lock | 1 - substrate/bin/node/cli/Cargo.toml | 1 - .../bin/node/cli/tests/runtime_api_works.rs | 56 ------------------- 3 files changed, 58 deletions(-) delete mode 100644 substrate/bin/node/cli/tests/runtime_api_works.rs diff --git a/Cargo.lock b/Cargo.lock index 5f3101c07612d..ea37c3521ca1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23994,7 +23994,6 @@ dependencies = [ "sp-keyring", "staging-node-inspect", "substrate-cli-test-utils", - "substrate-rpc-client", "subxt-signer 0.43.0", "tempfile", "tokio", diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index ecd00a58eec8a..091b6123c5c38 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -169,7 +169,6 @@ wat = { workspace = true } node-testing = { workspace = true } sc-service-test = { workspace = true } substrate-cli-test-utils = { workspace = true } -substrate-rpc-client = { workspace = true } [build-dependencies] clap = { optional = true, workspace = true } diff --git a/substrate/bin/node/cli/tests/runtime_api_works.rs b/substrate/bin/node/cli/tests/runtime_api_works.rs deleted file mode 100644 index 38d48e77b05e9..0000000000000 --- a/substrate/bin/node/cli/tests/runtime_api_works.rs +++ /dev/null @@ -1,56 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#![cfg(unix)] -use codec::Decode; -use polkadot_sdk::sp_runtime::traits::NumberFor; -use std::time::Duration; -use substrate_cli_test_utils as common; -use substrate_rpc_client::{ws_client, StateApi}; - -#[tokio::test] -async fn transaction_storage_runtime_api_call_works() { - common::run_with_timeout(Duration::from_secs(60 * 10), async move { - // Run the node. - let mut node = common::KillChildOnDrop(common::start_node()); - let stderr = node.stderr.take().unwrap(); - let ws_url = common::extract_info_from_output(stderr).0.ws_url; - common::wait_n_finalized_blocks(1, &ws_url).await; - let block_hash = common::block_hash(1, &ws_url).await.unwrap(); - node.assert_still_running(); - - // Call the runtime API. - let rpc = ws_client(ws_url).await.unwrap(); - let result = rpc - .call( - String::from("TransactionStorageApi_storage_period"), - vec![].into(), - Some(block_hash), - ) - .await - .unwrap(); - - // Decode and assert the received value. - let storage_period: NumberFor = - Decode::decode(&mut &result.0[..]).unwrap(); - assert_eq!(storage_period, 100800); - - node.stop(); - }) - .await; -} From b725081304c1c8da63b7a89d1ef95077afe4f002 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 17 Dec 2025 12:23:29 +0100 Subject: [PATCH 16/19] Use directly runtime API, no need for "hacky" workaround `client.call_api_at` --- substrate/bin/node/cli/src/service.rs | 12 +++-- .../src/runtime_api.rs | 48 ------------------- 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 19bede34cf6e4..8f5f95bb43893 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -47,6 +47,7 @@ use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_api::ProvideRuntimeApi; use sp_core::crypto::Pair; use sp_runtime::{generic, traits::Block as BlockT, SaturatedConversion}; +use sp_transaction_storage_proof::runtime_api::TransactionStorageApi; use std::{path::Path, sync::Arc}; /// Host functions required for kitchensink runtime and Substrate node. @@ -627,11 +628,12 @@ pub fn new_full_base::Hash>>( slot_duration, ); - let storage_proof = sp_transaction_storage_proof::registration::new_data_provider( - &*client_clone, - &parent, - sp_transaction_storage_proof::runtime_api::client::retrieve_storage_period(&client_clone, parent)?, - )?; + let storage_proof = + sp_transaction_storage_proof::registration::new_data_provider( + &*client_clone, + &parent, + client_clone.runtime_api().storage_period(parent)?, + )?; Ok((slot, timestamp, storage_proof)) } diff --git a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs index 1132990975908..9e20b3c800619 100644 --- a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs +++ b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs @@ -26,51 +26,3 @@ sp_api::decl_runtime_apis! { fn storage_period() -> NumberFor; } } - -#[cfg(feature = "std")] -pub mod client { - use codec::Decode; - use sp_api::{ApiError, CallApiAt, CallApiAtParams}; - use sp_core::traits::CallContext; - use sp_runtime::traits::{Block as BlockT, NumberFor}; - - /// An expected state call key. - pub const TRANSACTION_STORAGE_API_STORAGE_PERIOD: &'static str = - "TransactionStorageApi_storage_period"; - - /// Fetches the storage period value for a specific block from the runtime API. - /// - /// This function interacts with the `TRANSACTION_STORAGE_API_STORAGE_PERIOD` API - /// provided by the runtime. - /// - /// # Arguments - /// - `client`: A reference to an object implementing the `CallApiAt` trait, used to interact - /// with the runtime API. - /// - `at_block`: The hash of the specific block for which the storage period is queried. - pub fn retrieve_storage_period( - client: &C, - at_block: B::Hash, - ) -> Result, ApiError> - where - B: BlockT, - C: CallApiAt, - { - // Call the expected runtime API. - let result = client.call_api_at(CallApiAtParams { - at: at_block, - function: TRANSACTION_STORAGE_API_STORAGE_PERIOD, - arguments: vec![], - overlayed_changes: &Default::default(), - call_context: CallContext::Onchain, - recorder: &None, - extensions: &Default::default(), - })?; - - // Decode to `NumberFor`. - Decode::decode(&mut &result[..]).map_err(|e| ApiError::FailedToDecodeReturnValue { - function: TRANSACTION_STORAGE_API_STORAGE_PERIOD, - error: e, - raw: result, - }) - } -} From 9f77401aafb14f1c4f0ee5b3d7dc3b0a6efec7b7 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 17 Dec 2025 12:48:15 +0100 Subject: [PATCH 17/19] Rename `StoragePeriod` to `RetentionPeriod` --- prdoc/pr_10656.prdoc | 8 ++-- substrate/bin/node/cli/src/service.rs | 2 +- .../cli/tests/res/default_genesis_config.json | 2 +- substrate/bin/node/runtime/src/lib.rs | 4 +- substrate/frame/transaction-storage/README.md | 10 ++--- .../transaction-storage/src/benchmarking.rs | 2 +- .../frame/transaction-storage/src/lib.rs | 42 ++++++++++--------- .../frame/transaction-storage/src/mock.rs | 2 +- .../transaction-storage-proof/src/lib.rs | 4 +- .../src/runtime_api.rs | 4 +- 10 files changed, 42 insertions(+), 38 deletions(-) diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc index 1fad9ff83793c..c7648c33434db 100644 --- a/prdoc/pr_10656.prdoc +++ b/prdoc/pr_10656.prdoc @@ -1,10 +1,10 @@ -title: '[pallet-transaction-storage] Configurable StoragePeriod' +title: '[pallet-transaction-storage] Configurable RetentionPeriod' doc: - audience: [Node Dev, Runtime Dev] description: |- - This PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof` (the `new_data_provider` inherent provider), both of which rely on a hard-coded `DEFAULT_STORAGE_PERIOD`. This PR: - - adds a new configurable argument `storage_period` to the `new_data_provider` - - introduces the `TransactionStorageApi::storage_period` runtime API, which the runtime can specify arbitrary + This PR refactors `pallet-transaction-storage` and `sp-transaction-storage-proof` (the `new_data_provider` inherent provider), both of which rely on a hard-coded `DEFAULT_RETENTION_PERIOD`. This PR: + - adds a new configurable argument `retention_period` to the `new_data_provider` + - introduces the `TransactionStorageApi::retention_period` runtime API, which the runtime can specify arbitrary - provides an example of using `new_data_provider`, with the node client calling the runtime API when constructing inherent provider data crates: - name: sp-transaction-storage-proof diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 8f5f95bb43893..a7da65a3544b4 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -632,7 +632,7 @@ pub fn new_full_base::Hash>>( sp_transaction_storage_proof::registration::new_data_provider( &*client_clone, &parent, - client_clone.runtime_api().storage_period(parent)?, + client_clone.runtime_api().retention_period(parent)?, )?; Ok((slot, timestamp, storage_proof)) diff --git a/substrate/bin/node/cli/tests/res/default_genesis_config.json b/substrate/bin/node/cli/tests/res/default_genesis_config.json index 85a8057bb60a3..d83392ffd5113 100644 --- a/substrate/bin/node/cli/tests/res/default_genesis_config.json +++ b/substrate/bin/node/cli/tests/res/default_genesis_config.json @@ -100,7 +100,7 @@ "transactionStorage": { "byteFee": 10, "entryFee": 1000, - "storagePeriod": 100800 + "retentionPeriod": 100800 }, "allianceMotion": { "members": [] diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 1bf2d466157b6..b418b8d8eb330 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -3777,8 +3777,8 @@ pallet_revive::impl_runtime_apis_plus_revive_traits!( } impl sp_transaction_storage_proof::runtime_api::TransactionStorageApi for Runtime { - fn storage_period() -> NumberFor { - TransactionStorage::storage_period() + fn retention_period() -> NumberFor { + TransactionStorage::retention_period() } } diff --git a/substrate/frame/transaction-storage/README.md b/substrate/frame/transaction-storage/README.md index b173c0a84d5a0..62741a0127281 100644 --- a/substrate/frame/transaction-storage/README.md +++ b/substrate/frame/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 +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 @@ -17,7 +17,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 +`transactionStorage` section. 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. @@ -34,7 +34,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. `--ipfs-server` enables serving stored content over IPFS. +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. @@ -78,7 +78,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 transaction, and index is the index of that transaction in the block. diff --git a/substrate/frame/transaction-storage/src/benchmarking.rs b/substrate/frame/transaction-storage/src/benchmarking.rs index ff6cf626e6372..491aed33e00b6 100644 --- a/substrate/frame/transaction-storage/src/benchmarking.rs +++ b/substrate/frame/transaction-storage/src/benchmarking.rs @@ -169,7 +169,7 @@ mod benchmarks { vec![0u8; T::MaxTransactionSize::get() as usize], )?; } - run_to_block::(crate::Pallet::::storage_period() + 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/substrate/frame/transaction-storage/src/lib.rs b/substrate/frame/transaction-storage/src/lib.rs index 98c1f36a2bb52..b9fbcb51fbec7 100644 --- a/substrate/frame/transaction-storage/src/lib.rs +++ b/substrate/frame/transaction-storage/src/lib.rs @@ -57,8 +57,8 @@ pub type CreditOf = Credit<::AccountId, Zero::zero() { weight.saturating_accrue(db_weight.writes(1)); @@ -238,7 +238,7 @@ pub mod pallet { ProofChecked::::take() || { // Proof is not required for early or empty blocks. let number = frame_system::Pallet::::block_number(); - let period = Self::storage_period(); + let period = Self::retention_period(); let target_number = number.saturating_sub(period); target_number.is_zero() || { @@ -267,11 +267,11 @@ pub mod pallet { !T::MaxTransactionSize::get().is_zero(), "MaxTransactionSize must be greater than zero" ); - let default_period = DEFAULT_STORAGE_PERIOD.into(); - let storage_period = GenesisConfig::::default().storage_period; + let default_period = DEFAULT_RETENTION_PERIOD.into(); + let retention_period = GenesisConfig::::default().retention_period; assert_eq!( - storage_period, default_period, - "GenesisConfig.storage_period must match DEFAULT_STORAGE_PERIOD" + retention_period, default_period, + "GenesisConfig.retention_period must match DEFAULT_RETENTION_PERIOD" ); } } @@ -279,7 +279,7 @@ pub mod pallet { #[pallet::call] impl Pallet { /// Index and store data off chain. Minimum data size is 1 byte, maximum is - /// `MaxTransactionSize`. Data will be removed after `StoragePeriod` blocks, unless `renew` + /// `MaxTransactionSize`. Data will be removed after `RetentionPeriod` blocks, unless `renew` /// is called. /// /// Emits [`Stored`](Event::Stored) when successful. @@ -379,7 +379,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 @@ -397,7 +397,7 @@ pub mod pallet { // Get the target block metadata. let number = frame_system::Pallet::::block_number(); - let period = Self::storage_period(); + let period = Self::retention_period(); let target_number = number.saturating_sub(period); ensure!(!target_number.is_zero(), Error::::UnexpectedProof); let transactions = @@ -459,9 +459,13 @@ pub mod pallet { /// Storage fee per transaction. pub type EntryFee = StorageValue<_, BalanceOf>; - /// Storage period for data in blocks. + /// 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 StoragePeriod = StorageValue<_, BlockNumberFor, ValueQuery>; + pub type RetentionPeriod = StorageValue<_, BlockNumberFor, ValueQuery>; // Intermediates #[pallet::storage] @@ -476,7 +480,7 @@ pub mod pallet { pub struct GenesisConfig { pub byte_fee: BalanceOf, pub entry_fee: BalanceOf, - pub storage_period: BlockNumberFor, + pub retention_period: BlockNumberFor, } impl Default for GenesisConfig { @@ -484,7 +488,7 @@ pub mod pallet { Self { byte_fee: 10u32.into(), entry_fee: 1000u32.into(), - storage_period: DEFAULT_STORAGE_PERIOD.into(), + retention_period: DEFAULT_RETENTION_PERIOD.into(), } } } @@ -494,7 +498,7 @@ pub mod pallet { fn build(&self) { ByteFee::::put(self.byte_fee); EntryFee::::put(self.entry_fee); - StoragePeriod::::put(self.storage_period); + RetentionPeriod::::put(self.retention_period); } } @@ -535,9 +539,9 @@ pub mod pallet { pub fn entry_fee() -> Option> { EntryFee::::get() } - /// Get StoragePeriod storage information from the outside of this pallet. - pub fn storage_period() -> BlockNumberFor { - StoragePeriod::::get() + /// Get RetentionPeriod storage information from the outside of this pallet. + pub fn retention_period() -> BlockNumberFor { + RetentionPeriod::::get() } fn apply_fee(sender: T::AccountId, size: u32) -> DispatchResult { diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs index 25f44b953bfb2..939c7d18ff21c 100644 --- a/substrate/frame/transaction-storage/src/mock.rs +++ b/substrate/frame/transaction-storage/src/mock.rs @@ -68,7 +68,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { ..Default::default() }, transaction_storage: pallet_transaction_storage::GenesisConfig:: { - storage_period: 10, + retention_period: 10, byte_fee: 2, entry_fee: 200, }, diff --git a/substrate/primitives/transaction-storage-proof/src/lib.rs b/substrate/primitives/transaction-storage-proof/src/lib.rs index ed81233f9c76b..55ea1276e3c1a 100644 --- a/substrate/primitives/transaction-storage-proof/src/lib.rs +++ b/substrate/primitives/transaction-storage-proof/src/lib.rs @@ -168,14 +168,14 @@ pub mod registration { pub fn new_data_provider( client: &C, parent: &B::Hash, - storage_period: NumberFor, + retention_period: NumberFor, ) -> Result where B: BlockT, C: IndexedBody, { let parent_number = client.number(*parent)?.unwrap_or(Zero::zero()); - let number = parent_number.saturating_add(One::one()).saturating_sub(storage_period); + let number = parent_number.saturating_add(One::one()).saturating_sub(retention_period); if number.is_zero() { // Too early to collect proofs. return Ok(InherentDataProvider::new(None)); diff --git a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs index 9e20b3c800619..b7d920a8a8f61 100644 --- a/substrate/primitives/transaction-storage-proof/src/runtime_api.rs +++ b/substrate/primitives/transaction-storage-proof/src/runtime_api.rs @@ -22,7 +22,7 @@ use sp_runtime::traits::NumberFor; sp_api::decl_runtime_apis! { /// Runtime API trait for transaction storage support. pub trait TransactionStorageApi { - /// Get the actual value of a storage period in blocks. - fn storage_period() -> NumberFor; + /// Get the actual value of a retention period in blocks. + fn retention_period() -> NumberFor; } } From 863492fb65e38ac12230428a59d6a80c8ba3cf4e Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 11:57:32 +0000 Subject: [PATCH 18/19] Update from github-actions[bot] running command 'fmt' --- substrate/frame/transaction-storage/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/transaction-storage/src/lib.rs b/substrate/frame/transaction-storage/src/lib.rs index b9fbcb51fbec7..253eb2cd06b68 100644 --- a/substrate/frame/transaction-storage/src/lib.rs +++ b/substrate/frame/transaction-storage/src/lib.rs @@ -279,8 +279,8 @@ pub mod pallet { #[pallet::call] impl Pallet { /// 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. + /// `MaxTransactionSize`. Data will be removed after `RetentionPeriod` blocks, unless + /// `renew` is called. /// /// Emits [`Stored`](Event::Stored) when successful. /// From c92a3fd6cbd16867c8f82b4bf7264e2914bd737d Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 17 Dec 2025 13:06:46 +0100 Subject: [PATCH 19/19] Update prdoc/pr_10656.prdoc --- prdoc/pr_10656.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_10656.prdoc b/prdoc/pr_10656.prdoc index c7648c33434db..edd6e454511d0 100644 --- a/prdoc/pr_10656.prdoc +++ b/prdoc/pr_10656.prdoc @@ -10,4 +10,4 @@ crates: - name: sp-transaction-storage-proof bump: major - name: pallet-transaction-storage - bump: minor + bump: major