This repository has been archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Implementer's Guide: Make HRMP use upward message kinds #1591
Merged
Merged
Changes from 7 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
247dc64
Draft HRMP related message types
pepyakin f30e983
Make HRMP use upward message kinds
pepyakin ee7393c
Incorporate changes into messaging.md
pepyakin 5c13530
Make docs a bit more clear
pepyakin f7c36ed
Clarify remove "D"
pepyakin 187d6c2
Update roadmap/implementers-guide/src/messaging.md
pepyakin 7b0f48c
Update roadmap/implementers-guide/src/runtime/router.md
pepyakin a697b80
Update router.md
pepyakin 216acba
Update roadmap/implementers-guide/src/runtime/router.md
pepyakin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,10 +40,6 @@ struct HrmpChannelId { | |
|
||
/// 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. | ||
|
@@ -56,19 +52,6 @@ struct HrmpOpenChannelRequest { | |
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. | ||
|
@@ -98,14 +81,30 @@ struct HrmpChannel { | |
HRMP related storage layout | ||
|
||
```rust,ignore | ||
/// Pending HRMP open channel requests. | ||
HrmpOpenChannelRequests: Vec<HrmpOpenChannelRequest>; | ||
/// The set of pending HRMP open channel requests. | ||
/// | ||
/// The set is accompanied by a list for iteration. | ||
/// | ||
/// Invariant: | ||
/// - There are no channels that exists in list but not in the set and vice versa. | ||
HrmpOpenChannelRequests: map HrmpChannelId => Option<HrmpOpenChannelRequest>; | ||
HrmpOpenChannelRequestsList: Vec<HrmpChannelId>; | ||
|
||
/// 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` | ||
/// Invariant: `HrmpOpenChannelRequestsList` should contain the same number of items that has `(X, _)` | ||
/// as the number of `HrmpOpenChannelRequestCount` for `X`. | ||
HrmpOpenChannelRequestCount: map ParaId => u32; | ||
/// Pending HRMP close channel requests. | ||
HrmpCloseChannelRequests: Vec<HrmpCloseChannelRequest>; | ||
|
||
/// A set of pending HRMP close channel requests that are going to be closed during the session change. | ||
/// Used for checking if a given channel is registered for closure. | ||
/// | ||
/// The set is accompanied by a list for iteration. | ||
/// | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 explicitness |
||
/// Invariant: | ||
/// - There are no channels that exists in list but not in the set and vice versa. | ||
HrmpCloseChannelRequests: map HrmpChannelId => Option<()>; | ||
HrmpCloseChannelRequestsList: Vec<HrmpChannelId>; | ||
|
||
/// The HRMP watermark associated with each para. | ||
HrmpWatermarks: map ParaId => Option<BlockNumber>; | ||
/// HRMP channel data associated with each para. | ||
|
@@ -129,44 +128,32 @@ HrmpChannelDigests: map ParaId => Vec<(BlockNumber, Vec<ParaId>)>; | |
|
||
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_upward_messages(P: ParaId, Vec<UpwardMessage>`: | ||
1. Checks that there are at most `config.max_upward_message_num_per_candidate` messages. | ||
1. Checks each upward message individually depending on its kind: | ||
1. Checks each upward message `M` individually depending on its kind: | ||
1. If the message kind is `Dispatchable`: | ||
1. Verify that `RelayDispatchQueueSize` for `P` has enough capacity for the message (NOTE that should include all processed | ||
upward messages of the `Dispatchable` kind up to this point!) | ||
1. If the message kind is `HrmpInitOpenChannel(recipient)`: | ||
1. Check that the `P` is not `recipient`. | ||
1. Check that `recipient` is a valid para. | ||
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 | ||
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. Check that `P`'s balance is more or equal to `config.hrmp_sender_deposit` | ||
1. If the message kind is `HrmpAcceptOpenChannel(sender)`: | ||
1. Check that there is exsting request between (`sender`, `P`) in `HrmpOpenChannelRequests` | ||
pepyakin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
1. Check that `P`'s balance is more or equal to `config.hrmp_recipient_deposit`. | ||
1. If the message kind is `HrmpCloseChannel(ch)`: | ||
1. Check that `P` is either `ch.sender` or `ch.recipient` | ||
1. Check that `HrmpChannels` for `ch` exists. | ||
1. Check that `ch` is not in the `HrmpCloseChannelRequests` set. | ||
* `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. | ||
|
@@ -205,6 +192,20 @@ Candidate Enactment: | |
1. Append the message to `RelayDispatchQueues` for `P` | ||
1. Increment the size and the count in `RelayDispatchQueueSize` for `P`. | ||
1. Ensure that `P` is present in `NeedsDispatch`. | ||
1. If the message kind is `HrmpInitOpenChannel(recipient)`: | ||
1. Increase `HrmpOpenChannelRequestCount` by 1 for the `P`. | ||
1. Append `(P, recipient)` to `HrmpOpenChannelRequestsList`. | ||
1. Add a new entry to `HrmpOpenChannelRequests` for `(sender, recipient)` | ||
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` | ||
1. Reserve the deposit for the `P` according to `config.hrmp_sender_deposit` | ||
1. If the message kind is `HrmpAcceptOpenChannel(sender)`: | ||
1. Reserve the deposit for the `P` according to `config.hrmp_recipient_deposit` | ||
1. For the request in `HrmpOpenChannelRequests` identified by `(sender, P)`, set `confirmed` flag to `true`. | ||
1. If the message kind is `HrmpCloseChannel(ch)`: | ||
1. Insert a new entry `Some(())` to `HrmpCloseChannelRequests` for `ch`. | ||
1. Append `ch` to `HrmpCloseChannelRequestsList`. | ||
|
||
The following routine is intended to be called in the same time when `Paras::schedule_para_cleanup` is called. | ||
|
||
|
@@ -242,23 +243,29 @@ any of dispatchables return an error. | |
1. Remove `RelayDispatchQueues` of `P`. | ||
1. Remove `P` if it exists in `NeedsDispatch`. | ||
1. If `P` is in `NextDispatchRoundStartWith`, then reset it to `None` | ||
- Note that we don't remove the open/close requests since they are gon die out naturally. | ||
1. For each request `R` in `HrmpOpenChannelRequests`: | ||
- Note that if we don't remove the open/close requests since they are goning die out naturally at the end of the session. | ||
pepyakin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
1. For each channel designator `D` in `HrmpOpenChannelRequestsList` we query the request `R` from `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. decrement `HrmpOpenChannelRequestCount` for `D.sender` by 1. | ||
1. remove `R` | ||
1. remove `D` | ||
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. if both `D.sender` and `D.recipient` are not offboarded. | ||
1. create a new channel `C` between `(D.sender, D.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 `D.sender` by 1. | ||
1. remove `R` | ||
1. For each request `R` in `HrmpCloseChannelRequests` remove the channel identified by `R.id`, if exists. | ||
1. remove `D` | ||
1. For each channel designator `D` in `HrmpCloseChannelRequestsList` | ||
1. remove the channel identified by `D`, if exists. | ||
1. remove `D` from `HrmpCloseChannelRequests`. | ||
1. remove `D` from `HrmpCloseChannelRequestsList` | ||
|
||
To remove a channel `C` identified with a tuple `(sender, recipient)`: | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
frame
maps support iteration already, i believe.