chore: regenerate umbrella crate, fix feature propagation
This commit is contained in:
@@ -41,8 +41,8 @@
|
||||
//! queues which hold at least one unprocessed message and are thereby *ready* to be serviced. The
|
||||
//! `ServiceHead` indicates which *ready* queue is the next to be serviced.
|
||||
//! The pezpallet implements [`pezframe_support::traits::EnqueueMessage`],
|
||||
//! [`pezframe_support::traits::ServiceQueues`] and has [`pezframe_support::traits::ProcessMessage`] and
|
||||
//! [`OnQueueChanged`] hooks to communicate with the outside world.
|
||||
//! [`pezframe_support::traits::ServiceQueues`] and has [`pezframe_support::traits::ProcessMessage`]
|
||||
//! and [`OnQueueChanged`] hooks to communicate with the outside world.
|
||||
//!
|
||||
//! NOTE: The storage items are not linked since they are not public.
|
||||
//!
|
||||
@@ -52,31 +52,32 @@
|
||||
//! logic of how to handle the message since they are blobs. Storage changes are not rolled back on
|
||||
//! error.
|
||||
//!
|
||||
//! A failed message can be temporarily or permanently overweight. The pezpallet will perpetually try
|
||||
//! to execute a temporarily overweight message. A permanently overweight message is skipped and
|
||||
//! A failed message can be temporarily or permanently overweight. The pezpallet will perpetually
|
||||
//! try to execute a temporarily overweight message. A permanently overweight message is skipped and
|
||||
//! must be executed manually.
|
||||
//!
|
||||
//! **Reentrancy**
|
||||
//!
|
||||
//! This pezpallet has two entry points for executing (possibly recursive) logic;
|
||||
//! [`Pezpallet::service_queues`] and [`Pezpallet::execute_overweight`]. Both entry points are guarded by
|
||||
//! the same mutex to error on reentrancy. The only functions that are explicitly **allowed** to be
|
||||
//! called by a message processor are: [`Pezpallet::enqueue_message`] and
|
||||
//! [`Pezpallet::service_queues`] and [`Pezpallet::execute_overweight`]. Both entry points are
|
||||
//! guarded by the same mutex to error on reentrancy. The only functions that are explicitly
|
||||
//! **allowed** to be called by a message processor are: [`Pezpallet::enqueue_message`] and
|
||||
//! [`Pezpallet::enqueue_messages`]. All other functions are forbidden and error with
|
||||
//! [`Error::RecursiveDisallowed`].
|
||||
//!
|
||||
//! **Pagination**
|
||||
//!
|
||||
//! Queues are stored in a *paged* manner by splitting their messages into [`Page`]s. This results
|
||||
//! in a lot of complexity when implementing the pezpallet but is completely necessary to achieve the
|
||||
//! second #[Design Goal](design-goals). The problem comes from the fact a message can *possibly* be
|
||||
//! quite large, lets say 64KiB. This then results in a *MEL* of at least 64KiB which results in a
|
||||
//! PoV of at least 64KiB. Now we have the assumption that most messages are much shorter than their
|
||||
//! maximum allowed length. This would result in most messages having a pre-dispatch PoV size which
|
||||
//! is much larger than their post-dispatch PoV size, possibly by a factor of thousand. Disregarding
|
||||
//! this observation would cripple the processing power of the pezpallet since it cannot straighten out
|
||||
//! this discrepancy at runtime. Conceptually, the implementation is packing as many messages into a
|
||||
//! single bounded vec, as actually fit into the bounds. This reduces the wasted PoV.
|
||||
//! in a lot of complexity when implementing the pezpallet but is completely necessary to achieve
|
||||
//! the second #[Design Goal](design-goals). The problem comes from the fact a message can
|
||||
//! *possibly* be quite large, lets say 64KiB. This then results in a *MEL* of at least 64KiB which
|
||||
//! results in a PoV of at least 64KiB. Now we have the assumption that most messages are much
|
||||
//! shorter than their maximum allowed length. This would result in most messages having a
|
||||
//! pre-dispatch PoV size which is much larger than their post-dispatch PoV size, possibly by a
|
||||
//! factor of thousand. Disregarding this observation would cripple the processing power of the
|
||||
//! pezpallet since it cannot straighten out this discrepancy at runtime. Conceptually, the
|
||||
//! implementation is packing as many messages into a single bounded vec, as actually fit into the
|
||||
//! bounds. This reduces the wasted PoV.
|
||||
//!
|
||||
//! **Page Data Layout**
|
||||
//!
|
||||
@@ -88,13 +89,13 @@
|
||||
//!
|
||||
//! **Weight Metering**
|
||||
//!
|
||||
//! The pezpallet utilizes the [`pezsp_weights::WeightMeter`] to manually track its consumption to always
|
||||
//! stay within the required limit. This implies that the message processor hook can calculate the
|
||||
//! weight of a message without executing it. This restricts the possible use-cases but is necessary
|
||||
//! since the pezpallet runs in `on_initialize` which has a hard weight limit. The weight meter is used
|
||||
//! in a way that `can_accrue` and `check_accrue` are always used to check the remaining weight of
|
||||
//! an operation before committing to it. The process of exiting due to insufficient weight is
|
||||
//! termed "bailing".
|
||||
//! The pezpallet utilizes the [`pezsp_weights::WeightMeter`] to manually track its consumption to
|
||||
//! always stay within the required limit. This implies that the message processor hook can
|
||||
//! calculate the weight of a message without executing it. This restricts the possible use-cases
|
||||
//! but is necessary since the pezpallet runs in `on_initialize` which has a hard weight limit. The
|
||||
//! weight meter is used in a way that `can_accrue` and `check_accrue` are always used to check the
|
||||
//! remaining weight of an operation before committing to it. The process of exiting due to
|
||||
//! insufficient weight is termed "bailing".
|
||||
//!
|
||||
//! # Scenario: Message enqueuing
|
||||
//!
|
||||
@@ -117,12 +118,12 @@
|
||||
//! next *ready* queue. It then starts to service this queue by servicing as many pages of it as
|
||||
//! possible. Servicing a page means to execute as many message of it as possible. Each executed
|
||||
//! message is marked as *processed* if the [`Config::MessageProcessor`] return Ok. An event
|
||||
//! [`Event::Processed`] is emitted afterwards. It is possible that the weight limit of the pezpallet
|
||||
//! will never allow a specific message to be executed. In this case it remains as unprocessed and
|
||||
//! is skipped. This process stops if either there are no more messages in the queue or the
|
||||
//! remaining weight became insufficient to service this queue. If there is enough weight it tries
|
||||
//! to advance to the next *ready* queue and service it. This continues until there are no more
|
||||
//! queues on which it can make progress or not enough weight to check that.
|
||||
//! [`Event::Processed`] is emitted afterwards. It is possible that the weight limit of the
|
||||
//! pezpallet will never allow a specific message to be executed. In this case it remains as
|
||||
//! unprocessed and is skipped. This process stops if either there are no more messages in the queue
|
||||
//! or the remaining weight became insufficient to service this queue. If there is enough weight it
|
||||
//! tries to advance to the next *ready* queue and service it. This continues until there are no
|
||||
//! more queues on which it can make progress or not enough weight to check that.
|
||||
//!
|
||||
//! # Scenario: Overweight execution
|
||||
//!
|
||||
@@ -131,11 +132,11 @@
|
||||
//! [`pezframe_support::traits::ServiceQueues::service_queues`].
|
||||
//!
|
||||
//! Manual intervention in the form of
|
||||
//! [`pezframe_support::traits::ServiceQueues::execute_overweight`] is necessary. Overweight messages
|
||||
//! emit an [`Event::OverweightEnqueued`] event which can be used to extract the arguments for
|
||||
//! manual execution. This only works on permanently overweight messages. There is no guarantee that
|
||||
//! this will work since the message could be part of a stale page and be reaped before execution
|
||||
//! commences.
|
||||
//! [`pezframe_support::traits::ServiceQueues::execute_overweight`] is necessary. Overweight
|
||||
//! messages emit an [`Event::OverweightEnqueued`] event which can be used to extract the arguments
|
||||
//! for manual execution. This only works on permanently overweight messages. There is no guarantee
|
||||
//! that this will work since the message could be part of a stale page and be reaped before
|
||||
//! execution commences.
|
||||
//!
|
||||
//! # Terminology
|
||||
//!
|
||||
@@ -153,8 +154,8 @@
|
||||
//! queues via their `ready_neighbours` fields. A `Queue` is *ready* if it contains at least one
|
||||
//! `Message` which can be processed. Can be empty.
|
||||
//! - `ServiceHead`: A pointer into the `ReadyRing` to the next `Queue` to be serviced.
|
||||
//! - (`un`)`processed`: A message is marked as *processed* after it was executed by the pezpallet. A
|
||||
//! message which was either: not yet executed or could not be executed remains as `unprocessed`
|
||||
//! - (`un`)`processed`: A message is marked as *processed* after it was executed by the pezpallet.
|
||||
//! A message which was either: not yet executed or could not be executed remains as `unprocessed`
|
||||
//! which is the default state for a message after being enqueued.
|
||||
//! - `knitting`/`unknitting`: The means of adding or removing a `Queue` from the `ReadyRing`.
|
||||
//! - `MEL`: The Max Encoded Length of a type, see [`codec::MaxEncodedLen`].
|
||||
@@ -220,7 +221,6 @@ use pezframe_support::{
|
||||
};
|
||||
use pezframe_system::pezpallet_prelude::*;
|
||||
pub use pezpallet::*;
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_arithmetic::traits::{BaseArithmetic, Unsigned};
|
||||
use pezsp_core::{defer, H256};
|
||||
use pezsp_runtime::{
|
||||
@@ -228,6 +228,7 @@ use pezsp_runtime::{
|
||||
SaturatedConversion, Saturating, TransactionOutcome,
|
||||
};
|
||||
use pezsp_weights::WeightMeter;
|
||||
use scale_info::TypeInfo;
|
||||
pub use weights::WeightInfo;
|
||||
|
||||
/// Type for identifying a page.
|
||||
@@ -506,7 +507,8 @@ pub mod pezpallet {
|
||||
pub trait Config: pezframe_system::Config {
|
||||
/// The overarching event type.
|
||||
#[allow(deprecated)]
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
|
||||
type RuntimeEvent: From<Event<Self>>
|
||||
+ IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
|
||||
|
||||
/// Weight information for extrinsics in this pezpallet.
|
||||
type WeightInfo: WeightInfo;
|
||||
@@ -814,8 +816,8 @@ enum MessageExecutionStatus {
|
||||
StackLimitReached,
|
||||
}
|
||||
|
||||
/// The context to pass to [`Pezpallet::service_queues_impl`] through on_idle and on_initialize hooks
|
||||
/// We don't want to throw the defensive message if called from on_idle hook
|
||||
/// The context to pass to [`Pezpallet::service_queues_impl`] through on_idle and on_initialize
|
||||
/// hooks We don't want to throw the defensive message if called from on_idle hook
|
||||
#[derive(PartialEq)]
|
||||
enum ServiceQueuesContext {
|
||||
/// Context of on_idle hook.
|
||||
@@ -1773,8 +1775,8 @@ impl<T: Config> ServiceQueues for Pezpallet<T> {
|
||||
return Err(ExecuteOverweightError::InsufficientWeight);
|
||||
}
|
||||
|
||||
Pezpallet::<T>::do_execute_overweight(message_origin, page, index, weight.remaining()).map_err(
|
||||
|e| match e {
|
||||
Pezpallet::<T>::do_execute_overweight(message_origin, page, index, weight.remaining())
|
||||
.map_err(|e| match e {
|
||||
Error::<T>::InsufficientWeight => ExecuteOverweightError::InsufficientWeight,
|
||||
Error::<T>::AlreadyProcessed => ExecuteOverweightError::AlreadyProcessed,
|
||||
Error::<T>::QueuePaused => ExecuteOverweightError::QueuePaused,
|
||||
@@ -1782,8 +1784,7 @@ impl<T: Config> ServiceQueues for Pezpallet<T> {
|
||||
ExecuteOverweightError::NotFound,
|
||||
Error::<T>::RecursiveDisallowed => ExecuteOverweightError::RecursiveDisallowed,
|
||||
_ => ExecuteOverweightError::Other,
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ use crate::{mock::*, *};
|
||||
use pezframe_support::{
|
||||
assert_noop, assert_ok, assert_storage_noop, traits::BatchFootprint, StorageNoopGuard,
|
||||
};
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng};
|
||||
use pezsp_crypto_hashing::blake2_256;
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng};
|
||||
|
||||
#[test]
|
||||
fn mocked_weight_works() {
|
||||
@@ -1250,8 +1250,10 @@ fn permanently_overweight_limit_is_valid_basic() {
|
||||
MessageQueue::enqueue_message(msg(&m), Here);
|
||||
MessageQueue::service_queues(w.into());
|
||||
|
||||
let last_event =
|
||||
pezframe_system::Pezpallet::<Test>::events().into_iter().last().expect("No event");
|
||||
let last_event = pezframe_system::Pezpallet::<Test>::events()
|
||||
.into_iter()
|
||||
.last()
|
||||
.expect("No event");
|
||||
|
||||
// The weight overhead for a single message is set to 50. The message itself needs 200.
|
||||
// Every weight in range `[50, 249]` should result in a permanently overweight message:
|
||||
@@ -1310,8 +1312,10 @@ fn permanently_overweight_limit_is_valid_fuzzy() {
|
||||
MessageQueue::enqueue_message(msg(&m), Here);
|
||||
MessageQueue::service_queues(w.into());
|
||||
|
||||
let last_event =
|
||||
pezframe_system::Pezpallet::<Test>::events().into_iter().last().expect("No event");
|
||||
let last_event = pezframe_system::Pezpallet::<Test>::events()
|
||||
.into_iter()
|
||||
.last()
|
||||
.expect("No event");
|
||||
|
||||
if w < o + 200 {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user