Skip to content

Commit 62c85f7

Browse files
tomusdrwkianenigmashawntabrizignunicorngui1117
authored
Streamline frame_system weight parametrization (#6629)
* Basic weights builder. * Fixing WiP * Make the tests work. * Fix weights in node/runtime. * WiP. * Update pallets with new weights parameters. * Validate returns a Result now. * Count mandatory weight separately. * DRY * BREAKING: Updating state root, because of the left-over weight-tracking stuff * Update tests affected by Mandatory tracking. * Fixing tests. * Fix defaults for simple_max * Update frame/system/src/weights.rs Co-authored-by: Kian Paimani <[email protected]> * Rework the API a bit. * Fix compilation & tests. * Apply suggestions from code review Co-authored-by: Kian Paimani <[email protected]> * Add extra docs & rename few things. * Fix whitespace in ASCII art. * Update frame/system/src/limits.rs Co-authored-by: Kian Paimani <[email protected]> * Fix max_extrinsic calculations. * Fix conflicts. * Fix compilation. * Fix new code. * re-remove generic asset * Fix usage. * Update state root. * Update proxy. * Fix tests. * Move weights validity to integrity_test * Remove redundant BlockWeights. * Add all/non_mandatory comment * Add test. * Remove fn block_weights * Make the macro prettier. * Fix some docs. * Make max_total behave more predictabily. * Add BlockWeights to metadata. * fix balances test * Fix utility test. Co-authored-by: Kian Paimani <[email protected]> Co-authored-by: Shawn Tabrizi <[email protected]> Co-authored-by: Benjamin Kampmann <[email protected]> Co-authored-by: thiolliere <[email protected]>
1 parent 777a863 commit 62c85f7

File tree

2 files changed

+119
-9
lines changed

2 files changed

+119
-9
lines changed

src/weights.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ impl Default for Pays {
213213
}
214214

215215
/// A generalized group of dispatch types.
216+
///
217+
/// NOTE whenever upgrading the enum make sure to also update
218+
/// [DispatchClass::all] and [DispatchClass::non_mandatory] helper functions.
216219
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
217220
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
218221
#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)]
@@ -242,6 +245,39 @@ impl Default for DispatchClass {
242245
}
243246
}
244247

248+
impl DispatchClass {
249+
/// Returns an array containing all dispatch classes.
250+
pub fn all() -> &'static [DispatchClass] {
251+
&[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory]
252+
}
253+
254+
/// Returns an array of all dispatch classes except `Mandatory`.
255+
pub fn non_mandatory() -> &'static [DispatchClass] {
256+
&[DispatchClass::Normal, DispatchClass::Operational]
257+
}
258+
}
259+
260+
/// A trait that represents one or many values of given type.
261+
///
262+
/// Useful to accept as parameter type to let the caller pass either a single value directly
263+
/// or an iterator.
264+
pub trait OneOrMany<T> {
265+
/// The iterator type.
266+
type Iter: Iterator<Item = T>;
267+
/// Convert this item into an iterator.
268+
fn into_iter(self) -> Self::Iter;
269+
}
270+
271+
impl OneOrMany<DispatchClass> for DispatchClass {
272+
type Iter = sp_std::iter::Once<DispatchClass>;
273+
fn into_iter(self) -> Self::Iter { sp_std::iter::once(self) }
274+
}
275+
276+
impl<'a> OneOrMany<DispatchClass> for &'a [DispatchClass] {
277+
type Iter = sp_std::iter::Cloned<sp_std::slice::Iter<'a, DispatchClass>>;
278+
fn into_iter(self) -> Self::Iter { self.iter().cloned() }
279+
}
280+
245281
/// Primitives related to priority management of Frame.
246282
pub mod priority {
247283
/// The starting point of all Operational transactions. 3/4 of u64::max_value().
@@ -695,6 +731,87 @@ impl<T> WeightToFeePolynomial for IdentityFee<T> where
695731
}
696732
}
697733

734+
/// A struct holding value for each `DispatchClass`.
735+
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)]
736+
pub struct PerDispatchClass<T> {
737+
/// Value for `Normal` extrinsics.
738+
normal: T,
739+
/// Value for `Operational` extrinsics.
740+
operational: T,
741+
/// Value for `Mandatory` extrinsics.
742+
mandatory: T,
743+
}
744+
745+
impl<T> PerDispatchClass<T> {
746+
/// Create new `PerDispatchClass` with the same value for every class.
747+
pub fn new(val: impl Fn(DispatchClass) -> T) -> Self {
748+
Self {
749+
normal: val(DispatchClass::Normal),
750+
operational: val(DispatchClass::Operational),
751+
mandatory: val(DispatchClass::Mandatory),
752+
}
753+
}
754+
755+
/// Get a mutable reference to current value of given class.
756+
pub fn get_mut(&mut self, class: DispatchClass) -> &mut T {
757+
match class {
758+
DispatchClass::Operational => &mut self.operational,
759+
DispatchClass::Normal => &mut self.normal,
760+
DispatchClass::Mandatory => &mut self.mandatory,
761+
}
762+
}
763+
764+
/// Get current value for given class.
765+
pub fn get(&self, class: DispatchClass) -> &T {
766+
match class {
767+
DispatchClass::Normal => &self.normal,
768+
DispatchClass::Operational => &self.operational,
769+
DispatchClass::Mandatory => &self.mandatory,
770+
}
771+
}
772+
}
773+
774+
impl<T: Clone> PerDispatchClass<T> {
775+
/// Set the value of given class.
776+
pub fn set(&mut self, new: T, class: impl OneOrMany<DispatchClass>) {
777+
for class in class.into_iter() {
778+
*self.get_mut(class) = new.clone();
779+
}
780+
}
781+
}
782+
783+
impl PerDispatchClass<Weight> {
784+
/// Returns the total weight consumed by all extrinsics in the block.
785+
pub fn total(&self) -> Weight {
786+
let mut sum = 0;
787+
for class in DispatchClass::all() {
788+
sum = sum.saturating_add(*self.get(*class));
789+
}
790+
sum
791+
}
792+
793+
/// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`.
794+
pub fn add(&mut self, weight: Weight, class: DispatchClass) {
795+
let value = self.get_mut(class);
796+
*value = value.saturating_add(weight);
797+
}
798+
799+
/// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would
800+
/// occur.
801+
pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> {
802+
let value = self.get_mut(class);
803+
*value = value.checked_add(weight).ok_or(())?;
804+
Ok(())
805+
}
806+
807+
/// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of
808+
/// `Weight`.
809+
pub fn sub(&mut self, weight: Weight, class: DispatchClass) {
810+
let value = self.get_mut(class);
811+
*value = value.saturating_sub(weight);
812+
}
813+
}
814+
698815
#[cfg(test)]
699816
#[allow(dead_code)]
700817
mod tests {

test/tests/pallet_with_name_trait_is_valid.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ mod tests {
117117

118118
parameter_types! {
119119
pub const BlockHashCount: u64 = 250;
120-
pub const MaximumBlockWeight: frame_support::weights::Weight = 1024;
121-
pub const MaximumBlockLength: u32 = 2 * 1024;
122-
pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one();
123120
}
124121

125122
impl frame_system::Config for Runtime {
@@ -135,13 +132,9 @@ mod tests {
135132
type Header = TestHeader;
136133
type Event = ();
137134
type BlockHashCount = BlockHashCount;
138-
type MaximumBlockWeight = MaximumBlockWeight;
139135
type DbWeight = ();
140-
type BlockExecutionWeight = ();
141-
type ExtrinsicBaseWeight = ();
142-
type MaximumExtrinsicWeight = MaximumBlockWeight;
143-
type MaximumBlockLength = MaximumBlockLength;
144-
type AvailableBlockRatio = AvailableBlockRatio;
136+
type BlockWeights = ();
137+
type BlockLength = ();
145138
type Version = ();
146139
type PalletInfo = ();
147140
type AccountData = ();

0 commit comments

Comments
 (0)