Skip to content

Commit 492786d

Browse files
paritytech-release-backport-bot[bot]ggwpezgithub-actions[bot]EgorPopelyaev
authored
[stable2409] Backport #7785 (#8626)
Backport #7785 into `stable2409` from ggwpez. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> Signed-off-by: Oliver Tale-Yazdi <[email protected]> Co-authored-by: Oliver Tale-Yazdi <[email protected]> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Egor_P <[email protected]>
1 parent 9d2cd7d commit 492786d

5 files changed

Lines changed: 94 additions & 4 deletions

File tree

prdoc/pr_7785.prdoc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
title: 'pallet scheduler: fix weight and add safety checks'
2+
doc:
3+
- audience: Runtime Dev
4+
description: |-
5+
Changes:
6+
- Add runtime integrity test for scheduler pallet to ensure that lookups use sensible weights
7+
- Check all passed storage names in the omni bencher to be known by FRAME metadata
8+
- Trim storage names in omni bencher to fix V1 bench syntax bug
9+
- Fix V1 bench syntax storage name sanitization for specific Rust versions
10+
11+
I re-ran the benchmarks with the omni-bencher modifications and it did not change the [proof size](https://weights.tasty.limo/compare?repo=polkadot-sdk&threshold=1&path_pattern=substrate%2Fframe%2F**%2Fsrc%2Fweights.rs%2Cpolkadot%2Fruntime%2F*%2Fsrc%2Fweights%2F**%2F*.rs%2Cpolkadot%2Fbridges%2Fmodules%2F*%2Fsrc%2Fweights.rs%2Ccumulus%2F**%2Fweights%2F*.rs%2Ccumulus%2F**%2Fweights%2Fxcm%2F*.rs%2Ccumulus%2F**%2Fsrc%2Fweights.rs&method=asymptotic&ignore_errors=true&unit=proof&old=cc0142510b81dcf1c1a22f7dc164c453c25287e6&new=bb19d78821eaeaf2262f6a23ee45f83dd4f94d29). I reverted [the commit](https://github.com/paritytech/polkadot-sdk/pull/7785/commits/bb19d78821eaeaf2262f6a23ee45f83dd4f94d29) afterwards to reduce the noise for reviewers.
12+
crates:
13+
- name: frame-benchmarking-cli
14+
bump: minor
15+
- name: frame-benchmarking
16+
bump: minor
17+
- name: pallet-scheduler
18+
bump: minor
19+
- name: asset-hub-westend-runtime
20+
bump: minor
21+
- name: westend-runtime
22+
bump: minor

substrate/frame/benchmarking/src/v1.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,8 @@ macro_rules! impl_benchmark {
10081008
$(
10091009
(stringify!($pov_name).as_bytes().to_vec(),
10101010
$crate::__private::vec![
1011-
$( ( stringify!($storage).as_bytes().to_vec(),
1011+
// Stringify sometimes includes spaces, depending on the Rust version.
1012+
$( ( stringify!($storage).replace(" ", "").as_bytes().to_vec(),
10121013
stringify!($pov_mode).as_bytes().to_vec() ), )*
10131014
]),
10141015
)*

substrate/frame/scheduler/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,27 @@ pub mod pallet {
381381
Self::service_agendas(&mut weight_counter, now, u32::max_value());
382382
weight_counter.consumed()
383383
}
384+
385+
#[cfg(feature = "std")]
386+
fn integrity_test() {
387+
/// Calculate the maximum weight that a lookup of a given size can take.
388+
fn lookup_weight<T: Config>(s: usize) -> Weight {
389+
T::WeightInfo::service_agendas_base() +
390+
T::WeightInfo::service_agenda_base(T::MaxScheduledPerBlock::get()) +
391+
T::WeightInfo::service_task(Some(s), true, true)
392+
}
393+
394+
let limit = sp_runtime::Perbill::from_percent(90) * T::MaximumWeight::get();
395+
396+
let small_lookup = lookup_weight::<T>(128);
397+
assert!(small_lookup.all_lte(limit), "Must be possible to submit a small lookup");
398+
399+
let medium_lookup = lookup_weight::<T>(1024);
400+
assert!(medium_lookup.all_lte(limit), "Must be possible to submit a medium lookup");
401+
402+
let large_lookup = lookup_weight::<T>(1024 * 1024);
403+
assert!(large_lookup.all_lte(limit), "Must be possible to submit a large lookup");
404+
}
384405
}
385406

386407
#[pallet::call]

substrate/utils/frame/benchmarking-cli/src/pallet/command.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ impl PalletCmd {
281281
let mut timer = time::SystemTime::now();
282282
// Maps (pallet, extrinsic) to its component ranges.
283283
let mut component_ranges = HashMap::<(String, String), Vec<ComponentRange>>::new();
284-
let pov_modes = Self::parse_pov_modes(&benchmarks_to_run)?;
284+
let pov_modes =
285+
Self::parse_pov_modes(&benchmarks_to_run, &storage_info, self.ignore_unknown_pov_mode)?;
285286
let mut failed = Vec::<(String, String)>::new();
286287

287288
'outer: for (i, SelectedBenchmark { pallet, extrinsic, components, .. }) in
@@ -889,22 +890,29 @@ impl PalletCmd {
889890
}
890891

891892
/// Parses the PoV modes per benchmark that were specified by the `#[pov_mode]` attribute.
892-
fn parse_pov_modes(benchmarks: &Vec<SelectedBenchmark>) -> Result<PovModesMap> {
893+
fn parse_pov_modes(
894+
benchmarks: &Vec<SelectedBenchmark>,
895+
storage_info: &[StorageInfo],
896+
ignore_unknown_pov_mode: bool,
897+
) -> Result<PovModesMap> {
893898
use std::collections::hash_map::Entry;
894899
let mut parsed = PovModesMap::new();
895900

896901
for SelectedBenchmark { pallet, extrinsic, pov_modes, .. } in benchmarks {
897902
for (pallet_storage, mode) in pov_modes {
898903
let mode = PovEstimationMode::from_str(&mode)?;
904+
let pallet_storage = pallet_storage.replace(" ", "");
899905
let splits = pallet_storage.split("::").collect::<Vec<_>>();
906+
900907
if splits.is_empty() || splits.len() > 2 {
901908
return Err(format!(
902909
"Expected 'Pallet::Storage' as storage name but got: {}",
903910
pallet_storage
904911
)
905912
.into())
906913
}
907-
let (pov_pallet, pov_storage) = (splits[0], splits.get(1).unwrap_or(&"ALL"));
914+
let (pov_pallet, pov_storage) =
915+
(splits[0].trim(), splits.get(1).unwrap_or(&"ALL").trim());
908916

909917
match parsed
910918
.entry((pallet.clone(), extrinsic.clone()))
@@ -923,9 +931,43 @@ impl PalletCmd {
923931
}
924932
}
925933
}
934+
log::debug!("Parsed PoV modes: {:?}", parsed);
935+
Self::check_pov_modes(&parsed, storage_info, ignore_unknown_pov_mode)?;
936+
926937
Ok(parsed)
927938
}
928939

940+
fn check_pov_modes(
941+
pov_modes: &PovModesMap,
942+
storage_info: &[StorageInfo],
943+
ignore_unknown_pov_mode: bool,
944+
) -> Result<()> {
945+
// Check that all PoV modes are valid pallet storage keys
946+
for (pallet, storage) in pov_modes.values().flat_map(|i| i.keys()) {
947+
let (mut found_pallet, mut found_storage) = (false, false);
948+
949+
for info in storage_info {
950+
if pallet == "ALL" || info.pallet_name == pallet.as_bytes() {
951+
found_pallet = true;
952+
}
953+
if storage == "ALL" || info.storage_name == storage.as_bytes() {
954+
found_storage = true;
955+
}
956+
}
957+
if !found_pallet || !found_storage {
958+
let err = format!("The PoV mode references an unknown storage item or pallet: `{}::{}`. You can ignore this warning by specifying `--ignore-unknown-pov-mode`", pallet, storage);
959+
960+
if ignore_unknown_pov_mode {
961+
log::warn!(target: LOG_TARGET, "Error demoted to warning due to `--ignore-unknown-pov-mode`: {}", err);
962+
} else {
963+
return Err(err.into());
964+
}
965+
}
966+
}
967+
968+
Ok(())
969+
}
970+
929971
/// Sanity check the CLI arguments.
930972
fn check_args(&self) -> Result<()> {
931973
if self.runtime.is_some() && self.shared_params.chain.is_some() {

substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ pub struct PalletCmd {
128128
#[arg(long, default_value("max-encoded-len"), value_enum)]
129129
pub default_pov_mode: command::PovEstimationMode,
130130

131+
/// Ignore the error when PoV modes reference unknown storage items or pallets.
132+
#[arg(long)]
133+
pub ignore_unknown_pov_mode: bool,
134+
131135
/// Set the heap pages while running benchmarks. If not set, the default value from the client
132136
/// is used.
133137
#[arg(long)]

0 commit comments

Comments
 (0)