mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-10 05:17:59 +00:00
6f3d1a8143
* The message queue * Make fully generic * Refactor * Docs * Refactor * Use iter not slice * Per-origin queues * Multi-queue processing * Introduce MaxReady * Remove MaxReady in favour of ready ring * Cleanups * ReadyRing and tests * Stale page reaping * from_components -> from_parts Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Move WeightCounter to sp_weights Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add MockedWeightInfo Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Deploy to kitchensink Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use WeightCounter Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Small fixes and logging Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add service_page Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Typo Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Move service_page below service_queue Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add service_message Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use correct weight function Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Overweight execution * Refactor * Missing file * Fix WeightCounter usage in scheduler Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix peek_index Take into account that decoding from a mutable slice modifies it. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add tests and bench service_page_item Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add debug_info Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add no-progress check to service_queues Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add more benches Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Bound from_message and try_append_message Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add PageReaped event Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Rename BookStateOf and BookStateFor Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update tests and remove logging Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove redundant per-message origins; add footprint() and sweep_queue() * Move testing stuff to mock.rs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add integration test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix no-progress check Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix debug_info Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fixup merge and tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix footprint tracking * Introduce * Formatting * OverweightEnqueued event, auto-servicing config item * Update tests and benchmarks Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Provide change handler * Add missing BookStateFor::insert and call QueueChangeHandler Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Docs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update benchmarks and weights Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use weight metering functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * weightInfo::process_message_payload is gone Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add defensive_saturating_accrue Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Rename WeightCounter to WeightMeter Ctr+Shift+H should do the trick. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test on_initialize Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add module docs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove origin from MaxMessageLen The message origin is not encoded into the heap and does therefore not influence the max message length anymore. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add BoundedVec::as_slice Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test Page::{from_message, try_append_message} Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fixup docs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Docs * Do nothing in sweep_queue if the queue does not exist ... otherwise it inserts default values into the storage. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test ring (un)knitting Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Upgrade stress-test Change the test to not assume that all queued messages will be processed in the next block but split it over multiple. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Beauty fixes Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Rename BoundedVec::as_slice to as_bounded_slice Conflicts with deref().as_slice() otherwise. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix imports Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove ReadyRing struct Was used for testing only. Instead use 'fn assert_ring' which also check the service head and backlinks. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Beauty fixes Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix stale page watermark Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Cleanup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix test feature and clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * QueueChanged handler is called correctly Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update benches Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Abstract testing functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Cleanup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Simplify tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make stuff compile Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Extend overweight execution benchmark Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove TODOs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test service queue with faulty MessageProcessor Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update pallet ui tests to 1.65 Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More docs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Review doc fixes Co-authored-by: Robert Klotzner <eskimor@users.noreply.github.com> Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add weight_limit to extrinsic weight of execute_overweight * Correctly return unused weight * Return actual weight consumed in do_execute_overweight * Review fixes Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Set version 7.0.0-dev Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make it compile Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Switch message_size to u64 Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Switch message_count to u64 Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix benchmarks Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make CI green Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Docs * Update tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * ".git/.scripts/bench-bot.sh" pallet dev pallet_message_queue * Dont mention README.md in the Cargo.toml Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove reference to readme Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: parity-processbot <> Co-authored-by: Robert Klotzner <eskimor@users.noreply.github.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
183 lines
6.2 KiB
Rust
183 lines
6.2 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) 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 `WeightMeter` primitive to meter weight usage.
|
|
|
|
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 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 still be 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 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. Saturate in any case.
|
|
pub fn defensive_saturating_accrue(&mut self, w: Weight) {
|
|
self.consumed.saturating_accrue(w);
|
|
debug_assert!(self.consumed.all_lte(self.limit), "Weight counter overflow");
|
|
}
|
|
|
|
/// 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) {
|
|
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));
|
|
|
|
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));
|
|
|
|
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));
|
|
|
|
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));
|
|
}
|
|
|
|
#[test]
|
|
fn weight_meter_can_accrue_works() {
|
|
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)));
|
|
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_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();
|
|
|
|
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]
|
|
fn consumed_ratio_works() {
|
|
let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 20));
|
|
|
|
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));
|
|
|
|
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));
|
|
|
|
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));
|
|
}
|
|
}
|