Skip to content

Commit 63c73bf

Browse files
gui1117actions-usergeorgepisaltuggwpezskunert
authored
Implement cumulus StorageWeightReclaim as wrapping transaction extension + frame system ReclaimWeight (#6140)
(rebasing of #5234) ## Issues: * Transaction extensions have weights and refund weight. So the reclaiming of unused weight must happen last in the transaction extension pipeline. Currently it is inside `CheckWeight`. * cumulus storage weight reclaim transaction extension misses the proof size of logic happening prior to itself. ## Done: * a new storage `ExtrinsicWeightReclaimed` in frame-system. Any logic which attempts to do some reclaim must use this storage to avoid double reclaim. * a new function `reclaim_weight` in frame-system pallet: info and post info in arguments, read the already reclaimed weight, calculate the new unused weight from info and post info. do the more accurate reclaim if higher. * `CheckWeight` is unchanged and still reclaim the weight in post dispatch * `ReclaimWeight` is a new transaction extension in frame system. For solo chains it must be used last in the transactino extension pipeline. It does the final most accurate reclaim * `StorageWeightReclaim` is moved from cumulus primitives into its own pallet (in order to define benchmark) and is changed into a wrapping transaction extension. It does the recording of proof size and does the reclaim using this recording and the info and post info. So parachains don't need to use `ReclaimWeight`. But also if they use it, there is no bug. ```rust /// The TransactionExtension to the basic transaction logic. pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim< Runtime, ( frame_system::CheckNonZeroSender<Runtime>, frame_system::CheckSpecVersion<Runtime>, frame_system::CheckTxVersion<Runtime>, frame_system::CheckGenesis<Runtime>, frame_system::CheckEra<Runtime>, frame_system::CheckNonce<Runtime>, frame_system::CheckWeight<Runtime>, pallet_transaction_payment::ChargeTransactionPayment<Runtime>, BridgeRejectObsoleteHeadersAndMessages, (bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages,), frame_metadata_hash_extension::CheckMetadataHash<Runtime>, ), >; ``` --------- Co-authored-by: GitHub Action <[email protected]> Co-authored-by: georgepisaltu <[email protected]> Co-authored-by: Oliver Tale-Yazdi <[email protected]> Co-authored-by: Sebastian Kunert <[email protected]> Co-authored-by: command-bot <>
1 parent b5a5ac4 commit 63c73bf

File tree

113 files changed

+4007
-666
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+4007
-666
lines changed

.github/workflows/runtimes-matrix.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
{
146146
"name": "glutton-westend",
147147
"package": "glutton-westend-runtime",
148-
"path": "cumulus/parachains/runtimes/gluttons/glutton-westend",
148+
"path": "cumulus/parachains/runtimes/glutton/glutton-westend",
149149
"header": "cumulus/file_header.txt",
150150
"template": "cumulus/templates/xcm-bench-template.hbs",
151151
"bench_features": "runtime-benchmarks",

Cargo.lock

+35-15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ members = [
8383
"cumulus/pallets/parachain-system/proc-macro",
8484
"cumulus/pallets/session-benchmarking",
8585
"cumulus/pallets/solo-to-para",
86+
"cumulus/pallets/weight-reclaim",
8687
"cumulus/pallets/xcm",
8788
"cumulus/pallets/xcmp-queue",
8889
"cumulus/parachains/common",
@@ -717,6 +718,7 @@ cumulus-pallet-parachain-system = { path = "cumulus/pallets/parachain-system", d
717718
cumulus-pallet-parachain-system-proc-macro = { path = "cumulus/pallets/parachain-system/proc-macro", default-features = false }
718719
cumulus-pallet-session-benchmarking = { path = "cumulus/pallets/session-benchmarking", default-features = false }
719720
cumulus-pallet-solo-to-para = { path = "cumulus/pallets/solo-to-para", default-features = false }
721+
cumulus-pallet-weight-reclaim = { path = "cumulus/pallets/weight-reclaim", default-features = false }
720722
cumulus-pallet-xcm = { path = "cumulus/pallets/xcm", default-features = false }
721723
cumulus-pallet-xcmp-queue = { path = "cumulus/pallets/xcmp-queue", default-features = false }
722724
cumulus-ping = { path = "cumulus/parachains/pallets/ping", default-features = false }
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
[package]
2+
name = "cumulus-pallet-weight-reclaim"
3+
version = "1.0.0"
4+
authors.workspace = true
5+
edition.workspace = true
6+
license = "Apache-2.0"
7+
homepage.workspace = true
8+
repository.workspace = true
9+
description = "pallet and transaction extensions for accurate proof size reclaim"
10+
11+
[lints]
12+
workspace = true
13+
14+
[package.metadata.docs.rs]
15+
targets = ["x86_64-unknown-linux-gnu"]
16+
17+
[dependencies]
18+
# Substrate dependencies
19+
sp-io = { workspace = true }
20+
sp-runtime = { workspace = true }
21+
sp-trie = { workspace = true }
22+
23+
cumulus-primitives-storage-weight-reclaim = { workspace = true }
24+
frame-benchmarking = { optional = true, workspace = true }
25+
frame-support = { workspace = true }
26+
frame-system = { workspace = true }
27+
28+
# Other dependencies
29+
codec = { features = ["derive"], workspace = true }
30+
derivative = { features = ["use_core"], workspace = true }
31+
docify = { workspace = true }
32+
log = { workspace = true, default-features = true }
33+
scale-info = { features = ["derive"], workspace = true }
34+
35+
[dev-dependencies]
36+
cumulus-primitives-proof-size-hostfunction = { workspace = true }
37+
38+
[features]
39+
default = ["std"]
40+
std = [
41+
"codec/std",
42+
"cumulus-primitives-proof-size-hostfunction/std",
43+
"cumulus-primitives-storage-weight-reclaim/std",
44+
"frame-benchmarking?/std",
45+
"frame-support/std",
46+
"frame-system/std",
47+
"log/std",
48+
"scale-info/std",
49+
"sp-io/std",
50+
"sp-runtime/std",
51+
"sp-trie/std",
52+
]
53+
runtime-benchmarks = [
54+
"frame-benchmarking/runtime-benchmarks",
55+
"frame-support/runtime-benchmarks",
56+
"frame-system/runtime-benchmarks",
57+
"sp-runtime/runtime-benchmarks",
58+
]
59+
try-runtime = [
60+
"frame-support/try-runtime",
61+
"frame-system/try-runtime",
62+
"sp-runtime/try-runtime",
63+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (C) Parity Technologies (UK) Ltd.
2+
// This file is part of Cumulus.
3+
4+
// Cumulus is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Cumulus is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
16+
17+
#![cfg(feature = "runtime-benchmarks")]
18+
19+
use super::*;
20+
use frame_support::pallet_prelude::{DispatchClass, Pays};
21+
use frame_system::RawOrigin;
22+
use sp_runtime::traits::{AsTransactionAuthorizedOrigin, DispatchTransaction};
23+
24+
#[frame_benchmarking::v2::benchmarks(
25+
where T: Send + Sync,
26+
<T as frame_system::Config>::RuntimeCall:
27+
Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
28+
<T as frame_system::Config>::RuntimeOrigin: AsTransactionAuthorizedOrigin,
29+
)]
30+
mod bench {
31+
use super::*;
32+
use frame_benchmarking::impl_test_function;
33+
34+
#[benchmark]
35+
fn storage_weight_reclaim() {
36+
let ext = StorageWeightReclaim::<T, ()>::new(());
37+
38+
let origin = RawOrigin::Root.into();
39+
let call = T::RuntimeCall::from(frame_system::Call::remark { remark: alloc::vec![] });
40+
41+
let overestimate = 10_000;
42+
let info = DispatchInfo {
43+
call_weight: Weight::zero().add_proof_size(overestimate),
44+
extension_weight: Weight::zero(),
45+
class: DispatchClass::Normal,
46+
pays_fee: Pays::No,
47+
};
48+
49+
let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No };
50+
51+
let mut block_weight = frame_system::ConsumedWeight::default();
52+
block_weight.accrue(Weight::from_parts(0, overestimate), info.class);
53+
54+
frame_system::BlockWeight::<T>::put(block_weight);
55+
56+
#[block]
57+
{
58+
assert!(ext.test_run(origin, &call, &info, 0, 0, |_| Ok(post_info)).unwrap().is_ok());
59+
}
60+
61+
let final_block_proof_size =
62+
frame_system::BlockWeight::<T>::get().get(info.class).proof_size();
63+
64+
assert!(
65+
final_block_proof_size < overestimate,
66+
"The proof size measured should be less than {overestimate}"
67+
);
68+
}
69+
70+
impl_benchmark_test_suite!(Pallet, crate::tests::setup_test_ext_default(), crate::tests::Test);
71+
}

0 commit comments

Comments
 (0)