Skip to content

Commit 6487749

Browse files
ggwpezjoepetrowski
andauthored
[FRAME] Warn on unchecked weight witness (#1818)
Adds a warning to FRAME pallets when a function argument that starts with `_` is used in the weight formula. This is in most cases an error since the weight witness needs to be checked. Example: ```rust #[pallet::call_index(0)] #[pallet::weight(T::SystemWeightInfo::remark(_remark.len() as u32))] pub fn remark(_origin: OriginFor<T>, _remark: Vec<u8>) -> DispatchResultWithPostInfo { Ok(().into()) } ``` Produces this warning: ```pre warning: use of deprecated constant `pallet::warnings::UncheckedWeightWitness_0::_w`: It is deprecated to not check weight witness data. Please instead ensure that all witness data for weight calculation is checked before usage. For more info see: <#1818> --> substrate/frame/system/src/lib.rs:424:40 | 424 | pub fn remark(_origin: OriginFor<T>, _remark: Vec<u8>) -> DispatchResultWithPostInfo { | ^^^^^^^ | = note: `#[warn(deprecated)]` on by default ``` Can be suppressed like this, since in this case it is legit: ```rust #[pallet::call_index(0)] #[pallet::weight(T::SystemWeightInfo::remark(remark.len() as u32))] pub fn remark(_origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo { let _ = remark; // We dont need to check the weight witness. Ok(().into()) } ``` Changes: - Add warning on uncheded weight witness - Respect `subkeys` limit in `System::kill_prefix` - Fix HRMP pallet and other warnings - Update`proc_macro_warning` dependency - Delete random folder `substrate/src/src` 🙈 - Adding Prdoc --------- Signed-off-by: Oliver Tale-Yazdi <[email protected]> Co-authored-by: joe petrowski <[email protected]>
1 parent e3c97e4 commit 6487749

File tree

19 files changed

+243
-340
lines changed

19 files changed

+243
-340
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

polkadot/runtime/parachains/src/hrmp.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -554,14 +554,26 @@ pub mod pallet {
554554
///
555555
/// Origin must be the `ChannelManager`.
556556
#[pallet::call_index(3)]
557-
#[pallet::weight(<T as Config>::WeightInfo::force_clean_hrmp(*_inbound, *_outbound))]
557+
#[pallet::weight(<T as Config>::WeightInfo::force_clean_hrmp(*num_inbound, *num_outbound))]
558558
pub fn force_clean_hrmp(
559559
origin: OriginFor<T>,
560560
para: ParaId,
561-
_inbound: u32,
562-
_outbound: u32,
561+
num_inbound: u32,
562+
num_outbound: u32,
563563
) -> DispatchResult {
564564
T::ChannelManager::ensure_origin(origin)?;
565+
566+
ensure!(
567+
HrmpIngressChannelsIndex::<T>::decode_len(para).unwrap_or_default() <=
568+
num_inbound as usize,
569+
Error::<T>::WrongWitness
570+
);
571+
ensure!(
572+
HrmpEgressChannelsIndex::<T>::decode_len(para).unwrap_or_default() <=
573+
num_outbound as usize,
574+
Error::<T>::WrongWitness
575+
);
576+
565577
Self::clean_hrmp_after_outgoing(&para);
566578
Ok(())
567579
}
@@ -575,9 +587,16 @@ pub mod pallet {
575587
///
576588
/// Origin must be the `ChannelManager`.
577589
#[pallet::call_index(4)]
578-
#[pallet::weight(<T as Config>::WeightInfo::force_process_hrmp_open(*_channels))]
579-
pub fn force_process_hrmp_open(origin: OriginFor<T>, _channels: u32) -> DispatchResult {
590+
#[pallet::weight(<T as Config>::WeightInfo::force_process_hrmp_open(*channels))]
591+
pub fn force_process_hrmp_open(origin: OriginFor<T>, channels: u32) -> DispatchResult {
580592
T::ChannelManager::ensure_origin(origin)?;
593+
594+
ensure!(
595+
HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32 <=
596+
channels,
597+
Error::<T>::WrongWitness
598+
);
599+
581600
let host_config = configuration::Pallet::<T>::config();
582601
Self::process_hrmp_open_channel_requests(&host_config);
583602
Ok(())
@@ -592,9 +611,16 @@ pub mod pallet {
592611
///
593612
/// Origin must be the `ChannelManager`.
594613
#[pallet::call_index(5)]
595-
#[pallet::weight(<T as Config>::WeightInfo::force_process_hrmp_close(*_channels))]
596-
pub fn force_process_hrmp_close(origin: OriginFor<T>, _channels: u32) -> DispatchResult {
614+
#[pallet::weight(<T as Config>::WeightInfo::force_process_hrmp_close(*channels))]
615+
pub fn force_process_hrmp_close(origin: OriginFor<T>, channels: u32) -> DispatchResult {
597616
T::ChannelManager::ensure_origin(origin)?;
617+
618+
ensure!(
619+
HrmpCloseChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32 <=
620+
channels,
621+
Error::<T>::WrongWitness
622+
);
623+
598624
Self::process_hrmp_close_channel_requests();
599625
Ok(())
600626
}

prdoc/pr_1818.prdoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
title: FRAME pallets warning for unchecked weight witness
2+
3+
doc:
4+
- audience: Core Dev
5+
description: |
6+
FRAME pallets now emit a warning when a call uses a function argument that starts with an underscore in its weight declaration.
7+
8+
migrations:
9+
db: [ ]
10+
runtime: [ ]
11+
12+
host_functions: []
13+
14+
crates:
15+
- name: "frame-support-procedural"
16+
semver: minor

substrate/frame/elections-phragmen/src/benchmarking.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ benchmarks! {
379379
let root = RawOrigin::Root;
380380
}: _(root, v, d)
381381
verify {
382-
assert_eq!(<Voting<T>>::iter().count() as u32, 0);
382+
assert_eq!(<Voting<T>>::iter().count() as u32, v - d);
383383
}
384384

385385
election_phragmen {

substrate/frame/elections-phragmen/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,15 +591,18 @@ pub mod pallet {
591591
/// ## Complexity
592592
/// - Check is_defunct_voter() details.
593593
#[pallet::call_index(5)]
594-
#[pallet::weight(T::WeightInfo::clean_defunct_voters(*_num_voters, *_num_defunct))]
594+
#[pallet::weight(T::WeightInfo::clean_defunct_voters(*num_voters, *num_defunct))]
595595
pub fn clean_defunct_voters(
596596
origin: OriginFor<T>,
597-
_num_voters: u32,
598-
_num_defunct: u32,
597+
num_voters: u32,
598+
num_defunct: u32,
599599
) -> DispatchResult {
600600
let _ = ensure_root(origin)?;
601+
601602
<Voting<T>>::iter()
603+
.take(num_voters as usize)
602604
.filter(|(_, x)| Self::is_defunct_voter(&x.votes))
605+
.take(num_defunct as usize)
603606
.for_each(|(dv, _)| Self::do_remove_voter(&dv));
604607

605608
Ok(())

substrate/frame/root-testing/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use sp_runtime::Perbill;
2929

3030
pub use pallet::*;
3131

32-
#[frame_support::pallet]
32+
#[frame_support::pallet(dev_mode)]
3333
pub mod pallet {
3434
use super::*;
3535
use frame_support::pallet_prelude::*;

substrate/frame/sudo/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,15 @@ pub mod pallet {
204204
/// ## Complexity
205205
/// - O(1).
206206
#[pallet::call_index(1)]
207-
#[pallet::weight((*_weight, call.get_dispatch_info().class))]
207+
#[pallet::weight((*weight, call.get_dispatch_info().class))]
208208
pub fn sudo_unchecked_weight(
209209
origin: OriginFor<T>,
210210
call: Box<<T as Config>::RuntimeCall>,
211-
_weight: Weight,
211+
weight: Weight,
212212
) -> DispatchResultWithPostInfo {
213213
// This is a public call, so we ensure that the origin is some signed account.
214214
let sender = ensure_signed(origin)?;
215+
let _ = weight; // We don't check the weight witness since it is a root call.
215216
ensure!(Self::key().map_or(false, |k| sender == k), Error::<T>::RequireSudo);
216217

217218
let res = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into());

substrate/frame/support/procedural/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ proc-macro2 = "1.0.56"
2323
quote = "1.0.28"
2424
syn = { version = "2.0.38", features = ["full"] }
2525
frame-support-procedural-tools = { path = "tools" }
26-
proc-macro-warning = { version = "0.4.2", default-features = false }
26+
proc-macro-warning = { version = "1.0.0", default-features = false }
2727
macro_magic = { version = "0.4.2", features = ["proc_support"] }
2828
expander = "2.0.0"
2929
sp-core-hashing = { path = "../../../primitives/core/hashing" }

substrate/frame/support/procedural/src/construct_runtime/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ fn construct_runtime_final_expansion(
414414
)
415415
.help_links(&["https://github.com/paritytech/substrate/pull/14437"])
416416
.span(where_section.span)
417-
.build(),
417+
.build_or_panic(),
418418
)
419419
});
420420

substrate/frame/support/procedural/src/pallet/expand/call.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
use crate::{
1919
pallet::{
20+
expand::warnings::{weight_constant_warning, weight_witness_warning},
2021
parse::call::{CallVariantDef, CallWeightDef},
2122
Def,
2223
},
2324
COUNTER,
2425
};
2526
use proc_macro2::TokenStream as TokenStream2;
27+
use proc_macro_warning::Warning;
2628
use quote::{quote, ToTokens};
2729
use syn::spanned::Spanned;
2830

@@ -68,7 +70,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
6870
continue
6971
}
7072

71-
let warning = proc_macro_warning::Warning::new_deprecated("ImplicitCallIndex")
73+
let warning = Warning::new_deprecated("ImplicitCallIndex")
7274
.index(call_index_warnings.len())
7375
.old("use implicit call indices")
7476
.new("ensure that all calls have a `pallet::call_index` attribute or put the pallet into `dev` mode")
@@ -77,7 +79,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
7779
"https://github.com/paritytech/substrate/pull/11381"
7880
])
7981
.span(method.name.span())
80-
.build();
82+
.build_or_panic();
8183
call_index_warnings.push(warning);
8284
}
8385

@@ -86,18 +88,12 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
8688
for method in &methods {
8789
match &method.weight {
8890
CallWeightDef::DevModeDefault => fn_weight.push(syn::parse_quote!(0)),
89-
CallWeightDef::Immediate(e @ syn::Expr::Lit(lit)) if !def.dev_mode => {
90-
let warning = proc_macro_warning::Warning::new_deprecated("ConstantWeight")
91-
.index(weight_warnings.len())
92-
.old("use hard-coded constant as call weight")
93-
.new("benchmark all calls or put the pallet into `dev` mode")
94-
.help_link("https://github.com/paritytech/substrate/pull/13798")
95-
.span(lit.span())
96-
.build();
97-
weight_warnings.push(warning);
91+
CallWeightDef::Immediate(e) => {
92+
weight_constant_warning(e, def.dev_mode, &mut weight_warnings);
93+
weight_witness_warning(method, def.dev_mode, &mut weight_warnings);
94+
9895
fn_weight.push(e.into_token_stream());
9996
},
100-
CallWeightDef::Immediate(e) => fn_weight.push(e.into_token_stream()),
10197
CallWeightDef::Inherited => {
10298
let pallet_weight = def
10399
.call

0 commit comments

Comments
 (0)