From 139bc7f9a5c14d26ea583005ffeba352026706f5 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 2 Nov 2022 11:55:07 +0100 Subject: [PATCH 1/8] Move WeightCounter to sp_weights Signed-off-by: Oliver Tale-Yazdi --- frame/scheduler/src/lib.rs | 19 ------------- primitives/weights/src/weight_meter.rs | 37 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 primitives/weights/src/weight_meter.rs diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index b5ea0deeba9a3..96627559cca33 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -143,25 +143,6 @@ pub type ScheduledOf = Scheduled< ::AccountId, >; -struct WeightCounter { - used: Weight, - limit: Weight, -} -impl WeightCounter { - fn check_accrue(&mut self, w: Weight) -> bool { - let test = self.used.saturating_add(w); - if test.any_gt(self.limit) { - false - } else { - self.used = test; - true - } - } - fn can_accrue(&mut self, w: Weight) -> bool { - self.used.saturating_add(w).all_lte(self.limit) - } -} - pub(crate) trait MarginalWeightInfo: WeightInfo { fn service_task(maybe_lookup_len: Option, named: bool, periodic: bool) -> Weight { let base = Self::service_task_base(); diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs new file mode 100644 index 0000000000000..6a30f4d14c644 --- /dev/null +++ b/primitives/weights/src/weight_meter.rs @@ -0,0 +1,37 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2022 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. + +//! Contains the `WeightCounter` primitive. + +struct WeightCounter { + used: Weight, + limit: Weight, +} +impl WeightCounter { + fn check_accrue(&mut self, w: Weight) -> bool { + let test = self.used.saturating_add(w); + if test.any_gt(self.limit) { + false + } else { + self.used = test; + true + } + } + fn can_accrue(&mut self, w: Weight) -> bool { + self.used.saturating_add(w).all_lte(self.limit) + } +} From c6ef48fbedadcaed684e3938a9ecc6274b6395d6 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 2 Nov 2022 12:43:16 +0100 Subject: [PATCH 2/8] Rename to WeightMeter and test Signed-off-by: Oliver Tale-Yazdi --- primitives/weights/src/lib.rs | 2 + primitives/weights/src/weight_meter.rs | 164 ++++++++++++++++++++++--- 2 files changed, 149 insertions(+), 17 deletions(-) diff --git a/primitives/weights/src/lib.rs b/primitives/weights/src/lib.rs index e1ac7fcd4e892..34b8ff45666da 100644 --- a/primitives/weights/src/lib.rs +++ b/primitives/weights/src/lib.rs @@ -28,6 +28,7 @@ extern crate self as sp_weights; +mod weight_meter; mod weight_v2; use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; @@ -42,6 +43,7 @@ use sp_arithmetic::{ use sp_core::Get; use sp_debug_derive::RuntimeDebug; +pub use weight_meter::*; pub use weight_v2::*; pub mod constants { diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 6a30f4d14c644..79b9076edb4ea 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. +// Copyright (C) 2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,23 +15,153 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Contains the `WeightCounter` primitive. +//! Contains the `WeightMeter` primitive to meter weight usage. -struct WeightCounter { - used: Weight, - limit: Weight, +use super::Weight; + +use sp_arithmetic::Perbill; + +/// Meters consumed weight and a hard limit for the maximal consumable weight. +/// +/// Can be used to check if enough weight for an operation is available before committing to it. +/// +/// # Example +/// +/// ```rust +/// use sp_weights::{Weight, WeightMeter}; +/// +/// // The weight is limited to (10, 0). +/// let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); +/// // There is enough weight remaining for an operation with (5, 0) weight. +/// assert!(meter.check_accrue(Weight::from_parts(5, 0))); +/// // There is not enough weight remaining for an operation with (6, 0) weight. +/// assert!(!meter.check_accrue(Weight::from_parts(6, 0))); +/// ``` +#[derive(Debug, Clone)] +pub struct WeightMeter { + /// The already consumed weight. + pub consumed: Weight, + + /// The maximal consumable weight. + pub limit: Weight, } -impl WeightCounter { - fn check_accrue(&mut self, w: Weight) -> bool { - let test = self.used.saturating_add(w); - if test.any_gt(self.limit) { - false - } else { - self.used = test; - true - } - } - fn can_accrue(&mut self, w: Weight) -> bool { - self.used.saturating_add(w).all_lte(self.limit) + +impl WeightMeter { + /// Creates [`Self`] from a limit for the maximal consumable weight. + pub fn from_limit(limit: Weight) -> Self { + Self { consumed: Weight::zero(), limit } + } + + /// Creates [`Self`] with the maximal possible limit for the consumable weight. + pub fn max_limit() -> Self { + Self::from_limit(Weight::MAX) + } + + /// The remaining weight that can be still consumed. + pub fn remaining(&self) -> Weight { + self.limit.saturating_sub(self.consumed) + } + + /// The ratio of consumed weight to the limit. + /// + /// Calculates one ratio per component and returns the largest. + pub fn remaining_ratio(&self) -> Perbill { + let time = Perbill::from_rational(self.consumed.ref_time(), self.limit.ref_time()); + let pov = Perbill::from_rational(self.consumed.proof_size(), self.limit.proof_size()); + time.max(pov) + } + + /// Consume some weight and defensively fail if it is over the limit or would saturate the + /// arithmetic type. + pub fn defensive_accrue(&mut self, w: Weight) { + let res = self.check_accrue(w); + debug_assert!(res, "Weight meter exhausted; {} + {} > {}", &self.consumed, &w, &self.limit); + } + + /// Check if the given weight can be consumed. Do nothing if not. + pub fn check_accrue(&mut self, w: Weight) -> bool { + self.consumed.checked_add(&w).map_or(false, |test| { + if test.any_gt(self.limit) { + false + } else { + self.consumed = test; + true + } + }) + } + + /// Check if the given weight can be consumed. + pub fn can_accrue(&self, w: Weight) -> bool { + self.consumed.checked_add(&w).map_or(false, |t| t.all_lte(self.limit)) + } +} + +#[cfg(test)] +mod tests { + use crate::*; + + #[test] + fn weight_meter_remaining_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 20)); + + meter.defensive_accrue(Weight::from_parts(5, 0)); + assert_eq!(meter.consumed, Weight::from_parts(5, 0)); + assert_eq!(meter.remaining(), Weight::from_parts(5, 20)); + + meter.defensive_accrue(Weight::from_parts(2, 10)); + assert_eq!(meter.consumed, Weight::from_parts(7, 10)); + assert_eq!(meter.remaining(), Weight::from_parts(3, 10)); + + meter.defensive_accrue(Weight::from_parts(3, 10)); + assert_eq!(meter.consumed, Weight::from_parts(10, 20)); + assert_eq!(meter.remaining(), Weight::from_parts(0, 0)); + } + + #[test] + fn weight_meter_check_and_can_accrue_works() { + let mut meter = WeightMeter::max_limit(); + + assert!(meter.can_accrue(Weight::from_parts(u64::MAX, 0))); + assert!(meter.check_accrue(Weight::from_parts(u64::MAX, 0))); + + assert!(meter.can_accrue(Weight::from_parts(0, u64::MAX))); + assert!(meter.check_accrue(Weight::from_parts(0, u64::MAX))); + + assert!(!meter.can_accrue(Weight::from_parts(0, 1))); + assert!(!meter.check_accrue(Weight::from_parts(0, 1))); + + assert!(!meter.can_accrue(Weight::from_parts(1, 0))); + assert!(!meter.check_accrue(Weight::from_parts(1, 0))); + + assert!(meter.can_accrue(Weight::zero())); + assert!(meter.check_accrue(Weight::zero())); + } + + #[test] + #[should_panic(expected = "Weight meter exhausted")] + fn weight_meter_defensive_accrue_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); + + meter.defensive_accrue(Weight::from_parts(11, 0)); + } + + #[test] + fn remaining_ratio_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 20)); + + meter.defensive_accrue(Weight::from_parts(5, 0)); + assert_eq!(meter.remaining_ratio(), Perbill::from_percent(50)); + meter.defensive_accrue(Weight::from_parts(0, 12)); + assert_eq!(meter.remaining_ratio(), Perbill::from_percent(60)); + + meter.defensive_accrue(Weight::from_parts(2, 0)); + assert_eq!(meter.remaining_ratio(), Perbill::from_percent(70)); + meter.defensive_accrue(Weight::from_parts(0, 4)); + assert_eq!(meter.remaining_ratio(), Perbill::from_percent(80)); + + meter.defensive_accrue(Weight::from_parts(3, 0)); + assert_eq!(meter.remaining_ratio(), Perbill::from_percent(100)); + meter.defensive_accrue(Weight::from_parts(0, 4)); + assert_eq!(meter.remaining_ratio(), Perbill::from_percent(100)); } } From 8c7097941dc29ec3da075f921cdfeb2014db0fd9 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 2 Nov 2022 13:02:36 +0100 Subject: [PATCH 3/8] Fix pallet-scheduler for new usage Signed-off-by: Oliver Tale-Yazdi --- frame/scheduler/src/benchmarking.rs | 20 ++++++++------------ frame/scheduler/src/lib.rs | 15 +++++++-------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/frame/scheduler/src/benchmarking.rs b/frame/scheduler/src/benchmarking.rs index aaa30fd88ffda..e621c913b2386 100644 --- a/frame/scheduler/src/benchmarking.rs +++ b/frame/scheduler/src/benchmarking.rs @@ -122,17 +122,13 @@ fn make_origin(signed: bool) -> ::PalletsOrigin { } } -fn dummy_counter() -> WeightCounter { - WeightCounter { used: Weight::zero(), limit: Weight::MAX } -} - benchmarks! { // `service_agendas` when no work is done. service_agendas_base { let now = T::BlockNumber::from(BLOCK_NUMBER); IncompleteSince::::put(now - One::one()); }: { - Scheduler::::service_agendas(&mut dummy_counter(), now, 0); + Scheduler::::service_agendas(&mut WeightMeter::max_limit(), now, 0); } verify { assert_eq!(IncompleteSince::::get(), Some(now - One::one())); } @@ -144,7 +140,7 @@ benchmarks! { fill_schedule::(now, s)?; let mut executed = 0; }: { - Scheduler::::service_agenda(&mut dummy_counter(), &mut executed, now, now, 0); + Scheduler::::service_agenda(&mut WeightMeter::max_limit(), &mut executed, now, now, 0); } verify { assert_eq!(executed, 0); } @@ -155,7 +151,7 @@ benchmarks! { let now = BLOCK_NUMBER.into(); let task = make_task::(false, false, false, None, 0); // prevent any tasks from actually being executed as we only want the surrounding weight. - let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() }; + let mut counter = WeightMeter::from_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, now, now, 0, true, task); } verify { @@ -169,7 +165,7 @@ benchmarks! { let now = BLOCK_NUMBER.into(); let task = make_task::(false, false, false, Some(s), 0); // prevent any tasks from actually being executed as we only want the surrounding weight. - let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() }; + let mut counter = WeightMeter::from_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, now, now, 0, true, task); } verify { @@ -181,7 +177,7 @@ benchmarks! { let now = BLOCK_NUMBER.into(); let task = make_task::(false, true, false, None, 0); // prevent any tasks from actually being executed as we only want the surrounding weight. - let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() }; + let mut counter = WeightMeter::from_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, now, now, 0, true, task); } verify { @@ -193,7 +189,7 @@ benchmarks! { let now = BLOCK_NUMBER.into(); let task = make_task::(true, false, false, None, 0); // prevent any tasks from actually being executed as we only want the surrounding weight. - let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() }; + let mut counter = WeightMeter::from_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, now, now, 0, true, task); } verify { @@ -201,7 +197,7 @@ benchmarks! { // `execute_dispatch` when the origin is `Signed`, not counting the dispatable's weight. execute_dispatch_signed { - let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::MAX }; + let mut counter = WeightMeter::max_limit(); let origin = make_origin::(true); let call = T::Preimages::realize(&make_call::(None)).unwrap().0; }: { @@ -212,7 +208,7 @@ benchmarks! { // `execute_dispatch` when the origin is not `Signed`, not counting the dispatable's weight. execute_dispatch_unsigned { - let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::MAX }; + let mut counter = WeightMeter::max_limit(); let origin = make_origin::(false); let call = T::Preimages::realize(&make_call::(None)).unwrap().0; }: { diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 96627559cca33..c13cd82f1fb01 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -70,7 +70,7 @@ use frame_support::{ Bounded, CallerTrait, EnsureOrigin, Get, Hash as PreimageHash, IsType, OriginTrait, PalletInfoAccess, PrivilegeCmp, QueryPreimage, StorageVersion, StorePreimage, }, - weights::Weight, + weights::{Weight, WeightMeter}, }; use frame_system::{self as system}; pub use pallet::*; @@ -287,10 +287,9 @@ pub mod pallet { impl Hooks> for Pallet { /// Execute the scheduled calls fn on_initialize(now: T::BlockNumber) -> Weight { - let mut weight_counter = - WeightCounter { used: Weight::zero(), limit: T::MaximumWeight::get() }; + let mut weight_counter = WeightMeter::from_limit(T::MaximumWeight::get()); Self::service_agendas(&mut weight_counter, now, u32::max_value()); - weight_counter.used + weight_counter.consumed } } @@ -914,7 +913,7 @@ use ServiceTaskError::*; impl Pallet { /// Service up to `max` agendas queue starting from earliest incompletely executed agenda. - fn service_agendas(weight: &mut WeightCounter, now: T::BlockNumber, max: u32) { + fn service_agendas(weight: &mut WeightMeter, now: T::BlockNumber, max: u32) { if !weight.check_accrue(T::WeightInfo::service_agendas_base()) { return } @@ -942,7 +941,7 @@ impl Pallet { /// Returns `true` if the agenda was fully completed, `false` if it should be revisited at a /// later block. fn service_agenda( - weight: &mut WeightCounter, + weight: &mut WeightMeter, executed: &mut u32, now: T::BlockNumber, when: T::BlockNumber, @@ -1011,7 +1010,7 @@ impl Pallet { /// - realizing the task's call which can include a preimage lookup. /// - Rescheduling the task for execution in a later agenda if periodic. fn service_task( - weight: &mut WeightCounter, + weight: &mut WeightMeter, now: T::BlockNumber, when: T::BlockNumber, agenda_index: u32, @@ -1091,7 +1090,7 @@ impl Pallet { /// NOTE: Only the weight for this function will be counted (origin lookup, dispatch and the /// call itself). fn execute_dispatch( - weight: &mut WeightCounter, + weight: &mut WeightMeter, origin: T::PalletsOrigin, call: ::RuntimeCall, ) -> Result { From 15b92a6fa8de97045140a36bd261406d3a75f2b6 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Fri, 4 Nov 2022 19:54:54 +0100 Subject: [PATCH 4/8] Update primitives/weights/src/weight_meter.rs Co-authored-by: David --- primitives/weights/src/weight_meter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 79b9076edb4ea..92d4232856d16 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -78,7 +78,7 @@ impl WeightMeter { debug_assert!(res, "Weight meter exhausted; {} + {} > {}", &self.consumed, &w, &self.limit); } - /// Check if the given weight can be consumed. Do nothing if not. + /// Consume the given weight after checking if it can be consumed. Do nothing if not. pub fn check_accrue(&mut self, w: Weight) -> bool { self.consumed.checked_add(&w).map_or(false, |test| { if test.any_gt(self.limit) { From e8a333d2cbadec1de6f8d715899fb01dc2149d58 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sat, 5 Nov 2022 12:10:47 +0100 Subject: [PATCH 5/8] More tests for can_accrue Signed-off-by: Oliver Tale-Yazdi --- primitives/weights/src/weight_meter.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 92d4232856d16..df28fb6e873d7 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -117,6 +117,17 @@ mod tests { assert_eq!(meter.remaining(), Weight::from_parts(0, 0)); } + #[test] + fn weight_meter_can_accrue_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(1, 1)); + + assert!(meter.can_accrue(Weight::from_parts(0, 0))); + assert!(meter.can_accrue(Weight::from_parts(1, 1))); + assert!(!meter.can_accrue(Weight::from_parts(0, 2))); + assert!(!meter.can_accrue(Weight::from_parts(2, 0))); + assert!(!meter.can_accrue(Weight::from_parts(2, 2))); + } + #[test] fn weight_meter_check_and_can_accrue_works() { let mut meter = WeightMeter::max_limit(); From 76cc7dbc1032dfd8da0513f61e8b954936cdfad6 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sat, 5 Nov 2022 12:16:58 +0100 Subject: [PATCH 6/8] Clippy Signed-off-by: Oliver Tale-Yazdi --- primitives/weights/src/weight_meter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index df28fb6e873d7..4f0f22c0d0328 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -119,7 +119,7 @@ mod tests { #[test] fn weight_meter_can_accrue_works() { - let mut meter = WeightMeter::from_limit(Weight::from_parts(1, 1)); + let meter = WeightMeter::from_limit(Weight::from_parts(1, 1)); assert!(meter.can_accrue(Weight::from_parts(0, 0))); assert!(meter.can_accrue(Weight::from_parts(1, 1))); From c9d3b22aaf21dc71684a47c9d7362e1ac49579e6 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 6 Nov 2022 12:23:41 +0100 Subject: [PATCH 7/8] Remove defensive_accrue and fixup consumed_ratio I dont think there is a good use-case for defensive_accrue without saturation. Only in tests maybe, will remove for now until we have a use-case. Signed-off-by: Oliver Tale-Yazdi --- primitives/weights/src/weight_meter.rs | 53 +++++++++----------------- 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 4f0f22c0d0328..4a7254c539e9a 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -57,7 +57,7 @@ impl WeightMeter { Self::from_limit(Weight::MAX) } - /// The remaining weight that can be still consumed. + /// The remaining weight that can still be consumed. pub fn remaining(&self) -> Weight { self.limit.saturating_sub(self.consumed) } @@ -65,20 +65,13 @@ impl WeightMeter { /// The ratio of consumed weight to the limit. /// /// Calculates one ratio per component and returns the largest. - pub fn remaining_ratio(&self) -> Perbill { + pub fn consumed_ratio(&self) -> Perbill { let time = Perbill::from_rational(self.consumed.ref_time(), self.limit.ref_time()); let pov = Perbill::from_rational(self.consumed.proof_size(), self.limit.proof_size()); time.max(pov) } - /// Consume some weight and defensively fail if it is over the limit or would saturate the - /// arithmetic type. - pub fn defensive_accrue(&mut self, w: Weight) { - let res = self.check_accrue(w); - debug_assert!(res, "Weight meter exhausted; {} + {} > {}", &self.consumed, &w, &self.limit); - } - - /// Consume the given weight after checking if it can be consumed. Do nothing if not. + /// Consume the given weight after checking that it can be consumed. Otherwise do nothing. pub fn check_accrue(&mut self, w: Weight) -> bool { self.consumed.checked_add(&w).map_or(false, |test| { if test.any_gt(self.limit) { @@ -104,15 +97,15 @@ mod tests { fn weight_meter_remaining_works() { let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 20)); - meter.defensive_accrue(Weight::from_parts(5, 0)); + assert!(meter.check_accrue(Weight::from_parts(5, 0))); assert_eq!(meter.consumed, Weight::from_parts(5, 0)); assert_eq!(meter.remaining(), Weight::from_parts(5, 20)); - meter.defensive_accrue(Weight::from_parts(2, 10)); + assert!(meter.check_accrue(Weight::from_parts(2, 10))); assert_eq!(meter.consumed, Weight::from_parts(7, 10)); assert_eq!(meter.remaining(), Weight::from_parts(3, 10)); - meter.defensive_accrue(Weight::from_parts(3, 10)); + assert!(meter.check_accrue(Weight::from_parts(3, 10))); assert_eq!(meter.consumed, Weight::from_parts(10, 20)); assert_eq!(meter.remaining(), Weight::from_parts(0, 0)); } @@ -149,30 +142,22 @@ mod tests { } #[test] - #[should_panic(expected = "Weight meter exhausted")] - fn weight_meter_defensive_accrue_works() { - let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); - - meter.defensive_accrue(Weight::from_parts(11, 0)); - } - - #[test] - fn remaining_ratio_works() { + fn consumed_ratio_works() { let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 20)); - meter.defensive_accrue(Weight::from_parts(5, 0)); - assert_eq!(meter.remaining_ratio(), Perbill::from_percent(50)); - meter.defensive_accrue(Weight::from_parts(0, 12)); - assert_eq!(meter.remaining_ratio(), Perbill::from_percent(60)); + assert!(meter.check_accrue(Weight::from_parts(5, 0))); + assert_eq!(meter.consumed_ratio(), Perbill::from_percent(50)); + assert!(meter.check_accrue(Weight::from_parts(0, 12))); + assert_eq!(meter.consumed_ratio(), Perbill::from_percent(60)); - meter.defensive_accrue(Weight::from_parts(2, 0)); - assert_eq!(meter.remaining_ratio(), Perbill::from_percent(70)); - meter.defensive_accrue(Weight::from_parts(0, 4)); - assert_eq!(meter.remaining_ratio(), Perbill::from_percent(80)); + assert!(meter.check_accrue(Weight::from_parts(2, 0))); + assert_eq!(meter.consumed_ratio(), Perbill::from_percent(70)); + assert!(meter.check_accrue(Weight::from_parts(0, 4))); + assert_eq!(meter.consumed_ratio(), Perbill::from_percent(80)); - meter.defensive_accrue(Weight::from_parts(3, 0)); - assert_eq!(meter.remaining_ratio(), Perbill::from_percent(100)); - meter.defensive_accrue(Weight::from_parts(0, 4)); - assert_eq!(meter.remaining_ratio(), Perbill::from_percent(100)); + assert!(meter.check_accrue(Weight::from_parts(3, 0))); + assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); + assert!(meter.check_accrue(Weight::from_parts(0, 4))); + assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); } } From 56672b33e2b8fbf8674844c7277e0d8a1fdf8606 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 6 Nov 2022 12:27:08 +0100 Subject: [PATCH 8/8] Test Signed-off-by: Oliver Tale-Yazdi --- primitives/weights/src/weight_meter.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 4a7254c539e9a..d03e72968bb09 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -121,6 +121,19 @@ mod tests { assert!(!meter.can_accrue(Weight::from_parts(2, 2))); } + #[test] + fn weight_meter_check_accrue_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(2, 2)); + + assert!(meter.check_accrue(Weight::from_parts(0, 0))); + assert!(meter.check_accrue(Weight::from_parts(1, 1))); + assert!(!meter.check_accrue(Weight::from_parts(0, 2))); + assert!(!meter.check_accrue(Weight::from_parts(2, 0))); + assert!(!meter.check_accrue(Weight::from_parts(2, 2))); + assert!(meter.check_accrue(Weight::from_parts(0, 1))); + assert!(meter.check_accrue(Weight::from_parts(1, 0))); + } + #[test] fn weight_meter_check_and_can_accrue_works() { let mut meter = WeightMeter::max_limit();