mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 09:51:02 +00:00
Implementer's guide: downward messages and HRMP, take 2 (#1503)
* First stab at downward messages.
That also includes a notion of horizontal messages.
* Add some structure to the router.
* Update `ValidationOutputs`
* Add `processed_downward_messages` to `ValidationOutputs`.
Forgot to check that in.
* s/AccountId/ParaId
* DownwardMessage::ParachainSpecfic
* s/ensure_horizontal_messages_fits/ensure_horizontal_messages_fit
* Clarify that Router called for each candidate
* Update the preamble for Router.
* Rewrite the relay-chain extrinsic routines
* Update gloassary
* Add DMP to the glossary
* If the queue is empty, `processed_downward_messages` can be 0
* WIP
* Add condemned list
* Pivot to message-storing channel based HRMP
* Finished draft
* Tidy up
* Remove a duplicate glossary entry
* Fix typo
* Fix wording to emphasize that the channel is unidirectional
* Proper decrement `HrmpOpenChannelRequestCount`
* Add a comment for `HrmpOpenChannelRequestCount`.
* Remove old configuration values.
* Be more specific about the para{chain,thread} hrmp chan limits.
* Fix indentation so the lists are rendendered properly
* "to answer **the**" question instead of "a"
* Add a missing call to `check_processed_downward_messages`
* Clean more stuff during offboarding
* Fix typo
* Fix typo for the config
* Add a call to `prune_dmq`
* Add explicit invariants for ingress/egress indexes
* Add comments for the sender/reciever deposit config fields
* Document various fields and structs in Router module
* More docs
* Missing docs in Candidate.md
* Tabs to spaces in router.md
* Apply Rob's suggestion
* Add the hrmp_ prefix to the router messages
* Those are entry points
* Use SessionIndex type for the `age` field
* Use a struct to represent `HrmpChannelId`
* Put only MQCs into the LocalValidationData
* Close request can be initiated by the runtime directly
* Close request can be initiated by the runtime directly
* tabs/spaces
* Maintain the list of the outgoing paras in Router
* Update roadmap/implementers-guide/src/runtime/inclusion.md
Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
* fix typo
* Remove an unnecessary pair of code quotes
Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
@@ -7,12 +7,15 @@ Here you can find definitions of a bunch of jargon, usually specific to the Polk
|
||||
- Backed Candidate: A Backable Candidate noted in a relay-chain block
|
||||
- Backing: A set of statements proving that a Parachain Candidate is backable.
|
||||
- Collator: A node who generates Proofs-of-Validity (PoV) for blocks of a specific parachain.
|
||||
- DMP: (Downward Message Passing). Message passing from the relay-chain to a parachain.
|
||||
- Extrinsic: An element of a relay-chain block which triggers a specific entry-point of a runtime module with given arguments.
|
||||
- GRANDPA: (Ghost-based Recursive ANcestor Deriving Prefix Agreement). The algorithm validators use to guarantee finality of the Relay Chain.
|
||||
- HRMP: (Horizontally Relay-routed Message Passing). A mechanism for message passing between parachains (hence horizontal) that leverages the relay-chain storage. Predates XCMP.
|
||||
- Inclusion Pipeline: The set of steps taken to carry a Parachain Candidate from authoring, to backing, to availability and full inclusion in an active fork of its parachain.
|
||||
- Module: A component of the Runtime logic, encapsulating storage, routines, and entry-points.
|
||||
- Module Entry Point: A recipient of new information presented to the Runtime. This may trigger routines.
|
||||
- Module Routine: A piece of code executed within a module by block initialization, closing, or upon an entry point being triggered. This may execute computation, and read or write storage.
|
||||
- MQC: (Message Queue Chain). A cryptographic data structure that resembles an append-only linked list which doesn't store original values but only their hashes. The whole structure is described by a single hash, referred as a "head". When a value is appended, it's contents hashed with the previous head creating a hash that becomes a new head.
|
||||
- Node: A participant in the Polkadot network, who follows the protocols of communication and connection to other nodes. Nodes form a peer-to-peer network topology without a central authority.
|
||||
- Parachain Candidate, or Candidate: A proposed block for inclusion into a parachain.
|
||||
- Parablock: A block in a parachain.
|
||||
@@ -26,8 +29,11 @@ Here you can find definitions of a bunch of jargon, usually specific to the Polk
|
||||
- Runtime API: A means for the node-side behavior to access structured information based on the state of a fork of the blockchain.
|
||||
- Secondary Checker: A validator who has been randomly selected to perform secondary approval checks on a parablock which is pending approval.
|
||||
- Subsystem: A long-running task which is responsible for carrying out a particular category of work.
|
||||
- UMP: (Upward Message Passing) A vertical message passing mechanism from a parachain to the relay chain.
|
||||
- Validator: Specially-selected node in the network who is responsible for validating parachain blocks and issuing attestations about their validity.
|
||||
- Validation Function: A piece of Wasm code that describes the state-transition function of a parachain.
|
||||
- VMP: (Vertical Message Passing) A family of mechanisms that are responsible for message exchange between the relay chain and parachains.
|
||||
- XCMP (Cross-Chain Message Passing) A type of horizontal message passing (i.e. between parachains) that allows secure message passing directly between parachains and has minimal resource requirements from the relay chain, thus highly scalable.
|
||||
|
||||
Also of use is the [Substrate Glossary](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary).
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ All failed checks should lead to an unrecoverable error making the block invalid
|
||||
1. Check the collator's signature on the candidate data.
|
||||
1. check the backing of the candidate using the signatures and the bitfields, comparing against the validators assigned to the groups, fetched with the `group_validators` lookup.
|
||||
1. check that the upward messages, when combined with the existing queue size, are not exceeding `config.max_upward_queue_count` and `config.watermark_upward_queue_size` parameters.
|
||||
1. call `Router::check_processed_downward_messages(para, commitments.processed_downward_messages)` to check that the DMQ is properly drained.
|
||||
1. call `Router::check_hrmp_watermark(para, commitments.hrmp_watermark)` for each candidate to check rules of processing the HRMP watermark.
|
||||
1. check that in the commitments of each candidate the horizontal messages are sorted by ascending recipient ParaId and there is no two horizontal messages have the same recipient.
|
||||
1. using `Router::verify_outbound_hrmp(sender, commitments.horizontal_messages)` ensure that the each candidate send a valid set of horizontal messages
|
||||
1. create an entry in the `PendingAvailability` map for each backed candidate with a blank `availability_votes` bitfield.
|
||||
1. create a corresponding entry in the `PendingAvailabilityCommitments` with the commitments.
|
||||
1. Return a `Vec<CoreIndex>` of all scheduled cores of the list of passed assignments that a candidate was successfully backed for, sorted ascending by CoreIndex.
|
||||
@@ -76,6 +80,9 @@ All failed checks should lead to an unrecoverable error making the block invalid
|
||||
1. If the receipt contains a code upgrade, Call `Paras::schedule_code_upgrade(para_id, code, relay_parent_number + config.validationl_upgrade_delay)`.
|
||||
> TODO: Note that this is safe as long as we never enact candidates where the relay parent is across a session boundary. In that case, which we should be careful to avoid with contextual execution, the configuration might have changed and the para may de-sync from the host's understanding of it.
|
||||
1. call `Router::queue_upward_messages` for each backed candidate, using the [`UpwardMessage`s](../types/messages.md#upward-message) from the [`CandidateCommitments`](../types/candidate.md#candidate-commitments).
|
||||
1. call `Router::queue_outbound_hrmp` with the para id of the candidate and the list of horizontal messages taken from the commitment,
|
||||
1. call `Router::prune_hrmp` with the para id of the candiate and the candidate's `hrmp_watermark`.
|
||||
1. call `Router::prune_dmq` with the para id of the candidate and the candidate's `processed_downward_messages`.
|
||||
1. Call `Paras::note_new_head` using the `HeadData` from the receipt and `relay_parent_number`.
|
||||
* `collect_pending`:
|
||||
|
||||
|
||||
@@ -93,7 +93,8 @@ OutgoingParas: Vec<ParaId>;
|
||||
|
||||
## Session Change
|
||||
|
||||
1. Clean up outgoing paras. This means removing the entries under `Heads`, `ValidationCode`, `FutureCodeUpgrades`, and `FutureCode`. An according entry should be added to `PastCode`, `PastCodeMeta`, and `PastCodePruning` using the outgoing `ParaId` and removed `ValidationCode` value. This is because any outdated validation code must remain available on-chain for a determined amount of blocks, and validation code outdated by de-registering the para is still subject to that invariant.
|
||||
1. Clean up outgoing paras.
|
||||
1. This means removing the entries under `Heads`, `ValidationCode`, `FutureCodeUpgrades`, and `FutureCode`. An according entry should be added to `PastCode`, `PastCodeMeta`, and `PastCodePruning` using the outgoing `ParaId` and removed `ValidationCode` value. This is because any outdated validation code must remain available on-chain for a determined amount of blocks, and validation code outdated by de-registering the para is still subject to that invariant.
|
||||
1. Apply all incoming paras by initializing the `Heads` and `ValidationCode` using the genesis parameters.
|
||||
1. Amend the `Parachains` list to reflect changes in registered parachains.
|
||||
1. Amend the `Parathreads` set to reflect changes in registered parathreads.
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# Router Module
|
||||
|
||||
The Router module is responsible for storing and dispatching Upward and Downward messages from and to parachains respectively. It is intended to later handle the XCMP logic as well.
|
||||
|
||||
For each enacted block the `queue_upward_messages` entry-point is called.
|
||||
The Router module is responsible for all messaging mechanisms supported between paras and the relay chain, specifically: UMP, DMP, HRMP and later XCMP.
|
||||
|
||||
## Storage
|
||||
|
||||
Storage layout:
|
||||
|
||||
```rust,ignore
|
||||
/// Paras that are to be cleaned up at the end of the session.
|
||||
/// The entries are sorted ascending by the para id.
|
||||
OutgoingParas: Vec<ParaId>;
|
||||
/// Messages ready to be dispatched onto the relay chain.
|
||||
/// This is subject to `max_upward_queue_count` and
|
||||
/// `watermark_queue_size` from `HostConfiguration`.
|
||||
@@ -19,17 +20,221 @@ RelayDispatchQueues: map ParaId => Vec<UpwardMessage>;
|
||||
RelayDispatchQueueSize: map ParaId => (u32, u32);
|
||||
/// The ordered list of `ParaId`s that have a `RelayDispatchQueue` entry.
|
||||
NeedsDispatch: Vec<ParaId>;
|
||||
/// The downward messages addressed for a certain para.
|
||||
DownwardMessageQueues: map ParaId => Vec<DownwardMessage>;
|
||||
```
|
||||
|
||||
### HRMP
|
||||
|
||||
HRMP related structs:
|
||||
|
||||
```rust,ignore
|
||||
/// A type used to designate a HRMP channel between a (sender, recipient).
|
||||
struct HrmpChannelId {
|
||||
sender: ParaId,
|
||||
recipient: ParaId,
|
||||
}
|
||||
|
||||
/// A description of a request to open an HRMP channel.
|
||||
struct HrmpOpenChannelRequest {
|
||||
/// The sender and the initiator of this request.
|
||||
sender: ParaId,
|
||||
/// The recipient of the opened request.
|
||||
recipient: ParaId,
|
||||
/// Indicates if this request was confirmed by the recipient.
|
||||
confirmed: bool,
|
||||
/// How many session boundaries ago this request was seen.
|
||||
age: SessionIndex,
|
||||
/// The amount that the sender supplied at the time of creation of this request.
|
||||
sender_deposit: Balance,
|
||||
/// The maximum number of messages that can be pending in the channel at once.
|
||||
limit_used_places: u32,
|
||||
/// The maximum total size of the messages that can be pending in the channel at once.
|
||||
limit_used_bytes: u32,
|
||||
}
|
||||
|
||||
/// A description of a request to close an opened HRMP channel.
|
||||
struct HrmpCloseChannelRequest {
|
||||
/// The para which initiated closing an existing channel.
|
||||
///
|
||||
/// Invariant: it should be equal to one of the following
|
||||
/// - `Some(sender)`
|
||||
/// - `Some(recipient)`
|
||||
/// - `None` in case the request initiated by the runtime (including governance, migration, etc)
|
||||
initiator: Option<ParaId>,
|
||||
/// The identifier of an HRMP channel to be closed.
|
||||
id: HrmpChannelId,
|
||||
}
|
||||
|
||||
/// A metadata of an HRMP channel.
|
||||
struct HrmpChannel {
|
||||
/// The amount that the sender supplied as a deposit when opening this channel.
|
||||
sender_deposit: Balance,
|
||||
/// The amount that the recipient supplied as a deposit when accepting opening this channel.
|
||||
recipient_deposit: Balance,
|
||||
/// The maximum number of messages that can be pending in the channel at once.
|
||||
limit_used_places: u32,
|
||||
/// The maximum total size of the messages that can be pending in the channel at once.
|
||||
limit_used_bytes: u32,
|
||||
/// The current number of messages pending in the channel.
|
||||
/// Invariant: should be less or equal to `limit_used_places`.
|
||||
used_places: u32,
|
||||
/// The total size in bytes of all message payloads in the channel.
|
||||
/// Invariant: should be less or equal to `limit_used_bytes`.
|
||||
used_bytes: u32,
|
||||
/// A head of the Message Queue Chain for this channel. Each link in this chain has a form:
|
||||
/// `(prev_head, B, H(M))`, where
|
||||
/// - `prev_head`: is the previous value of `mqc_head`.
|
||||
/// - `B`: is the [relay-chain] block number in which a message was appended
|
||||
/// - `H(M)`: is the hash of the message being appended.
|
||||
/// This value is initialized to a special value that consists of all zeroes which indicates
|
||||
/// that no messages were previously added.
|
||||
mqc_head: Hash,
|
||||
}
|
||||
```
|
||||
HRMP related storage layout
|
||||
|
||||
```rust,ignore
|
||||
/// Pending HRMP open channel requests.
|
||||
HrmpOpenChannelRequests: Vec<HrmpOpenChannelRequest>;
|
||||
/// This mapping tracks how many open channel requests are inititated by a given sender para.
|
||||
/// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has `_.sender == X`
|
||||
/// as the number of `HrmpOpenChannelRequestCount` for `X`.
|
||||
HrmpOpenChannelRequestCount: map ParaId => u32;
|
||||
/// Pending HRMP close channel requests.
|
||||
HrmpCloseChannelRequests: Vec<HrmpCloseChannelRequest>;
|
||||
/// The HRMP watermark associated with each para.
|
||||
HrmpWatermarks: map ParaId => Option<BlockNumber>;
|
||||
/// HRMP channel data associated with each para.
|
||||
HrmpChannels: map HrmpChannelId => Option<HrmpChannel>;
|
||||
/// The indexes that map all senders to their recievers and vise versa.
|
||||
/// Invariants:
|
||||
/// - for each ingress index entry for `P` each item `I` in the index should present in `HrmpChannels` as `(I, P)`.
|
||||
/// - for each egress index entry for `P` each item `E` in the index should present in `HrmpChannels` as `(P, E)`.
|
||||
/// - there should be no other dangling channels in `HrmpChannels`.
|
||||
HrmpIngressChannelsIndex: map ParaId => Vec<ParaId>;
|
||||
HrmpEgressChannelsIndex: map ParaId => Vec<ParaId>;
|
||||
/// Storage for the messages for each channel.
|
||||
/// Invariant: cannot be non-empty if the corresponding channel in `HrmpChannels` is `None`.
|
||||
HrmpChannelContents: map HrmpChannelId => Vec<InboundHrmpMessage>;
|
||||
/// Maintains a mapping that can be used to answer the question:
|
||||
/// What paras sent a message at the given block number for a given reciever.
|
||||
HrmpChannelDigests: map ParaId => Vec<(BlockNumber, Vec<ParaId>)>;
|
||||
```
|
||||
|
||||
## Initialization
|
||||
|
||||
No initialization routine runs for this module.
|
||||
|
||||
## Entry points
|
||||
|
||||
The following routines are intended to be invoked by paras' upward messages.
|
||||
|
||||
* `hrmp_init_open_channel(recipient)`:
|
||||
1. Check that the origin of this message is a para. We say that the origin of this message is the `sender`.
|
||||
1. Check that the `sender` is not `recipient`.
|
||||
1. Check that the `recipient` para exists.
|
||||
1. Check that there is no existing open channel request from sender to recipient.
|
||||
1. Check that the sum of the number of already opened HRMP channels by the `sender` (the size of the set found `HrmpEgressChannelsIndex` for `sender`) and the number of open requests by the `sender` (the value from `HrmpOpenChannelRequestCount` for `sender`) doesn't exceed the limit of channels (`config.hrmp_max_parachain_outbound_channels` or `config.hrmp_max_parathread_outbound_channels`) minus 1.
|
||||
1. Reserve the deposit for the `sender` according to `config.hrmp_sender_deposit`
|
||||
1. Add a new entry to `HrmpOpenChannelRequests` and increase `HrmpOpenChannelRequestCount` by 1 for the `sender`.
|
||||
1. Set `sender_deposit` to `config.hrmp_sender_deposit`
|
||||
1. Set `limit_used_places` to `config.hrmp_channel_max_places`
|
||||
1. Set `limit_limit_used_bytes` to `config.hrmp_channel_max_size`
|
||||
|
||||
* `hrmp_accept_open_channel(i)`, `i` - is the index of open channel request:
|
||||
1. Check that the designated open channel request exists
|
||||
1. Check that the request's `recipient` corresponds to the origin of this message.
|
||||
1. Reserve the deposit for the `recipient` according to `config.hrmp_recipient_deposit`
|
||||
1. Set the request's `confirmed` flag to `true`.
|
||||
|
||||
* `hrmp_close_channel(sender, recipient)`:
|
||||
1. Check that the channel between `sender` and `recipient` exists
|
||||
1. Check that the origin of the message is either `sender` or `recipient`
|
||||
1. Check that there is no existing intention to close the channel between `sender` and `recipient`.
|
||||
1. Add a new entry to `HrmpCloseChannelRequests` with initiator set to the `Some` variant with the origin of this message.
|
||||
|
||||
## Routines
|
||||
|
||||
Candidate Acceptance Function:
|
||||
|
||||
* `check_processed_downward_messages(P: ParaId, processed_downward_messages)`:
|
||||
1. Checks that `DownwardMessageQueues` for `P` is at least `processed_downward_messages` long.
|
||||
1. Checks that `processed_downward_messages` is at least 1 if `DownwardMessageQueues` for `P` is not empty.
|
||||
* `check_hrmp_watermark(P: ParaId, new_hrmp_watermark)`:
|
||||
1. `new_hrmp_watermark` should be strictly greater than the value of `HrmpWatermarks` for `P` (if any).
|
||||
1. `new_hrmp_watermark` must not be greater than the context's block number.
|
||||
1. in `HrmpChannelDigests` for `P` an entry with the block number equal to `new_hrmp_watermark` should exist.
|
||||
* `verify_outbound_hrmp(sender: ParaId, Vec<OutboundHrmpMessage>)`:
|
||||
1. For each horizontal message `M` with the channel `C` identified by `(sender, M.recipient)` check:
|
||||
1. exists
|
||||
1. `M`'s payload size summed with the `C.used_bytes` doesn't exceed a preconfigured limit `C.limit_used_bytes`.
|
||||
1. `C.used_places + 1` doesn't exceed a preconfigured limit `C.limit_used_places`.
|
||||
|
||||
Candidate Enactment:
|
||||
|
||||
* `queue_outbound_hrmp(sender: ParaId, Vec<OutboundHrmpMessage>)`:
|
||||
1. For each horizontal message `HM` with the channel `C` identified by `(sender, HM.recipient)`:
|
||||
1. Append `HM` into `HrmpChannelContents` that corresponds to `C`.
|
||||
1. Locate or create an entry in ``HrmpChannelDigests`` for `HM.recipient` and append `sender` into the entry's list.
|
||||
1. Increment `C.used_places`
|
||||
1. Increment `C.used_bytes` by `HM`'s payload size
|
||||
1. Append a new link to the MQC and save the new head in `C.mqc_head`. Note that the current block number as of enactment is used for the link.
|
||||
* `prune_hrmp(recipient, new_hrmp_watermark)`:
|
||||
1. From ``HrmpChannelDigests`` for `recipient` remove all entries up to an entry with block number equal to `new_hrmp_watermark`.
|
||||
1. From the removed digests construct a set of paras that sent new messages within the interval between the old and new watermarks.
|
||||
1. For each channel `C` identified by `(sender, recipient)` for each `sender` coming from the set, prune messages up to the `new_hrmp_watermark`.
|
||||
1. For each pruned message `M` from channel `C`:
|
||||
1. Decrement `C.used_places`
|
||||
1. Decrement `C.used_bytes` by `M`'s payload size.
|
||||
1. Set `HrmpWatermarks` for `P` to be equal to `new_hrmp_watermark`
|
||||
* `prune_dmq(P: ParaId, processed_downward_messages)`:
|
||||
1. Remove the first `processed_downward_messages` from the `DownwardMessageQueues` of `P`.
|
||||
|
||||
* `queue_upward_messages(ParaId, Vec<UpwardMessage>)`:
|
||||
1. Updates `NeedsDispatch`, and enqueues upward messages into `RelayDispatchQueue` and modifies the respective entry in `RelayDispatchQueueSize`.
|
||||
|
||||
The following routine is intended to be called in the same time when `Paras::schedule_para_cleanup` is called.
|
||||
|
||||
`schedule_para_cleanup(ParaId)`:
|
||||
1. Add the para into the `OutgoingParas` vector maintaining the sorted order.
|
||||
|
||||
## Session Change
|
||||
|
||||
1. Drain `OutgoingParas`. For each `P` happened to be in the list:
|
||||
1. Remove all inbound channels of `P`, i.e. `(_, P)`,
|
||||
1. Remove all outbound channels of `P`, i.e. `(P, _)`,
|
||||
1. Remove all `DownwardMessageQueues` of `P`.
|
||||
1. Remove `RelayDispatchQueueSize` of `P`.
|
||||
1. Remove `RelayDispatchQueues` of `P`.
|
||||
- Note that we don't remove the open/close requests since they are gon die out naturally.
|
||||
TODO: What happens with the deposits in channels or open requests?
|
||||
1. For each request `R` in `HrmpOpenChannelRequests`:
|
||||
1. if `R.confirmed = false`:
|
||||
1. increment `R.age` by 1.
|
||||
1. if `R.age` reached a preconfigured time-to-live limit `config.hrmp_open_request_ttl`, then:
|
||||
1. refund `R.sender_deposit` to the sender
|
||||
1. decrement `HrmpOpenChannelRequestCount` for `R.sender` by 1.
|
||||
1. remove `R`
|
||||
2. if `R.confirmed = true`,
|
||||
1. check that `R.sender` and `R.recipient` are not offboarded.
|
||||
1. create a new channel `C` between `(R.sender, R.recipient)`.
|
||||
1. Initialize the `C.sender_deposit` with `R.sender_deposit` and `C.recipient_deposit` with the value found in the configuration `config.hrmp_recipient_deposit`.
|
||||
1. Insert `sender` into the set `HrmpIngressChannelsIndex` for the `recipient`.
|
||||
1. Insert `recipient` into the set `HrmpEgressChannelsIndex` for the `sender`.
|
||||
1. decrement `HrmpOpenChannelRequestCount` for `R.sender` by 1.
|
||||
1. remove `R`
|
||||
1. For each request `R` in `HrmpCloseChannelRequests` remove the channel identified by `R.id`, if exists.
|
||||
|
||||
To remove a channel `C` identified with a tuple `(sender, recipient)`:
|
||||
|
||||
1. Return `C.sender_deposit` to the `sender`.
|
||||
1. Return `C.recipient_deposit` to the `recipient`.
|
||||
1. Remove `C` from `HrmpChannels`.
|
||||
1. Remove `C` from `HrmpChannelContents`.
|
||||
1. Remove `recipient` from the set `HrmpEgressChannelsIndex` for `sender`.
|
||||
1. Remove `sender` from the set `HrmpIngressChannelsIndex` for `recipient`.
|
||||
|
||||
## Finalization
|
||||
|
||||
1. Dispatch queued upward messages from `RelayDispatchQueues` in a FIFO order applying the `config.watermark_upward_queue_size` and `config.max_upward_queue_count` limits.
|
||||
|
||||
@@ -151,6 +151,10 @@ struct LocalValidationData {
|
||||
/// which case the code upgrade should be applied at the end of the signaling
|
||||
/// block.
|
||||
code_upgrade_allowed: Option<BlockNumber>,
|
||||
/// The list of MQC heads for the inbound channels paired with the sender para ids. This
|
||||
/// vector is sorted ascending by the para id and doesn't contain multiple entries with the same
|
||||
/// sender.
|
||||
hrmp_mqc_heads: Vec<(ParaId, Hash)>,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -173,6 +177,8 @@ The execution and validation of parachain or parathread candidates produces a nu
|
||||
struct CandidateCommitments {
|
||||
/// Fees paid from the chain to the relay chain validators.
|
||||
fees: Balance,
|
||||
/// Messages directed to other paras routed via the relay chain.
|
||||
horizontal_messages: Vec<OutboundHrmpMessage>,
|
||||
/// Messages destined to be interpreted by the Relay chain itself.
|
||||
upward_messages: Vec<UpwardMessage>,
|
||||
/// The root of a block's erasure encoding Merkle tree.
|
||||
@@ -181,6 +187,10 @@ struct CandidateCommitments {
|
||||
new_validation_code: Option<ValidationCode>,
|
||||
/// The head-data produced as a result of execution.
|
||||
head_data: HeadData,
|
||||
/// The number of messages processed from the DMQ.
|
||||
processed_downward_messages: u32,
|
||||
/// The mark which specifies the block number up to which all inbound HRMP messages are processed.
|
||||
hrmp_watermark: BlockNumber,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -209,11 +219,17 @@ struct ValidationOutputs {
|
||||
global_validation_data: GlobalValidationData,
|
||||
/// The local validation data.
|
||||
local_validation_data: LocalValidationData,
|
||||
/// Messages directed to other paras routed via the relay chain.
|
||||
horizontal_messages: Vec<OutboundHrmpMessage>,
|
||||
/// Upwards messages to the relay chain.
|
||||
upwards_messages: Vec<UpwardsMessage>,
|
||||
/// Fees paid to the validators of the relay-chain.
|
||||
fees: Balance,
|
||||
/// The new validation code submitted by the execution, if any.
|
||||
new_validation_code: Option<ValidationCode>,
|
||||
/// The number of messages processed from the DMQ.
|
||||
processed_downward_messages: u32,
|
||||
/// The mark which specifies the block number up to which all inbound HRMP messages are processed.
|
||||
hrmp_watermark: BlockNumber,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
Types of messages that are passed between parachains and the relay chain: UMP, DMP, XCMP.
|
||||
|
||||
There is also HRMP (Horizontally Relay-routed Message Passing) which provides the same functionality
|
||||
although with smaller scalability potential.
|
||||
|
||||
## Upward Message
|
||||
|
||||
A type of messages dispatched from a parachain to the relay chain.
|
||||
@@ -26,3 +29,41 @@ struct UpwardMessage {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
```
|
||||
|
||||
## Horizontal Message
|
||||
|
||||
This is a message sent from a parachain to another parachain that travels through the relay chain.
|
||||
This message ends up in the recipient's mailbox. A size of a horizontal message is defined by its
|
||||
`data` payload.
|
||||
|
||||
```rust,ignore
|
||||
struct OutboundHrmpMessage {
|
||||
/// The para that will get this message in its downward message queue.
|
||||
pub recipient: ParaId,
|
||||
/// The message payload.
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
struct InboundHrmpMessage {
|
||||
pub sent_at: BlockNumber,
|
||||
/// The message payload.
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
```
|
||||
|
||||
## Downward Message
|
||||
|
||||
A message that go down from the relay chain to a parachain. Such a message could be initiated either
|
||||
as a result of an operation took place on the relay chain.
|
||||
|
||||
```rust,ignore
|
||||
enum DownwardMessage {
|
||||
/// Some funds were transferred into the parachain's account. The hash is the identifier that
|
||||
/// was given with the transfer.
|
||||
TransferInto(AccountId, Balance, Remark),
|
||||
/// An opaque message which interpretation is up to the recipient para. This variant ought
|
||||
/// to be used as a basis for special protocols between the relay chain and, typically system,
|
||||
/// paras.
|
||||
ParachainSpecific(Vec<u8>),
|
||||
}
|
||||
```
|
||||
|
||||
@@ -40,5 +40,19 @@ struct HostConfiguration {
|
||||
/// no further messages may be added to it. If it exceeds this then the queue may contain only
|
||||
/// a single message.
|
||||
pub watermark_upward_queue_size: u32,
|
||||
/// Number of sessions after which an HRMP open channel request expires.
|
||||
pub hrmp_open_request_ttl: u32,
|
||||
/// The deposit that the sender should provide for opening an HRMP channel.
|
||||
pub hrmp_sender_deposit: u32,
|
||||
/// The deposit that the recipient should provide for accepting opening an HRMP channel.
|
||||
pub hrmp_recipient_deposit: u32,
|
||||
/// The maximum number of messages allowed in an HRMP channel at once.
|
||||
pub hrmp_channel_max_places: u32,
|
||||
/// The maximum total size of messages in bytes allowed in an HRMP channel at once.
|
||||
pub hrmp_channel_max_size: u32,
|
||||
/// The maximum number of outbound HRMP channels a parachain is allowed to open.
|
||||
pub hrmp_max_parachain_outbound_channels: u32,
|
||||
/// The maximum number of outbound HRMP channels a parathread is allowed to open.
|
||||
pub hrmp_max_parathread_outbound_channels: u32,
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user