mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 12:17:58 +00:00
49b6dfd2e5
* Cargo.lock after merge * Restore scale-info feature * Fully qualify TypeInfo derive * Skip PendingSwap T * Add missing skip_type_params attr * metadata docs features * Reduce pallet event attribute to struct * Cargo.lock * Update frame/balances/src/tests_composite.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Line widths check * Cargo.lock * Add scale-info/std * Update frame/system/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Use `skip_type_params` to remove `TypeInfo` requirements on checks * Revert "Remove unused Call metadata stuff" This reverts commit 41311f85 * Skip BalanceSwapAction type parameter * Remove unused event metadata macro * Update frame-metadata * Update primitives/npos-elections/compact/src/codec.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Manual TypeInfo for Header * Remove TypeInfo requirement for consts in BoundedVec etc. * Another TypeInfo bound removed * review: fix indentation * TypeInfo impls for Identity types * Add some todos to add custom TypeInfo impls * Update frame/support/procedural/src/pallet/expand/pallet_struct.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Add some todos to add custom TypeInfo impls * Add a test for manual Data TypeInfo impl * Add custom TypeInfo impl for Vote * Era custom TypeInfo crimes * Revert finality-grandpa version to 0.14.z * review: renamed module to pallet_constants_metadata * New line at end of file * Add missing scale-info/std * Update frame/support/src/storage/types/mod.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Remove StorageEntryType::Map unused flag * Add missing scale-info dependency after merge * SignedExtension::AdditionalSigned metadata * Update frame-metadata, use abbreviated docs and args fields * Update frame/example/Cargo.toml Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Add scale_info/std and remove unused scale-info dependency * Remove scale-info dependency * Remove treasury pallet::metadata * Remove redundant Event test * Add back scale-info as dev dependency * fix error metadata when no error defined in decl_module * Add Module3 to tests * Fix metadata test * Add docs feature to frame-support test * WIP fixing pallet metadata test * Remove redundant FunctionMetadata, FunctionArgumentMetadata as per https://github.com/paritytech/frame-metadata/pull/20 * Use main branch of frame-metadata * Use patch of scale-info for latest changes * Use latest patched scale-info * Manual TypeInfo for DigestItem * Manual TypeInfo for DigestItem * Update scale-info * Skip __Ignore variants for Error, depends on https://github.com/paritytech/scale-info/pull/117 * Named fields for FRAME v2 pallet Call variants * Named fields for FRAME v1 pallet Call variants * Add missing scale-info dependency * WIP expand benchmark call variant * fix benchmark with new function create a new function for each variant of a pallet call. This function is called by benchmarking macro in order not to break call creation with unnamed argument * fix tests * more fix * Fix staking tests * Fix offchain workers calls * Cherry pick rustfmt.toml from master * cargo +nightly-2021-06-22 fmt --all * Update to new call variant structs * More call variant struct updates * Remove unused import * More call variant structs * More call variant structs * Even more call variant structs * Mooar variant structs * Evermore variant structs * Call variant structs ad infinitum * Fmt * More call variants * Last call variant * Call variants all done? * Fix SS58Prefix type * Potential workaround for BitFlags<IdentityFields> TypeInfo * Enable docs capturing for Call, Event, and Error types * Fix IdentityFields TypeInfo * Remove metadata-docs feature * Add capture_docs = true for legacy Call, Event and Error types * Fmt * Fix metadata test type * Update benchmarks with call struct variants * Fmt * More test fixes * Fmt * Fix benches * Use latest capture_docs attr * Latest scale_info * Fmt * review: change &Vec to &[] * Remove pallet metadata attr * review: remove commented out test code * review: skip_type_params trailing comma suggestion * Update to scale-info 0.10.0 * Update construct_runtime ui tests, different because of metadata TypeInfo impls * Add some TypeInfo derives for UI tests * Update storage ensure span ui stderrs * Update call argument bound ui tests Possibly changed because change from tuple to struct variants? * Add scale-info dev dependency * Update to latest finality-grandpa release * review: missing newline * review: missing scale-info/std * review: remove duplicate scale-info/std * review: remove fully qualified TypeInfo * review: add missing scale-info/std * review: remove unnecessary imports. * Fmt * Use crates.io RC version of frame-metadata * Remove scale-info/std because it is a dev dependency * Add missing scale_info dev-dependency for test * Delete empty metadata folder * Fix sp_std import * review: improve manual UncheckedExtrinsic TypeInfo impl * review: use full scale-info for dev-dependency * Remove DefaultByteGetter impl * review: derive TypeInfo for generic header * Fmt * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update bin/node/executor/Cargo.toml Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update frame/identity/src/types.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update frame/support/src/dispatch.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Remove redundant derive * Simplify scale-info dependency * Strip underscore prefix from call variant struct names * Another underscore field * More underscore fields * Another underscore field * Update to frame-metadata 14.0.0-rc.2 with combined StorageEntryType::Map * Fmt * Revert weights formatting * Fix up some tests * Fix up some tests for StorageEntryTypeMetadata * scale-info dev dependency * Fix test error * Add missing TypeInfo derives * Add back missing scale-info dependency * Add back missing scale-info dependency * Fix npos compact impls * Cargo.lock * Fmt * Fix errors * Fmt * Fix renamed raw_solution field * Fix error * Fmt * Fix some benchmarks * Fmt * Stray R * Fix * Add missing TypeInfos * ui test fix * Fix line widths * Revert "ui test fix" This reverts commit 2d15ec058a216e3f92d713f1174603a2bb1eac65. * Upgrade to scale-info 0.11.0 * Revert "Upgrade to scale-info 0.11.0" This reverts commit 047bb179085a0059c36cd20ab405f55cf0867e28. * Add Runtime type * Update to scale-info 0.12 * Update to scale-info 1.0 * Update frame-metadata to version 14.0.0 * Patch finality-grandpa until release available * Fix metadata tests * Fix metadata tests * Fmt * Remove patched finality-grandpa * Fix tests, use scale_info imports * Fix pallet tests * Add BlockNumber TypeInfo bound * ui test fix * Cargo.lock * Remove pallet metadata * Cargo.lock * Add missing scale-info dependency * Remove pallet event metadata * Fix error * Fix collective errors * Semicolol * Fmt * Remove another metadata attribute * Add new variant to custom digest TypeInfo * Fmt * Cargo.lock from master * Remove comma lol * Fix example call error * Fix example call error properly Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
441 lines
15 KiB
Rust
441 lines
15 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) 2017-2021 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.
|
|
|
|
//! Block resource limits configuration structures.
|
|
//!
|
|
//! FRAME defines two resources that are limited within a block:
|
|
//! - Weight (execution cost/time)
|
|
//! - Length (block size)
|
|
//!
|
|
//! `frame_system` tracks consumption of each of these resources separately for each
|
|
//! `DispatchClass`. This module contains configuration object for both resources,
|
|
//! which should be passed to `frame_system` configuration when runtime is being set up.
|
|
|
|
use frame_support::weights::{constants, DispatchClass, OneOrMany, PerDispatchClass, Weight};
|
|
use scale_info::TypeInfo;
|
|
use sp_runtime::{Perbill, RuntimeDebug};
|
|
|
|
/// Block length limit configuration.
|
|
#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode, TypeInfo)]
|
|
pub struct BlockLength {
|
|
/// Maximal total length in bytes for each extrinsic class.
|
|
///
|
|
/// In the worst case, the total block length is going to be:
|
|
/// `MAX(max)`
|
|
pub max: PerDispatchClass<u32>,
|
|
}
|
|
|
|
impl Default for BlockLength {
|
|
fn default() -> Self {
|
|
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, DEFAULT_NORMAL_RATIO)
|
|
}
|
|
}
|
|
|
|
impl BlockLength {
|
|
/// Create new `BlockLength` with `max` for every class.
|
|
pub fn max(max: u32) -> Self {
|
|
Self { max: PerDispatchClass::new(|_| max) }
|
|
}
|
|
|
|
/// Create new `BlockLength` with `max` for `Operational` & `Mandatory`
|
|
/// and `normal * max` for `Normal`.
|
|
pub fn max_with_normal_ratio(max: u32, normal: Perbill) -> Self {
|
|
Self {
|
|
max: PerDispatchClass::new(|class| {
|
|
if class == DispatchClass::Normal {
|
|
normal * max
|
|
} else {
|
|
max
|
|
}
|
|
}),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Default, RuntimeDebug)]
|
|
pub struct ValidationErrors {
|
|
pub has_errors: bool,
|
|
#[cfg(feature = "std")]
|
|
pub errors: Vec<String>,
|
|
}
|
|
|
|
macro_rules! error_assert {
|
|
($cond : expr, $err : expr, $format : expr $(, $params: expr )*$(,)*) => {
|
|
if !$cond {
|
|
$err.has_errors = true;
|
|
#[cfg(feature = "std")]
|
|
{ $err.errors.push(format!($format $(, &$params )*)); }
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A result of validating `BlockWeights` correctness.
|
|
pub type ValidationResult = Result<BlockWeights, ValidationErrors>;
|
|
|
|
/// A ratio of `Normal` dispatch class within block, used as default value for
|
|
/// `BlockWeight` and `BlockLength`. The `Default` impls are provided mostly for convenience
|
|
/// to use in tests.
|
|
const DEFAULT_NORMAL_RATIO: Perbill = Perbill::from_percent(75);
|
|
|
|
/// `DispatchClass`-specific weight configuration.
|
|
#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode, TypeInfo)]
|
|
pub struct WeightsPerClass {
|
|
/// Base weight of single extrinsic of given class.
|
|
pub base_extrinsic: Weight,
|
|
/// Maximal weight of single extrinsic. Should NOT include `base_extrinsic` cost.
|
|
///
|
|
/// `None` indicates that this class of extrinsics doesn't have a limit.
|
|
pub max_extrinsic: Option<Weight>,
|
|
/// Block maximal total weight for all extrinsics of given class.
|
|
///
|
|
/// `None` indicates that weight sum of this class of extrinsics is not
|
|
/// restricted. Use this value carefully, since it might produce heavily oversized
|
|
/// blocks.
|
|
///
|
|
/// In the worst case, the total weight consumed by the class is going to be:
|
|
/// `MAX(max_total) + MAX(reserved)`.
|
|
pub max_total: Option<Weight>,
|
|
/// Block reserved allowance for all extrinsics of a particular class.
|
|
///
|
|
/// Setting to `None` indicates that extrinsics of that class are allowed
|
|
/// to go over total block weight (but at most `max_total` for that class).
|
|
/// Setting to `Some(x)` guarantees that at least `x` weight of particular class
|
|
/// is processed in every block.
|
|
pub reserved: Option<Weight>,
|
|
}
|
|
|
|
/// Block weight limits & base values configuration.
|
|
///
|
|
/// This object is responsible for defining weight limits and base weight values tracked
|
|
/// during extrinsic execution.
|
|
///
|
|
/// Each block starts with `base_block` weight being consumed right away. Next up the
|
|
/// `on_initialize` pallet callbacks are invoked and their cost is added before any extrinsic
|
|
/// is executed. This cost is tracked as `Mandatory` dispatch class.
|
|
///
|
|
/// ```text,ignore
|
|
/// | | `max_block` | |
|
|
/// | | | |
|
|
/// | | | |
|
|
/// | | | |
|
|
/// | | | #| `on_initialize`
|
|
/// | #| `base_block` | #|
|
|
/// |NOM| |NOM|
|
|
/// ||\_ Mandatory
|
|
/// |\__ Operational
|
|
/// \___ Normal
|
|
/// ```
|
|
///
|
|
/// The remaining capacity can be used to dispatch extrinsics. Note that each dispatch class
|
|
/// is being tracked separately, but the sum can't exceed `max_block` (except for `reserved`).
|
|
/// Below you can see a picture representing full block with 3 extrinsics (two `Operational` and
|
|
/// one `Normal`). Each class has it's own limit `max_total`, but also the sum cannot exceed
|
|
/// `max_block` value.
|
|
///
|
|
/// ```text,ignore
|
|
/// -- `Mandatory` limit (unlimited)
|
|
/// | # | | |
|
|
/// | # | `Ext3` | - - `Operational` limit
|
|
/// |# | `Ext2` |- - `Normal` limit
|
|
/// | # | `Ext1` | # |
|
|
/// | #| `on_initialize` | ##|
|
|
/// | #| `base_block` |###|
|
|
/// |NOM| |NOM|
|
|
/// ```
|
|
///
|
|
/// It should be obvious now that it's possible for one class to reach it's limit (say `Normal`),
|
|
/// while the block has still capacity to process more transactions (`max_block` not reached,
|
|
/// `Operational` transactions can still go in). Setting `max_total` to `None` disables the
|
|
/// per-class limit. This is generally highly recommended for `Mandatory` dispatch class, while it
|
|
/// can be dangerous for `Normal` class and should only be done with extra care and consideration.
|
|
///
|
|
/// Often it's desirable for some class of transactions to be added to the block despite it being
|
|
/// full. For instance one might want to prevent high-priority `Normal` transactions from pushing
|
|
/// out lower-priority `Operational` transactions. In such cases you might add a `reserved` capacity
|
|
/// for given class.
|
|
///
|
|
/// ```test,ignore
|
|
/// _
|
|
/// # \
|
|
/// # `Ext8` - `reserved`
|
|
/// # _/
|
|
/// | # | `Ext7 | - - `Operational` limit
|
|
/// |# | `Ext6` | |
|
|
/// |# | `Ext5` |-# - `Normal` limit
|
|
/// |# | `Ext4` |## |
|
|
/// | #| `on_initialize` |###|
|
|
/// | #| `base_block` |###|
|
|
/// |NOM| |NOM|
|
|
/// ```
|
|
///
|
|
/// In the above example, `Ext4-6` fill up the block almost up to `max_block`. `Ext7` would not fit
|
|
/// if there wasn't the extra `reserved` space for `Operational` transactions. Note that `max_total`
|
|
/// limit applies to `reserved` space as well (i.e. the sum of weights of `Ext7` & `Ext8` mustn't
|
|
/// exceed it). Setting `reserved` to `None` allows the extrinsics to always get into the block up
|
|
/// to their `max_total` limit. If `max_total` is set to `None` as well, all extrinsics witch
|
|
/// dispatchables of given class will always end up in the block (recommended for `Mandatory`
|
|
/// dispatch class).
|
|
///
|
|
/// As a consequence of `reserved` space, total consumed block weight might exceed `max_block`
|
|
/// value, so this parameter should rather be thought of as "target block weight" than a hard limit.
|
|
#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode, TypeInfo)]
|
|
pub struct BlockWeights {
|
|
/// Base weight of block execution.
|
|
pub base_block: Weight,
|
|
/// Maximal total weight consumed by all kinds of extrinsics (without `reserved` space).
|
|
pub max_block: Weight,
|
|
/// Weight limits for extrinsics of given dispatch class.
|
|
pub per_class: PerDispatchClass<WeightsPerClass>,
|
|
}
|
|
|
|
impl Default for BlockWeights {
|
|
fn default() -> Self {
|
|
Self::with_sensible_defaults(1 * constants::WEIGHT_PER_SECOND, DEFAULT_NORMAL_RATIO)
|
|
}
|
|
}
|
|
|
|
impl BlockWeights {
|
|
/// Get per-class weight settings.
|
|
pub fn get(&self, class: DispatchClass) -> &WeightsPerClass {
|
|
self.per_class.get(class)
|
|
}
|
|
|
|
/// Verifies correctness of this `BlockWeights` object.
|
|
pub fn validate(self) -> ValidationResult {
|
|
fn or_max(w: Option<Weight>) -> Weight {
|
|
w.unwrap_or_else(|| Weight::max_value())
|
|
}
|
|
let mut error = ValidationErrors::default();
|
|
|
|
for class in DispatchClass::all() {
|
|
let weights = self.per_class.get(*class);
|
|
let max_for_class = or_max(weights.max_total);
|
|
let base_for_class = weights.base_extrinsic;
|
|
let reserved = or_max(weights.reserved);
|
|
// Make sure that if total is set it's greater than base_block &&
|
|
// base_for_class
|
|
error_assert!(
|
|
(max_for_class > self.base_block && max_for_class > base_for_class)
|
|
|| max_for_class == 0,
|
|
&mut error,
|
|
"[{:?}] {:?} (total) has to be greater than {:?} (base block) & {:?} (base extrinsic)",
|
|
class, max_for_class, self.base_block, base_for_class,
|
|
);
|
|
// Max extrinsic can't be greater than max_for_class.
|
|
error_assert!(
|
|
weights.max_extrinsic.unwrap_or(0) <= max_for_class.saturating_sub(base_for_class),
|
|
&mut error,
|
|
"[{:?}] {:?} (max_extrinsic) can't be greater than {:?} (max for class)",
|
|
class,
|
|
weights.max_extrinsic,
|
|
max_for_class.saturating_sub(base_for_class),
|
|
);
|
|
// Max extrinsic should not be 0
|
|
error_assert!(
|
|
weights.max_extrinsic.unwrap_or_else(|| Weight::max_value()) > 0,
|
|
&mut error,
|
|
"[{:?}] {:?} (max_extrinsic) must not be 0. Check base cost and average initialization cost.",
|
|
class, weights.max_extrinsic,
|
|
);
|
|
// Make sure that if reserved is set it's greater than base_for_class.
|
|
error_assert!(
|
|
reserved > base_for_class || reserved == 0,
|
|
&mut error,
|
|
"[{:?}] {:?} (reserved) has to be greater than {:?} (base extrinsic) if set",
|
|
class,
|
|
reserved,
|
|
base_for_class,
|
|
);
|
|
// Make sure max block is greater than max_total if it's set.
|
|
error_assert!(
|
|
self.max_block >= weights.max_total.unwrap_or(0),
|
|
&mut error,
|
|
"[{:?}] {:?} (max block) has to be greater than {:?} (max for class)",
|
|
class,
|
|
self.max_block,
|
|
weights.max_total,
|
|
);
|
|
// Make sure we can fit at least one extrinsic.
|
|
error_assert!(
|
|
self.max_block > base_for_class + self.base_block,
|
|
&mut error,
|
|
"[{:?}] {:?} (max block) must fit at least one extrinsic {:?} (base weight)",
|
|
class,
|
|
self.max_block,
|
|
base_for_class + self.base_block,
|
|
);
|
|
}
|
|
|
|
if error.has_errors {
|
|
Err(error)
|
|
} else {
|
|
Ok(self)
|
|
}
|
|
}
|
|
|
|
/// Create new weights definition, with both `Normal` and `Operational`
|
|
/// classes limited to given weight.
|
|
///
|
|
/// Note there is no reservation for `Operational` class, so this constructor
|
|
/// is not suitable for production deployments.
|
|
pub fn simple_max(block_weight: Weight) -> Self {
|
|
Self::builder()
|
|
.base_block(0)
|
|
.for_class(DispatchClass::all(), |weights| {
|
|
weights.base_extrinsic = 0;
|
|
})
|
|
.for_class(DispatchClass::non_mandatory(), |weights| {
|
|
weights.max_total = block_weight.into();
|
|
})
|
|
.build()
|
|
.expect("We only specify max_total and leave base values as defaults; qed")
|
|
}
|
|
|
|
/// Create a sensible default weights system given only expected maximal block weight and the
|
|
/// ratio that `Normal` extrinsics should occupy.
|
|
///
|
|
/// Assumptions:
|
|
/// - Average block initialization is assumed to be `10%`.
|
|
/// - `Operational` transactions have reserved allowance (`1.0 - normal_ratio`)
|
|
pub fn with_sensible_defaults(expected_block_weight: Weight, normal_ratio: Perbill) -> Self {
|
|
let normal_weight = normal_ratio * expected_block_weight;
|
|
Self::builder()
|
|
.for_class(DispatchClass::Normal, |weights| {
|
|
weights.max_total = normal_weight.into();
|
|
})
|
|
.for_class(DispatchClass::Operational, |weights| {
|
|
weights.max_total = expected_block_weight.into();
|
|
weights.reserved = (expected_block_weight - normal_weight).into();
|
|
})
|
|
.avg_block_initialization(Perbill::from_percent(10))
|
|
.build()
|
|
.expect("Sensible defaults are tested to be valid; qed")
|
|
}
|
|
|
|
/// Start constructing new `BlockWeights` object.
|
|
///
|
|
/// By default all kinds except of `Mandatory` extrinsics are disallowed.
|
|
pub fn builder() -> BlockWeightsBuilder {
|
|
BlockWeightsBuilder {
|
|
weights: BlockWeights {
|
|
base_block: constants::BlockExecutionWeight::get(),
|
|
max_block: 0,
|
|
per_class: PerDispatchClass::new(|class| {
|
|
let initial = if class == DispatchClass::Mandatory { None } else { Some(0) };
|
|
WeightsPerClass {
|
|
base_extrinsic: constants::ExtrinsicBaseWeight::get(),
|
|
max_extrinsic: None,
|
|
max_total: initial,
|
|
reserved: initial,
|
|
}
|
|
}),
|
|
},
|
|
init_cost: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An opinionated builder for `Weights` object.
|
|
pub struct BlockWeightsBuilder {
|
|
weights: BlockWeights,
|
|
init_cost: Option<Perbill>,
|
|
}
|
|
|
|
impl BlockWeightsBuilder {
|
|
/// Set base block weight.
|
|
pub fn base_block(mut self, base_block: Weight) -> Self {
|
|
self.weights.base_block = base_block;
|
|
self
|
|
}
|
|
|
|
/// Average block initialization weight cost.
|
|
///
|
|
/// This value is used to derive maximal allowed extrinsic weight for each
|
|
/// class, based on the allowance.
|
|
///
|
|
/// This is to make sure that extrinsics don't stay forever in the pool,
|
|
/// because they could seamingly fit the block (since they are below `max_block`),
|
|
/// but the cost of calling `on_initialize` alway prevents them from being included.
|
|
pub fn avg_block_initialization(mut self, init_cost: Perbill) -> Self {
|
|
self.init_cost = Some(init_cost);
|
|
self
|
|
}
|
|
|
|
/// Set parameters for particular class.
|
|
///
|
|
/// Note: `None` values of `max_extrinsic` will be overwritten in `build` in case
|
|
/// `avg_block_initialization` rate is set to a non-zero value.
|
|
pub fn for_class(
|
|
mut self,
|
|
class: impl OneOrMany<DispatchClass>,
|
|
action: impl Fn(&mut WeightsPerClass),
|
|
) -> Self {
|
|
for class in class.into_iter() {
|
|
action(self.weights.per_class.get_mut(class));
|
|
}
|
|
self
|
|
}
|
|
|
|
/// Construct the `BlockWeights` object.
|
|
pub fn build(self) -> ValidationResult {
|
|
// compute max extrinsic size
|
|
let Self { mut weights, init_cost } = self;
|
|
|
|
// compute max block size.
|
|
for class in DispatchClass::all() {
|
|
weights.max_block = match weights.per_class.get(*class).max_total {
|
|
Some(max) if max > weights.max_block => max,
|
|
_ => weights.max_block,
|
|
};
|
|
}
|
|
// compute max size of single extrinsic
|
|
if let Some(init_weight) = init_cost.map(|rate| rate * weights.max_block) {
|
|
for class in DispatchClass::all() {
|
|
let per_class = weights.per_class.get_mut(*class);
|
|
if per_class.max_extrinsic.is_none() && init_cost.is_some() {
|
|
per_class.max_extrinsic = per_class
|
|
.max_total
|
|
.map(|x| x.saturating_sub(init_weight))
|
|
.map(|x| x.saturating_sub(per_class.base_extrinsic));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate the result
|
|
weights.validate()
|
|
}
|
|
|
|
/// Construct the `BlockWeights` object or panic if it's invalid.
|
|
///
|
|
/// This is a convenience method to be called whenever you construct a runtime.
|
|
pub fn build_or_panic(self) -> BlockWeights {
|
|
self.build().expect(
|
|
"Builder finished with `build_or_panic`; The panic is expected if runtime weights are not correct"
|
|
)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn default_weights_are_valid() {
|
|
BlockWeights::default().validate().unwrap();
|
|
}
|
|
}
|