diff --git a/.github/workflows/runtimes-matrix.json b/.github/workflows/runtimes-matrix.json
index 104e73521331..ff16b7397247 100644
--- a/.github/workflows/runtimes-matrix.json
+++ b/.github/workflows/runtimes-matrix.json
@@ -145,7 +145,7 @@
{
"name": "glutton-westend",
"package": "glutton-westend-runtime",
- "path": "cumulus/parachains/runtimes/gluttons/glutton-westend",
+ "path": "cumulus/parachains/runtimes/glutton/glutton-westend",
"header": "cumulus/file_header.txt",
"template": "cumulus/templates/xcm-bench-template.hbs",
"bench_features": "runtime-benchmarks",
diff --git a/Cargo.lock b/Cargo.lock
index 3c55a14256c5..b0fb0586be38 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -959,11 +959,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -1095,11 +1095,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -2666,11 +2666,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -2905,11 +2905,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -3645,11 +3645,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -3952,11 +3952,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -4095,11 +4095,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -4196,11 +4196,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -5074,6 +5074,25 @@ dependencies = [
"sp-runtime 39.0.2",
]
+[[package]]
+name = "cumulus-pallet-weight-reclaim"
+version = "1.0.0"
+dependencies = [
+ "cumulus-primitives-proof-size-hostfunction 0.2.0",
+ "cumulus-primitives-storage-weight-reclaim 1.0.0",
+ "derivative",
+ "docify",
+ "frame-benchmarking 28.0.0",
+ "frame-support 28.0.0",
+ "frame-system 28.0.0",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-io 30.0.0",
+ "sp-runtime 31.0.1",
+ "sp-trie 29.0.0",
+]
+
[[package]]
name = "cumulus-pallet-xcm"
version = "0.7.0"
@@ -5524,10 +5543,10 @@ dependencies = [
name = "cumulus-test-client"
version = "0.1.0"
dependencies = [
+ "cumulus-pallet-weight-reclaim",
"cumulus-primitives-core 0.7.0",
"cumulus-primitives-parachain-inherent 0.7.0",
"cumulus-primitives-proof-size-hostfunction 0.2.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-test-relay-sproof-builder 0.7.0",
"cumulus-test-runtime",
"cumulus-test-service",
@@ -5589,9 +5608,9 @@ version = "0.1.0"
dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"frame-executive 28.0.0",
"frame-support 28.0.0",
"frame-system 28.0.0",
@@ -5643,8 +5662,8 @@ dependencies = [
"cumulus-client-pov-recovery",
"cumulus-client-service",
"cumulus-pallet-parachain-system 0.7.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-relay-chain-inprocess-interface",
"cumulus-relay-chain-interface",
"cumulus-relay-chain-minimal-node",
@@ -16742,11 +16761,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"enumflags2",
"frame-benchmarking 28.0.0",
@@ -16845,11 +16864,11 @@ dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
"cumulus-pallet-session-benchmarking 9.0.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"enumflags2",
"frame-benchmarking 28.0.0",
@@ -18645,6 +18664,7 @@ dependencies = [
"cumulus-pallet-parachain-system-proc-macro 0.6.0",
"cumulus-pallet-session-benchmarking 9.0.0",
"cumulus-pallet-solo-to-para 0.7.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-ping 0.7.0",
@@ -19233,8 +19253,8 @@ dependencies = [
"cumulus-client-service",
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-primitives-proof-size-hostfunction 0.2.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"docify",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
@@ -21447,12 +21467,12 @@ version = "0.6.0"
dependencies = [
"cumulus-pallet-aura-ext 0.7.0",
"cumulus-pallet-parachain-system 0.7.0",
+ "cumulus-pallet-weight-reclaim",
"cumulus-pallet-xcm 0.7.0",
"cumulus-pallet-xcmp-queue 0.7.0",
"cumulus-ping 0.7.0",
"cumulus-primitives-aura 0.7.0",
"cumulus-primitives-core 0.7.0",
- "cumulus-primitives-storage-weight-reclaim 1.0.0",
"cumulus-primitives-utility 0.7.0",
"frame-benchmarking 28.0.0",
"frame-executive 28.0.0",
diff --git a/Cargo.toml b/Cargo.toml
index 64a11a340d10..c917a8a8fead 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -83,6 +83,7 @@ members = [
"cumulus/pallets/parachain-system/proc-macro",
"cumulus/pallets/session-benchmarking",
"cumulus/pallets/solo-to-para",
+ "cumulus/pallets/weight-reclaim",
"cumulus/pallets/xcm",
"cumulus/pallets/xcmp-queue",
"cumulus/parachains/common",
@@ -717,6 +718,7 @@ cumulus-pallet-parachain-system = { path = "cumulus/pallets/parachain-system", d
cumulus-pallet-parachain-system-proc-macro = { path = "cumulus/pallets/parachain-system/proc-macro", default-features = false }
cumulus-pallet-session-benchmarking = { path = "cumulus/pallets/session-benchmarking", default-features = false }
cumulus-pallet-solo-to-para = { path = "cumulus/pallets/solo-to-para", default-features = false }
+cumulus-pallet-weight-reclaim = { path = "cumulus/pallets/weight-reclaim", default-features = false }
cumulus-pallet-xcm = { path = "cumulus/pallets/xcm", default-features = false }
cumulus-pallet-xcmp-queue = { path = "cumulus/pallets/xcmp-queue", default-features = false }
cumulus-ping = { path = "cumulus/parachains/pallets/ping", default-features = false }
diff --git a/cumulus/pallets/weight-reclaim/Cargo.toml b/cumulus/pallets/weight-reclaim/Cargo.toml
new file mode 100644
index 000000000000..8bde6abaff6a
--- /dev/null
+++ b/cumulus/pallets/weight-reclaim/Cargo.toml
@@ -0,0 +1,63 @@
+[package]
+name = "cumulus-pallet-weight-reclaim"
+version = "1.0.0"
+authors.workspace = true
+edition.workspace = true
+license = "Apache-2.0"
+homepage.workspace = true
+repository.workspace = true
+description = "pallet and transaction extensions for accurate proof size reclaim"
+
+[lints]
+workspace = true
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+# Substrate dependencies
+sp-io = { workspace = true }
+sp-runtime = { workspace = true }
+sp-trie = { workspace = true }
+
+cumulus-primitives-storage-weight-reclaim = { workspace = true }
+frame-benchmarking = { optional = true, workspace = true }
+frame-support = { workspace = true }
+frame-system = { workspace = true }
+
+# Other dependencies
+codec = { features = ["derive"], workspace = true }
+derivative = { features = ["use_core"], workspace = true }
+docify = { workspace = true }
+log = { workspace = true, default-features = true }
+scale-info = { features = ["derive"], workspace = true }
+
+[dev-dependencies]
+cumulus-primitives-proof-size-hostfunction = { workspace = true }
+
+[features]
+default = ["std"]
+std = [
+ "codec/std",
+ "cumulus-primitives-proof-size-hostfunction/std",
+ "cumulus-primitives-storage-weight-reclaim/std",
+ "frame-benchmarking?/std",
+ "frame-support/std",
+ "frame-system/std",
+ "log/std",
+ "scale-info/std",
+ "sp-io/std",
+ "sp-runtime/std",
+ "sp-trie/std",
+]
+runtime-benchmarks = [
+ "frame-benchmarking/runtime-benchmarks",
+ "frame-support/runtime-benchmarks",
+ "frame-system/runtime-benchmarks",
+ "sp-runtime/runtime-benchmarks",
+]
+try-runtime = [
+ "frame-support/try-runtime",
+ "frame-system/try-runtime",
+ "sp-runtime/try-runtime",
+]
diff --git a/cumulus/pallets/weight-reclaim/src/benchmarks.rs b/cumulus/pallets/weight-reclaim/src/benchmarks.rs
new file mode 100644
index 000000000000..78bebc967d96
--- /dev/null
+++ b/cumulus/pallets/weight-reclaim/src/benchmarks.rs
@@ -0,0 +1,71 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus 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.
+
+// Cumulus 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 Cumulus. If not, see .
+
+#![cfg(feature = "runtime-benchmarks")]
+
+use super::*;
+use frame_support::pallet_prelude::{DispatchClass, Pays};
+use frame_system::RawOrigin;
+use sp_runtime::traits::{AsTransactionAuthorizedOrigin, DispatchTransaction};
+
+#[frame_benchmarking::v2::benchmarks(
+ where T: Send + Sync,
+ ::RuntimeCall:
+ Dispatchable,
+ ::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+)]
+mod bench {
+ use super::*;
+ use frame_benchmarking::impl_test_function;
+
+ #[benchmark]
+ fn storage_weight_reclaim() {
+ let ext = StorageWeightReclaim::::new(());
+
+ let origin = RawOrigin::Root.into();
+ let call = T::RuntimeCall::from(frame_system::Call::remark { remark: alloc::vec![] });
+
+ let overestimate = 10_000;
+ let info = DispatchInfo {
+ call_weight: Weight::zero().add_proof_size(overestimate),
+ extension_weight: Weight::zero(),
+ class: DispatchClass::Normal,
+ pays_fee: Pays::No,
+ };
+
+ let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No };
+
+ let mut block_weight = frame_system::ConsumedWeight::default();
+ block_weight.accrue(Weight::from_parts(0, overestimate), info.class);
+
+ frame_system::BlockWeight::::put(block_weight);
+
+ #[block]
+ {
+ assert!(ext.test_run(origin, &call, &info, 0, 0, |_| Ok(post_info)).unwrap().is_ok());
+ }
+
+ let final_block_proof_size =
+ frame_system::BlockWeight::::get().get(info.class).proof_size();
+
+ assert!(
+ final_block_proof_size < overestimate,
+ "The proof size measured should be less than {overestimate}"
+ );
+ }
+
+ impl_benchmark_test_suite!(Pallet, crate::tests::setup_test_ext_default(), crate::tests::Test);
+}
diff --git a/cumulus/pallets/weight-reclaim/src/lib.rs b/cumulus/pallets/weight-reclaim/src/lib.rs
new file mode 100644
index 000000000000..bd9929033af1
--- /dev/null
+++ b/cumulus/pallets/weight-reclaim/src/lib.rs
@@ -0,0 +1,311 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus 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.
+
+// Cumulus 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 Cumulus. If not, see .
+
+//! Pallet and transaction extensions to reclaim PoV proof size weight after an extrinsic has been
+//! applied.
+//!
+//! This crate provides:
+//! * [`StorageWeightReclaim`] transaction extension: it must wrap the whole transaction extension
+//! pipeline.
+//! * The pallet required for the transaction extensions weight information and benchmarks.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+extern crate alloc;
+#[cfg(not(feature = "std"))]
+use alloc::vec::Vec;
+use codec::{Decode, Encode};
+use cumulus_primitives_storage_weight_reclaim::get_proof_size;
+use derivative::Derivative;
+use frame_support::{
+ dispatch::{DispatchInfo, PostDispatchInfo},
+ pallet_prelude::Weight,
+ traits::Defensive,
+};
+use scale_info::TypeInfo;
+use sp_runtime::{
+ traits::{DispatchInfoOf, Dispatchable, Implication, PostDispatchInfoOf, TransactionExtension},
+ transaction_validity::{TransactionSource, TransactionValidityError, ValidTransaction},
+ DispatchResult,
+};
+
+#[cfg(feature = "runtime-benchmarks")]
+pub mod benchmarks;
+#[cfg(test)]
+mod tests;
+mod weights;
+
+pub use pallet::*;
+pub use weights::WeightInfo;
+
+const LOG_TARGET: &'static str = "runtime::storage_reclaim_pallet";
+
+/// Pallet to use alongside the transaction extension [`StorageWeightReclaim`], the pallet provides
+/// weight information and benchmarks.
+#[frame_support::pallet]
+pub mod pallet {
+ use super::*;
+
+ #[pallet::pallet]
+ pub struct Pallet(_);
+
+ #[pallet::config]
+ pub trait Config: frame_system::Config {
+ type WeightInfo: WeightInfo;
+ }
+}
+
+/// Storage weight reclaim mechanism.
+///
+/// This extension must wrap all the transaction extensions:
+#[doc = docify::embed!("./src/tests.rs", Tx)]
+///
+/// This extension checks the size of the node-side storage proof before and after executing a given
+/// extrinsic using the proof size host function. The difference between benchmarked and used weight
+/// is reclaimed.
+///
+/// If the benchmark was underestimating the proof size, then it is added to the block weight.
+///
+/// For the time part of the weight, it does same as system `WeightReclaim` extension, it
+/// calculates the unused weight using the post information and reclaim the unused weight.
+/// So this extension can be used as a drop-in replacement for `WeightReclaim` extension for
+/// parachains.
+#[derive(Encode, Decode, TypeInfo, Derivative)]
+#[derivative(
+ Clone(bound = "S: Clone"),
+ Eq(bound = "S: Eq"),
+ PartialEq(bound = "S: PartialEq"),
+ Default(bound = "S: Default")
+)]
+#[scale_info(skip_type_params(T))]
+pub struct StorageWeightReclaim(pub S, core::marker::PhantomData);
+
+impl StorageWeightReclaim {
+ /// Create a new `StorageWeightReclaim` instance.
+ pub fn new(s: S) -> Self {
+ Self(s, Default::default())
+ }
+}
+
+impl From for StorageWeightReclaim {
+ fn from(s: S) -> Self {
+ Self::new(s)
+ }
+}
+
+impl core::fmt::Debug for StorageWeightReclaim {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
+ #[cfg(feature = "std")]
+ let _ = write!(f, "StorageWeightReclaim<{:?}>", self.0);
+
+ #[cfg(not(feature = "std"))]
+ let _ = write!(f, "StorageWeightReclaim");
+
+ Ok(())
+ }
+}
+
+impl>
+ TransactionExtension for StorageWeightReclaim
+where
+ T::RuntimeCall: Dispatchable,
+{
+ const IDENTIFIER: &'static str = "StorageWeightReclaim