UMP Module
A module responsible for Upward Message Passing (UMP). See Messaging Overview for more details.
Storage
Storage related to UMP
#![allow(unused)] fn main() { /// The messages waiting to be handled by the relay-chain originating from a certain parachain. /// /// Note that some upward messages might have been already processed by the inclusion logic. E.g. /// channel management messages. /// /// The messages are processed in FIFO order. RelayDispatchQueues: map ParaId => Vec<UpwardMessage>; /// Size of the dispatch queues. Caches sizes of the queues in `RelayDispatchQueue`. /// /// First item in the tuple is the count of messages and second /// is the total length (in bytes) of the message payloads. /// /// Note that this is an auxilary mapping: it's possible to tell the byte size and the number of /// messages only looking at `RelayDispatchQueues`. This mapping is separate to avoid the cost of /// loading the whole message queue if only the total size and count are required. /// /// Invariant: /// - The set of keys should exactly match the set of keys of `RelayDispatchQueues`. RelayDispatchQueueSize: map ParaId => (u32, u32); // (num_messages, total_bytes) /// The ordered list of `ParaId`s that have a `RelayDispatchQueue` entry. /// /// Invariant: /// - The set of items from this vector should be exactly the set of the keys in /// `RelayDispatchQueues` and `RelayDispatchQueueSize`. NeedsDispatch: Vec<ParaId>; /// This is the para that gets dispatched first during the next upward dispatchable queue /// execution round. /// /// Invariant: /// - If `Some(para)`, then `para` must be present in `NeedsDispatch`. NextDispatchRoundStartWith: Option<ParaId>; }
Initialization
No initialization routine runs for this module.
Routines
Candidate Acceptance Function:
check_upward_messages(P: ParaId, Vec<UpwardMessage>
):- Checks that there are at most
config.max_upward_message_num_per_candidate
messages. - Checks that no message exceeds
config.max_upward_message_size
. - Verify that
RelayDispatchQueueSize
forP
has enough capacity for the messages
- Checks that there are at most
Candidate Enactment:
receive_upward_messages(P: ParaId, Vec<UpwardMessage>)
:- Process each upward message
M
in order:- Append the message to
RelayDispatchQueues
forP
- Increment the size and the count in
RelayDispatchQueueSize
forP
. - Ensure that
P
is present inNeedsDispatch
.
- Append the message to
- Process each upward message
The following routine is meant to execute pending entries in upward message queues. This function doesn't fail, even if dispatching any of individual upward messages returns an error.
process_pending_upward_messages()
:
- Initialize a cumulative weight counter
T
to 0 - Iterate over items in
NeedsDispatch
cyclically, starting withNextDispatchRoundStartWith
. If the item specified isNone
start from the beginning. For eachP
encountered: - Dequeue the first upward message
D
fromRelayDispatchQueues
forP
- Decrement the size of the message from
RelayDispatchQueueSize
forP
- Delegate processing of the message to the runtime. The weight consumed is added to
T
. - If
T >= config.ump_service_total_weight
, setNextDispatchRoundStartWith
toP
and finish processing. - If
RelayDispatchQueues
forP
became empty, removeP
fromNeedsDispatch
. - If
NeedsDispatch
became empty then finish processing and setNextDispatchRoundStartWith
toNone
. > NOTE that in practice we would need to approach the weight calculation more thoroughly, i.e. incorporate all operations > that could take place on the course of handling these upward messages.
Session Change
- For each
P
inoutgoing_paras
(generated byParas::on_new_session
):- Remove
RelayDispatchQueueSize
ofP
. - Remove
RelayDispatchQueues
ofP
. - Remove
P
if it exists inNeedsDispatch
. - If
P
is inNextDispatchRoundStartWith
, then reset it toNone
- Note that if we don't remove the open/close requests since they are going to die out naturally at the end of the session.
- Remove