mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-20 01:11:08 +00:00
Implementer's Guide: Incorporate HRMP to TransientValidationData (#1588)
* Add a note about time of collection of TransientValidationData * Add HRMP digest and dmq length to TransientValidationData * Add a note that the vector in hrmp digest is never empty * Add hrmp watermark to TransientValidationData * Add HRMP egress limits * Incorporate the latest dispatchable upward messages changes. * Update candidate.md * Update candidate.md docs * Fix wording * Delete assignmets.md * Update roadmap/implementers-guide/src/types/candidate.md Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Extract HrmpTransientValidationData and add additional data. * Some clarifications. * Introduce HrmpAbridgedOpenChannelRequest * Update roadmap/implementers-guide/src/types/candidate.md Co-authored-by: Bernhard Schuster <bernhard@ahoi.io> * Fix typo: egress->ingress * A note about sorting Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bernhard Schuster <bernhard@ahoi.io>
This commit is contained in:
@@ -6,7 +6,7 @@ The Router module is responsible for all messaging mechanisms supported between
|
|||||||
|
|
||||||
Storage layout:
|
Storage layout:
|
||||||
|
|
||||||
```rust,ignore
|
```rust
|
||||||
/// Paras that are to be cleaned up at the end of the session.
|
/// Paras that are to be cleaned up at the end of the session.
|
||||||
/// The entries are sorted ascending by the para id.
|
/// The entries are sorted ascending by the para id.
|
||||||
OutgoingParas: Vec<ParaId>;
|
OutgoingParas: Vec<ParaId>;
|
||||||
@@ -31,7 +31,7 @@ DownwardMessageQueues: map ParaId => Vec<DownwardMessage>;
|
|||||||
|
|
||||||
HRMP related structs:
|
HRMP related structs:
|
||||||
|
|
||||||
```rust,ignore
|
```rust
|
||||||
/// A description of a request to open an HRMP channel.
|
/// A description of a request to open an HRMP channel.
|
||||||
struct HrmpOpenChannelRequest {
|
struct HrmpOpenChannelRequest {
|
||||||
/// Indicates if this request was confirmed by the recipient.
|
/// Indicates if this request was confirmed by the recipient.
|
||||||
@@ -74,7 +74,7 @@ struct HrmpChannel {
|
|||||||
```
|
```
|
||||||
HRMP related storage layout
|
HRMP related storage layout
|
||||||
|
|
||||||
```rust,ignore
|
```rust
|
||||||
/// The set of pending HRMP open channel requests.
|
/// The set of pending HRMP open channel requests.
|
||||||
///
|
///
|
||||||
/// The set is accompanied by a list for iteration.
|
/// The set is accompanied by a list for iteration.
|
||||||
@@ -115,6 +115,7 @@ HrmpEgressChannelsIndex: map ParaId => Vec<ParaId>;
|
|||||||
HrmpChannelContents: map HrmpChannelId => Vec<InboundHrmpMessage>;
|
HrmpChannelContents: map HrmpChannelId => Vec<InboundHrmpMessage>;
|
||||||
/// Maintains a mapping that can be used to answer the question:
|
/// 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.
|
/// What paras sent a message at the given block number for a given reciever.
|
||||||
|
/// Invariant: The vector is never empty.
|
||||||
HrmpChannelDigests: map ParaId => Vec<(BlockNumber, Vec<ParaId>)>;
|
HrmpChannelDigests: map ParaId => Vec<(BlockNumber, Vec<ParaId>)>;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -135,6 +136,7 @@ Candidate Acceptance Function:
|
|||||||
1. If the message kind is `HrmpInitOpenChannel(recipient)`:
|
1. If the message kind is `HrmpInitOpenChannel(recipient)`:
|
||||||
1. Check that the `P` is not `recipient`.
|
1. Check that the `P` is not `recipient`.
|
||||||
1. Check that `recipient` is a valid para.
|
1. Check that `recipient` is a valid para.
|
||||||
|
1. Check that there is no existing channel for `(P, recipient)` in `HrmpChannels`.
|
||||||
1. Check that there is no existing open channel request (`P`, `recipient`) in `HrmpOpenChannelRequests`.
|
1. Check that there is no existing open channel request (`P`, `recipient`) in `HrmpOpenChannelRequests`.
|
||||||
1. Check that the sum of the number of already opened HRMP channels by the `sender` (the size
|
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
|
of the set found `HrmpEgressChannelsIndex` for `sender`) and the number of open requests by the
|
||||||
@@ -142,7 +144,8 @@ Candidate Acceptance Function:
|
|||||||
channels (`config.hrmp_max_parachain_outbound_channels` or `config.hrmp_max_parathread_outbound_channels`) minus 1.
|
channels (`config.hrmp_max_parachain_outbound_channels` or `config.hrmp_max_parathread_outbound_channels`) minus 1.
|
||||||
1. Check that `P`'s balance is more or equal to `config.hrmp_sender_deposit`
|
1. Check that `P`'s balance is more or equal to `config.hrmp_sender_deposit`
|
||||||
1. If the message kind is `HrmpAcceptOpenChannel(sender)`:
|
1. If the message kind is `HrmpAcceptOpenChannel(sender)`:
|
||||||
1. Check that there is existing request between (`sender`, `P`) in `HrmpOpenChannelRequests`
|
1. Check that there is an existing request between (`sender`, `P`) in `HrmpOpenChannelRequests`
|
||||||
|
1. Check that it is not confirmed.
|
||||||
1. Check that `P`'s balance is more or equal to `config.hrmp_recipient_deposit`.
|
1. Check that `P`'s balance is more or equal to `config.hrmp_recipient_deposit`.
|
||||||
1. If the message kind is `HrmpCloseChannel(ch)`:
|
1. If the message kind is `HrmpCloseChannel(ch)`:
|
||||||
1. Check that `P` is either `ch.sender` or `ch.recipient`
|
1. Check that `P` is either `ch.sender` or `ch.recipient`
|
||||||
|
|||||||
@@ -96,6 +96,10 @@ Persisted validation data are generally derived from some relay-chain state to f
|
|||||||
|
|
||||||
The validation data also serve the purpose of giving collators a means of ensuring that their produced candidate and the commitments submitted to the relay-chain alongside it will pass the checks done by the relay-chain when backing, and give validators the same understanding when determining whether to second or attest to a candidate.
|
The validation data also serve the purpose of giving collators a means of ensuring that their produced candidate and the commitments submitted to the relay-chain alongside it will pass the checks done by the relay-chain when backing, and give validators the same understanding when determining whether to second or attest to a candidate.
|
||||||
|
|
||||||
|
Furthermore, the validation data acts as a way to authorize the additional data the collator needs to pass to the validation
|
||||||
|
function. For example, the validation function can check whether the incoming messages (e.g. downward messages) were actually
|
||||||
|
sent by using the data provided in the validation data using so called MQC heads.
|
||||||
|
|
||||||
Since the commitments of the validation function are checked by the relay-chain, secondary checkers can rely on the invariant that the relay-chain only includes para-blocks for which these checks have already been done. As such, there is no need for the validation data used to inform validators and collators about the checks the relay-chain will perform to be persisted by the availability system. Nevertheless, we expose it so the backing validators can validate the outputs of a candidate before voting to submit it to the relay-chain and so collators can collate candidates that satisfy the criteria implied these transient validation data.
|
Since the commitments of the validation function are checked by the relay-chain, secondary checkers can rely on the invariant that the relay-chain only includes para-blocks for which these checks have already been done. As such, there is no need for the validation data used to inform validators and collators about the checks the relay-chain will perform to be persisted by the availability system. Nevertheless, we expose it so the backing validators can validate the outputs of a candidate before voting to submit it to the relay-chain and so collators can collate candidates that satisfy the criteria implied these transient validation data.
|
||||||
|
|
||||||
Design-wise we should maintain two properties about this data structure:
|
Design-wise we should maintain two properties about this data structure:
|
||||||
@@ -121,10 +125,12 @@ struct PersistedValidationData {
|
|||||||
parent_head: HeadData,
|
parent_head: HeadData,
|
||||||
/// The relay-chain block number this is in the context of. This informs the collator.
|
/// The relay-chain block number this is in the context of. This informs the collator.
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
/// The relay-chain
|
|
||||||
/// The list of MQC heads for the inbound channels paired with the sender para ids. This
|
/// 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
|
/// vector is sorted ascending by the para id and doesn't contain multiple entries with the same
|
||||||
/// sender.
|
/// sender.
|
||||||
|
///
|
||||||
|
/// The MQC heads will be used by the validation function to authorize the input messages passed
|
||||||
|
/// by the collator.
|
||||||
hrmp_mqc_heads: Vec<(ParaId, Hash)>,
|
hrmp_mqc_heads: Vec<(ParaId, Hash)>,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -133,6 +139,8 @@ struct PersistedValidationData {
|
|||||||
|
|
||||||
These validation data are derived from some relay-chain state to check outputs of the validation function.
|
These validation data are derived from some relay-chain state to check outputs of the validation function.
|
||||||
|
|
||||||
|
It's worth noting that all the data is collected **before** the candidate execution.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
struct TransientValidationData {
|
struct TransientValidationData {
|
||||||
/// The maximum code size permitted, in bytes, of a produced validation code upgrade.
|
/// The maximum code size permitted, in bytes, of a produced validation code upgrade.
|
||||||
@@ -159,6 +167,53 @@ struct TransientValidationData {
|
|||||||
///
|
///
|
||||||
/// This informs a relay-chain backing check and the parachain logic.
|
/// This informs a relay-chain backing check and the parachain logic.
|
||||||
code_upgrade_allowed: Option<BlockNumber>,
|
code_upgrade_allowed: Option<BlockNumber>,
|
||||||
|
/// A copy of `config.max_upward_message_num_per_candidate` for checking that a candidate doesn't
|
||||||
|
/// send more messages that permitted.
|
||||||
|
config_max_upward_message_num_per_candidate: u32,
|
||||||
|
/// The number of messages pending of the downward message queue.
|
||||||
|
dmq_length: u32,
|
||||||
|
/// A part of transient validation data related to HRMP.
|
||||||
|
hrmp: HrmpTransientValidationData,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HrmpTransientValidationData {
|
||||||
|
/// A vector that enumerates the list of blocks in which there was at least one HRMP message
|
||||||
|
/// received.
|
||||||
|
///
|
||||||
|
/// The first number in the vector, if any, is always greater than the HRMP watermark. The
|
||||||
|
/// elements are ordered by ascending the block number. The vector doesn't contain duplicates.
|
||||||
|
digest: Vec<BlockNumber>,
|
||||||
|
/// The watermark of the HRMP. That is, the block number up to which (inclusive) all HRMP messages
|
||||||
|
/// sent to the parachain are processed.
|
||||||
|
watermark: BlockNumber,
|
||||||
|
/// A mapping that specifies if the parachain can send an HRMP message to the given recipient
|
||||||
|
/// channel. A candidate can send a message only to the recipients that are present in this
|
||||||
|
/// mapping. The number elements in this vector corresponds to the number of egress channels.
|
||||||
|
/// Since it's a mapping there can't be two items with same `ParaId`.
|
||||||
|
egress_limits: Vec<(ParaId, HrmpChannelLimits)>,
|
||||||
|
/// A vector of paras that have a channel to this para. The number of elements in this vector
|
||||||
|
/// correponds to the number of ingress channels. The items are ordered ascending by `ParaId`.
|
||||||
|
/// The vector doesn't contain two entries with the same `ParaId`.
|
||||||
|
ingress_senders: Vec<ParaId>,
|
||||||
|
/// A vector of open requests in which the para participates either as sender or recipient. The
|
||||||
|
/// items are ordered ascending by `HrmpChannelId`. The vector doesn't contain two entries
|
||||||
|
/// with the same `HrmpChannelId`.
|
||||||
|
open_requests: Vec<(HrmpChannelId, HrmpAbridgedOpenChannelRequest)>,
|
||||||
|
/// A vector of close requests in which the para participates either as sender or recipient.
|
||||||
|
/// The vector doesn't contain two entries with the same `HrmpChannelId`.
|
||||||
|
close_requests: Vec<HrmpChannelId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A shorter version of `HrmpOpenChannelRequest`.
|
||||||
|
struct HrmpAbridgedOpenChannelRequest {
|
||||||
|
confirmed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HrmpChannelLimits {
|
||||||
|
/// Indicates if the channel is already full and cannot accept any more messages.
|
||||||
|
is_full: bool,
|
||||||
|
/// A message sent to the channel can occupy only that many bytes.
|
||||||
|
available_size: u32,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ that we use the first item tuple for the sender and the second for the recipient
|
|||||||
is allowed between two participants in one direction, i.e. there cannot be 2 different channels
|
is allowed between two participants in one direction, i.e. there cannot be 2 different channels
|
||||||
identified by `(A, B)`.
|
identified by `(A, B)`.
|
||||||
|
|
||||||
|
`HrmpChannelId` has a defined ordering: first `sender` and tie is resolved by `recipient`.
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
struct HrmpChannelId {
|
struct HrmpChannelId {
|
||||||
sender: ParaId,
|
sender: ParaId,
|
||||||
|
|||||||
Reference in New Issue
Block a user