some fixes to please cargo-spellcheck (#3550)

* some fixes to please cargo-spellcheck

* some (not all) fixes for the impl guide

* fix
This commit is contained in:
Andronik Ordian
2021-08-02 13:00:04 +02:00
committed by GitHub
parent 2cfda98aca
commit 33fe763188
24 changed files with 160 additions and 143 deletions
+2 -2
View File
@@ -271,7 +271,7 @@ impl IsSystem for Sibling {
} }
} }
/// This type can be converted into and possibly from an AccountId (which itself is generic). /// This type can be converted into and possibly from an [`AccountId`] (which itself is generic).
pub trait AccountIdConversion<AccountId>: Sized { pub trait AccountIdConversion<AccountId>: Sized {
/// Convert into an account ID. This is infallible. /// Convert into an account ID. This is infallible.
fn into_account(&self) -> AccountId; fn into_account(&self) -> AccountId;
@@ -300,7 +300,7 @@ impl<'a> parity_scale_codec::Input for TrailingZeroInput<'a> {
} }
/// Format is b"para" ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing /// Format is b"para" ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing
/// zeroes to fill AccountId. /// zeroes to fill [`AccountId`].
impl<T: Encode + Decode + Default> AccountIdConversion<T> for Id { impl<T: Encode + Decode + Default> AccountIdConversion<T> for Id {
fn into_account(&self) -> T { fn into_account(&self) -> T {
(b"para", self) (b"para", self)
@@ -1,6 +1,7 @@
# The Polkadot Parachain Host Implementers' Guide # The Polkadot Parachain Host Implementers' Guide
The implementers' guide is compiled from several source files with [mdBook](https://github.com/rust-lang/mdBook). To view it live, locally, from the repo root: The implementers' guide is compiled from several source files with [`mdBook`](https://github.com/rust-lang/mdBook).
To view it live, locally, from the repo root:
```sh ```sh
cargo install mdbook mdbook-linkcheck mdbook-graphviz cargo install mdbook mdbook-linkcheck mdbook-graphviz
@@ -11,18 +11,18 @@
- [Architecture Overview](architecture.md) - [Architecture Overview](architecture.md)
- [Messaging Overview](messaging.md) - [Messaging Overview](messaging.md)
- [Runtime Architecture](runtime/README.md) - [Runtime Architecture](runtime/README.md)
- [Initializer Module](runtime/initializer.md) - [`Initializer` Module](runtime/initializer.md)
- [Configuration Module](runtime/configuration.md) - [`Configuration` Module](runtime/configuration.md)
- [Shared](runtime/shared.md) - [`Shared`](runtime/shared.md)
- [Disputes Module](runtime/disputes.md) - [`Disputes` Module](runtime/disputes.md)
- [Paras Module](runtime/paras.md) - [`Paras` Module](runtime/paras.md)
- [Scheduler Module](runtime/scheduler.md) - [`Scheduler` Module](runtime/scheduler.md)
- [Inclusion Module](runtime/inclusion.md) - [`Inclusion` Module](runtime/inclusion.md)
- [ParaInherent Module](runtime/parainherent.md) - [`ParaInherent` Module](runtime/parainherent.md)
- [DMP Module](runtime/dmp.md) - [`DMP` Module](runtime/dmp.md)
- [UMP Module](runtime/ump.md) - [`UMP` Module](runtime/ump.md)
- [HRMP Module](runtime/hrmp.md) - [`HRMP` Module](runtime/hrmp.md)
- [Session Info Module](runtime/session_info.md) - [`Session Info` Module](runtime/session_info.md)
- [Runtime APIs](runtime-api/README.md) - [Runtime APIs](runtime-api/README.md)
- [Validators](runtime-api/validators.md) - [Validators](runtime-api/validators.md)
- [Validator Groups](runtime-api/validator-groups.md) - [Validator Groups](runtime-api/validator-groups.md)
@@ -82,7 +82,7 @@ Only peers that already voted shall be queried for the dispute availability data
The peer to be queried for disputes data, must be picked at random. The peer to be queried for disputes data, must be picked at random.
A validator must retain code, persisted validation data and PoV until a block, that contains the dispute resolution, is finalized - plus an additional 24h. A validator must retain code, persisted validation data and PoV until a block, that contains the dispute resolution, is finalized - plus an additional 24 hours.
Dispute availability gossip must continue beyond the dispute resolution, until the post resolution timeout expired (equiv to the timeout until which additional late votes are accepted). Dispute availability gossip must continue beyond the dispute resolution, until the post resolution timeout expired (equiv to the timeout until which additional late votes are accepted).
@@ -108,7 +108,7 @@ If the count of votes pro or cons regarding the disputed block, reaches the requ
If a block is found invalid by a dispute resolution, it must be blacklisted to avoid resync or further build on that chain if other chains are available (to be detailed in the grandpa fork choice rule). If a block is found invalid by a dispute resolution, it must be blacklisted to avoid resync or further build on that chain if other chains are available (to be detailed in the grandpa fork choice rule).
A dispute accepts Votes after the dispute is resolved, for 1d. A dispute accepts Votes after the dispute is resolved, for 1 day.
If a vote is received, after the dispute is resolved, the vote shall still be recorded in the state root, albeit yielding less reward. If a vote is received, after the dispute is resolved, the vote shall still be recorded in the state root, albeit yielding less reward.
@@ -131,7 +131,7 @@ Ensure a vector is present in `pending_known` for each hash in the view that doe
Invoke `unify_with_peer(peer, view)` to catch them up to messages we have. Invoke `unify_with_peer(peer, view)` to catch them up to messages we have.
We also need to use the `view.finalized_number` to remove the `PeerId` from any blocks that it won't be wanting information about anymore. Note that we have to be on guard for peers doing crazy stuff like jumping their 'finalized_number` forward 10 trillion blocks to try and get us stuck in a loop for ages. We also need to use the `view.finalized_number` to remove the `PeerId` from any blocks that it won't be wanting information about anymore. Note that we have to be on guard for peers doing crazy stuff like jumping their `finalized_number` forward 10 trillion blocks to try and get us stuck in a loop for ages.
One of the safeguards we can implement is to reject view updates from peers where the new `finalized_number` is less than the previous. One of the safeguards we can implement is to reject view updates from peers where the new `finalized_number` is less than the previous.
@@ -192,7 +192,7 @@ We maintain a few invariants:
The algorithm is the following: The algorithm is the following:
* Load the BlockEntry using `assignment.block_hash`. If it does not exist, report the source if it is `MessageSource::Peer` and return. * Load the `BlockEntry` using `assignment.block_hash`. If it does not exist, report the source if it is `MessageSource::Peer` and return.
* Compute a fingerprint for the `assignment` using `claimed_candidate_index`. * Compute a fingerprint for the `assignment` using `claimed_candidate_index`.
* If the source is `MessageSource::Peer(sender)`: * If the source is `MessageSource::Peer(sender)`:
* check if `peer` appears under `known_by` and whether the fingerprint is in the knowledge of the peer. If the peer does not know the block, report for providing data out-of-view and proceed. If the peer does know the block and the `sent` knowledge contains the fingerprint, report for providing replicate data and return, otherwise, insert into the `received` knowledge and return. * check if `peer` appears under `known_by` and whether the fingerprint is in the knowledge of the peer. If the peer does not know the block, report for providing data out-of-view and proceed. If the peer does know the block and the `sent` knowledge contains the fingerprint, report for providing replicate data and return, otherwise, insert into the `received` knowledge and return.
@@ -218,7 +218,7 @@ The algorithm is the following:
Imports an approval signature referenced by block hash and candidate index: Imports an approval signature referenced by block hash and candidate index:
* Load the BlockEntry using `approval.block_hash` and the candidate entry using `approval.candidate_entry`. If either does not exist, report the source if it is `MessageSource::Peer` and return. * Load the `BlockEntry` using `approval.block_hash` and the candidate entry using `approval.candidate_entry`. If either does not exist, report the source if it is `MessageSource::Peer` and return.
* Compute a fingerprint for the approval. * Compute a fingerprint for the approval.
* Compute a fingerprint for the corresponding assignment. If the `BlockEntry`'s knowledge does not contain that fingerprint, then report the source if it is `MessageSource::Peer` and return. All references to a fingerprint after this refer to the approval's, not the assignment's. * Compute a fingerprint for the corresponding assignment. If the `BlockEntry`'s knowledge does not contain that fingerprint, then report the source if it is `MessageSource::Peer` and return. All references to a fingerprint after this refer to the approval's, not the assignment's.
* If the source is `MessageSource::Peer(sender)`: * If the source is `MessageSource::Peer(sender)`:
@@ -13,8 +13,8 @@ In particular this subsystem is responsible for:
this is to ensure availability by at least 2/3+ of all validators, this this is to ensure availability by at least 2/3+ of all validators, this
happens after a candidate is backed. happens after a candidate is backed.
- Fetch `PoV` from validators, when requested via `FetchPoV` message from - Fetch `PoV` from validators, when requested via `FetchPoV` message from
backing (pov_requester module). backing (`pov_requester` module).
-
The backing subsystem is responsible of making available data available in the The backing subsystem is responsible of making available data available in the
local `Availability Store` upon validation. This subsystem will serve any local `Availability Store` upon validation. This subsystem will serve any
network requests by querying that store. network requests by querying that store.
@@ -22,27 +22,27 @@ network requests by querying that store.
## Protocol ## Protocol
This subsystem does not handle any peer set messages, but the `pov_requester` This subsystem does not handle any peer set messages, but the `pov_requester`
does connecto to validators of the same backing group on the validation peer does connect to validators of the same backing group on the validation peer
set, to ensure fast propagation of statements between those validators and for set, to ensure fast propagation of statements between those validators and for
ensuring already established connections for requesting `PoV`s. Other than that ensuring already established connections for requesting `PoV`s. Other than that
this subsystem drives request/response protocols. this subsystem drives request/response protocols.
Input: Input:
- OverseerSignal::ActiveLeaves(`[ActiveLeavesUpdate]`) - `OverseerSignal::ActiveLeaves(ActiveLeavesUpdate)`
- AvailabilityDistributionMessage{msg: ChunkFetchingRequest} - `AvailabilityDistributionMessage{msg: ChunkFetchingRequest}`
- AvailabilityDistributionMessage{msg: PoVFetchingRequest} - `AvailabilityDistributionMessage{msg: PoVFetchingRequest}`
- AvailabilityDistributionMessage{msg: FetchPoV} - `AvailabilityDistributionMessage{msg: FetchPoV}`
Output: Output:
- NetworkBridgeMessage::SendRequests(`[Requests]`, IfDisconnected::TryConnect) - `NetworkBridgeMessage::SendRequests(Requests, IfDisconnected::TryConnect)`
- AvailabilityStore::QueryChunk(candidate_hash, index, response_channel) - `AvailabilityStore::QueryChunk(candidate_hash, index, response_channel)`
- AvailabilityStore::StoreChunk(candidate_hash, chunk) - `AvailabilityStore::StoreChunk(candidate_hash, chunk)`
- AvailabilityStore::QueryAvailableData(candidate_hash, response_channel) - `AvailabilityStore::QueryAvailableData(candidate_hash, response_channel)`
- RuntimeApiRequest::SessionIndexForChild - `RuntimeApiRequest::SessionIndexForChild`
- RuntimeApiRequest::SessionInfo - `RuntimeApiRequest::SessionInfo`
- RuntimeApiRequest::AvailabilityCores - `RuntimeApiRequest::AvailabilityCores`
## Functionality ## Functionality
@@ -10,14 +10,14 @@ This version of the availability recovery subsystem is based off of direct conne
Input: Input:
- NetworkBridgeUpdateV1(update) - `NetworkBridgeUpdateV1(update)`
- AvailabilityRecoveryMessage::RecoverAvailableData(candidate, session, backing_group, response) - `AvailabilityRecoveryMessage::RecoverAvailableData(candidate, session, backing_group, response)`
Output: Output:
- NetworkBridge::SendValidationMessage - `NetworkBridge::SendValidationMessage`
- NetworkBridge::ReportPeer - `NetworkBridge::ReportPeer`
- AvailabilityStore::QueryChunk - `AvailabilityStore::QueryChunk`
## Functionality ## Functionality
@@ -90,7 +90,7 @@ On `Conclude`, shut down the subsystem.
1. Check the `availability_lru` for the candidate and return the data if so. 1. Check the `availability_lru` for the candidate and return the data if so.
1. Check if there is already an interaction handle for the request. If so, add the response handle to it. 1. Check if there is already an interaction handle for the request. If so, add the response handle to it.
1. Otherwise, load the session info for the given session under the state of `live_block_hash`, and initiate an interaction with *launch_interaction*. Add an interaction handle to the state and add the response channel to it. 1. Otherwise, load the session info for the given session under the state of `live_block_hash`, and initiate an interaction with *`launch_interaction`*. Add an interaction handle to the state and add the response channel to it.
1. If the session info is not available, return `RecoveryError::Unavailable` on the response channel. 1. If the session info is not available, return `RecoveryError::Unavailable` on the response channel.
### From-interaction logic ### From-interaction logic
@@ -98,7 +98,7 @@ On `Conclude`, shut down the subsystem.
#### `FromInteraction::Concluded` #### `FromInteraction::Concluded`
1. Load the entry from the `interactions` map. It should always exist, if not for logic errors. Send the result to each member of `awaiting`. 1. Load the entry from the `interactions` map. It should always exist, if not for logic errors. Send the result to each member of `awaiting`.
1. Add the entry to the availability_lru. 1. Add the entry to the `availability_lru`.
### Interaction logic ### Interaction logic
@@ -10,8 +10,8 @@ There is no dedicated input mechanism for bitfield signing. Instead, Bitfield Si
Output: Output:
- BitfieldDistribution::DistributeBitfield: distribute a locally signed bitfield - `BitfieldDistribution::DistributeBitfield`: distribute a locally signed bitfield
- AvailabilityStore::QueryChunk(CandidateHash, validator_index, response_channel) - `AvailabilityStore::QueryChunk(CandidateHash, validator_index, response_channel)`
## Functionality ## Functionality
@@ -114,7 +114,7 @@ fn spawn_validation_work(candidate, parachain head, validation function) {
} }
``` ```
### Fetch Pov Block ### Fetch PoV Block
Create a `(sender, receiver)` pair. Create a `(sender, receiver)` pair.
Dispatch a [`AvailabilityDistributionMessage`][ADM]`::FetchPoV{ validator_index, pov_hash, candidate_hash, tx, } and listen on the passed receiver for a response. Availability distribution will send the request to the validator specified by `validator_index`, which might not be serving it for whatever reasons, therefore we need to retry with other backing validators in that case. Dispatch a [`AvailabilityDistributionMessage`][ADM]`::FetchPoV{ validator_index, pov_hash, candidate_hash, tx, } and listen on the passed receiver for a response. Availability distribution will send the request to the validator specified by `validator_index`, which might not be serving it for whatever reasons, therefore we need to retry with other backing validators in that case.
@@ -8,20 +8,20 @@ The Statement Distribution Subsystem is responsible for distributing statements
Input: Input:
- NetworkBridgeUpdate(update) - `NetworkBridgeUpdate(update)`
- StatementDistributionMessage - `StatementDistributionMessage`
Output: Output:
- NetworkBridge::SendMessage(`[PeerId]`, message) - `NetworkBridge::SendMessage(PeerId, message)`
- NetworkBridge::SendRequests (StatementFetching) - `NetworkBridge::SendRequests(StatementFetching)`
- NetworkBridge::ReportPeer(PeerId, cost_or_benefit) - `NetworkBridge::ReportPeer(PeerId, cost_or_benefit)`
## Functionality ## Functionality
Implemented as a gossip protocol. Handle updates to our view and peers' views. Neighbor packets are used to inform peers which chain heads we are interested in data for. Implemented as a gossip protocol. Handle updates to our view and peers' views. Neighbor packets are used to inform peers which chain heads we are interested in data for.
It is responsible for distributing signed statements that we have generated and forwarding them, and for detecting a variety of Validator misbehaviors for reporting to [Misbehavior Arbitration](../utility/misbehavior-arbitration.md). During the Backing stage of the inclusion pipeline, it's the main point of contact with peer nodes. On receiving a signed statement from a peer in the same backing group, assuming the peer receipt state machine is in an appropriate state, it sends the Candidate Receipt to the [Candidate Backing subsystem](candidate-backing.md) to handle the validator's statement. On receiving `StatementDistributionMessage::Share` we make sure to send messages to our backing group in addition to random other peers, to ensure a fast backing process and getting all statements quickly for distribtution. It is responsible for distributing signed statements that we have generated and forwarding them, and for detecting a variety of Validator misbehaviors for reporting to [Misbehavior Arbitration](../utility/misbehavior-arbitration.md). During the Backing stage of the inclusion pipeline, it's the main point of contact with peer nodes. On receiving a signed statement from a peer in the same backing group, assuming the peer receipt state machine is in an appropriate state, it sends the Candidate Receipt to the [Candidate Backing subsystem](candidate-backing.md) to handle the validator's statement. On receiving `StatementDistributionMessage::Share` we make sure to send messages to our backing group in addition to random other peers, to ensure a fast backing process and getting all statements quickly for distribution.
Track equivocating validators and stop accepting information from them. Establish a data-dependency order: Track equivocating validators and stop accepting information from them. Establish a data-dependency order:
@@ -71,7 +71,7 @@ The simple approach is to say that we only receive up to two `Seconded` statemen
With that in mind, this simple approach has a caveat worth digging deeper into. With that in mind, this simple approach has a caveat worth digging deeper into.
First: We may be aware of two equivocated `Seconded` statements issued by a validator. A totally honest peer of ours can also be aware of one or two different `Seconded` statements issued by the same validator. And yet another peer may be aware of one or two _more_ `Seconded` statements. And so on. This interacts badly with pre-emptive sending logic. Upon sending a `Seconded` statement to a peer, we will want to pre-emptively follow up with all statements relative to that candidate. Waiting for acknowledgement introduces latency at every hop, so that is best avoided. What can happen is that upon receipt of the `Seconded` statement, the peer will discard it as it falls beyond the bound of 2 that it is allowed to store. It cannot store anything in memory about discarded candidates as that would introduce a DoS vector. Then, the peer would receive from us all of the statements pertaining to that candidate, which, from its perspective, would be undesired - they are data-dependent on the `Seconded` statement we sent them, but they have erased all record of that from their memory. Upon receiving a potential flood of undesired statements, this 100% honest peer may choose to disconnect from us. In this way, an adversary may be able to partition the network with careful distribution of equivocated `Seconded` statements. First: We may be aware of two equivocated `Seconded` statements issued by a validator. A totally honest peer of ours can also be aware of one or two different `Seconded` statements issued by the same validator. And yet another peer may be aware of one or two _more_ `Seconded` statements. And so on. This interacts badly with pre-emptive sending logic. Upon sending a `Seconded` statement to a peer, we will want to pre-emptively follow up with all statements relative to that candidate. Waiting for acknowledgment introduces latency at every hop, so that is best avoided. What can happen is that upon receipt of the `Seconded` statement, the peer will discard it as it falls beyond the bound of 2 that it is allowed to store. It cannot store anything in memory about discarded candidates as that would introduce a DoS vector. Then, the peer would receive from us all of the statements pertaining to that candidate, which, from its perspective, would be undesired - they are data-dependent on the `Seconded` statement we sent them, but they have erased all record of that from their memory. Upon receiving a potential flood of undesired statements, this 100% honest peer may choose to disconnect from us. In this way, an adversary may be able to partition the network with careful distribution of equivocated `Seconded` statements.
The fix is to track, per-peer, the hashes of up to 4 candidates per validator (per relay-parent) that the peer is aware of. It is 4 because we may send them 2 and they may send us 2 different ones. We track the data that they are aware of as the union of things we have sent them and things they have sent us. If we receive a 1st or 2nd `Seconded` statement from a peer, we note it in the peer's known candidates even if we do disregard the data locally. And then, upon receipt of any data dependent on that statement, we do not reduce that peer's standing in our eyes, as the data was not undesired. The fix is to track, per-peer, the hashes of up to 4 candidates per validator (per relay-parent) that the peer is aware of. It is 4 because we may send them 2 and they may send us 2 different ones. We track the data that they are aware of as the union of things we have sent them and things they have sent us. If we receive a 1st or 2nd `Seconded` statement from a peer, we note it in the peer's known candidates even if we do disregard the data locally. And then, upon receipt of any data dependent on that statement, we do not reduce that peer's standing in our eyes, as the data was not undesired.
@@ -120,9 +120,9 @@ Subsequently, once a valid parablock candidate has been seconded, the [`Candidat
Several approaches have been discussed, but all have some issues: Several approaches have been discussed, but all have some issues:
- The current approach is very straightforward. However, that protocol is vulnerable to a single collator which, as an attack or simply through chance, gets its block candidate to the node more often than its fair share of the time. - The current approach is very straightforward. However, that protocol is vulnerable to a single collator which, as an attack or simply through chance, gets its block candidate to the node more often than its fair share of the time.
- If collators produce blocks via Aura, BABE or in future Sassafrass, it may be possible to choose an "Official" collator for the round, but it may be tricky to ensure that the PVF logic is enforced at collator leader election. - If collators produce blocks via Aura, BABE or in future Sassafras, it may be possible to choose an "Official" collator for the round, but it may be tricky to ensure that the PVF logic is enforced at collator leader election.
- We could use relay-chain BABE randomness to generate some delay `D` on the order of 1 second, +- 1 second. The collator would then second the first valid parablock which arrives after `D`, or in case none has arrived by `2*D`, the last valid parablock which has arrived. This makes it very hard for a collator to game the system to always get its block nominated, but it reduces the maximum throughput of the system by introducing delay into an already tight schedule. - We could use relay-chain BABE randomness to generate some delay `D` on the order of 1 second, +- 1 second. The collator would then second the first valid parablock which arrives after `D`, or in case none has arrived by `2*D`, the last valid parablock which has arrived. This makes it very hard for a collator to game the system to always get its block nominated, but it reduces the maximum throughput of the system by introducing delay into an already tight schedule.
- A variation of that scheme would be to have a fixed acceptance window `D` for parablock candidates and keep track of count `C`: the number of parablock candidates received. At the end of the period `D`, we choose a random number I in the range [0, C) and second the block at Index I. Its drawback is the same: it must wait the full `D` period before seconding any of its received candidates, reducing throughput. - A variation of that scheme would be to have a fixed acceptance window `D` for parablock candidates and keep track of count `C`: the number of parablock candidates received. At the end of the period `D`, we choose a random number I in the range `[0, C)` and second the block at Index I. Its drawback is the same: it must wait the full `D` period before seconding any of its received candidates, reducing throughput.
- In order to protect against DoS attacks, it may be prudent to run throw out collations from collators that have behaved poorly (whether recently or historically) and subsequently only verify the PoV for the most suitable of collations. - In order to protect against DoS attacks, it may be prudent to run throw out collations from collators that have behaved poorly (whether recently or historically) and subsequently only verify the PoV for the most suitable of collations.
[CB]: ../backing/candidate-backing.md [CB]: ../backing/candidate-backing.md
@@ -4,8 +4,8 @@ This section is for the node-side subsystems that lead to participation in dispu
* Detection. Detect bad parablocks, either during candidate backing or approval checking, and initiate a dispute. * Detection. Detect bad parablocks, either during candidate backing or approval checking, and initiate a dispute.
* Participation. Participate in active disputes. When a node becomes aware of a dispute, it should recover the data for the disputed block, check the validity of the parablock, and issue a statement regarding the validity of the parablock. * Participation. Participate in active disputes. When a node becomes aware of a dispute, it should recover the data for the disputed block, check the validity of the parablock, and issue a statement regarding the validity of the parablock.
* Distribution. Validators should notify each other of active disputes and relevant statements over the network. * Distribution. Validators should notify each other of active disputes and relevant statements over the network.
* Submission. When authoring a block, a validator should inspect the state of the parent block and provide any information about disputes that the chain needs as part of the ParaInherent. This should initialize new disputes on-chain as necessary. * Submission. When authoring a block, a validator should inspect the state of the parent block and provide any information about disputes that the chain needs as part of the `ParaInherent`. This should initialize new disputes on-chain as necessary.
* Fork-choice and Finality. When observing a block issuing a DisputeRollback digest in the header, that branch of the relay chain should be abandoned all the way back to the indicated block. When voting on chains in GRANDPA, no chains that contain blocks that are or have been disputed should be voted on. * Fork-choice and Finality. When observing a block issuing a `DisputeRollback` digest in the header, that branch of the relay chain should be abandoned all the way back to the indicated block. When voting on chains in GRANDPA, no chains that contain blocks that are or have been disputed should be voted on.
## Components ## Components
@@ -17,15 +17,15 @@ This component should track all statements received from all validators over som
This is responsible for tracking and initiating disputes. Disputes will be initiated either externally by another subsystem which has identified an issue with a parablock or internally upon observing two statements which conflict with each other on the validity of a parablock. This is responsible for tracking and initiating disputes. Disputes will be initiated either externally by another subsystem which has identified an issue with a parablock or internally upon observing two statements which conflict with each other on the validity of a parablock.
No more than one statement by each validator on each side of the dispute needs to be stored. That is, validators are allowed to participate on both sides of the dispute, although we won't write code to do so. Such behavior has negative EV in the runtime. No more than one statement by each validator on each side of the dispute needs to be stored. That is, validators are allowed to participate on both sides of the dispute, although we won't write code to do so. Such behavior has negative extractable value in the runtime.
This will notify the dispute participation subsystem of a new dispute if the local validator has not issued any statements on the disputed candidate already. This will notify the dispute participation subsystem of a new dispute if the local validator has not issued any statements on the disputed candidate already.
Locally authored statements related to disputes will be forwarded to the dispute distribution subsystem. Locally authored statements related to disputes will be forwarded to the dispute distribution subsystem.
This subsystem also provides two further behaviors for the interactions between disputes and fork-choice This subsystem also provides two further behaviors for the interactions between disputes and fork-choice
- Enhancing the finality voting rule. Given description of a chain and candidates included at different heights in that chain, it returns the BlockHash corresponding to the highest BlockNumber that there are no disputes before. I expect that we will slightly change ApprovalVoting::ApprovedAncestor to return this set and then the target block to vote on will be further constrained by this function. - Enhancing the finality voting rule. Given description of a chain and candidates included at different heights in that chain, it returns the `BlockHash` corresponding to the highest `BlockNumber` that there are no disputes before. I expect that we will slightly change `ApprovalVoting::ApprovedAncestor` to return this set and then the target block to vote on will be further constrained by this function.
- Chain roll-backs. Whenever importing new blocks, the header should be scanned for a roll-back digest. If there is one, the chain should be rolled back according to the digest. I expect this would be implemented with a ChainApi function and possibly an ApprovalVoting function to clean up the approval voting DB. - Chain roll-backs. Whenever importing new blocks, the header should be scanned for a roll-back digest. If there is one, the chain should be rolled back according to the digest. I expect this would be implemented with a `ChainApi` function and possibly an `ApprovalVoting` function to clean up the approval voting DB.
### Dispute Participation ### Dispute Participation
@@ -30,7 +30,7 @@ This design should result in a protocol that is:
#### Disputes #### Disputes
Protocol: "/polkadot/send\_dispute/1" Protocol: `"/polkadot/send_dispute/1"`
Request: Request:
@@ -86,7 +86,7 @@ enum DisputeResponse {
#### Vote Recovery #### Vote Recovery
Protocol: "/polkadot/req\_votes/1" Protocol: `"/polkadot/req_votes/1"`
```rust ```rust
struct IHaveVotesRequest { struct IHaveVotesRequest {
@@ -246,7 +246,7 @@ even if they did:
So this general rate limit, that we drop requests from same peers if they come So this general rate limit, that we drop requests from same peers if they come
faster than we can import the statements should not cause any problems for faster than we can import the statements should not cause any problems for
honest nodes and is in their favour. honest nodes and is in their favor.
Size of `N`: The larger `N` the better we can handle distributed flood attacks Size of `N`: The larger `N` the better we can handle distributed flood attacks
(see previous paragraph), but we also get potentially more availability recovery (see previous paragraph), but we also get potentially more availability recovery
@@ -6,14 +6,14 @@ Fortunately, most of that work is handled by other subsystems; this subsystem is
## Protocol ## Protocol
Input: [DisputeParticipationMessage][DisputeParticipationMessage] Input: [`DisputeParticipationMessage`][DisputeParticipationMessage]
Output: Output:
- [RuntimeApiMessage][RuntimeApiMessage] - [`RuntimeApiMessage`][RuntimeApiMessage]
- [CandidateValidationMessage][CandidateValidationMessage] - [`CandidateValidationMessage`][CandidateValidationMessage]
- [AvailabilityRecoveryMessage][AvailabilityRecoveryMessage] - [`AvailabilityRecoveryMessage`][AvailabilityRecoveryMessage]
- [AvailabilityStoreMessage][AvailabilityStoreMessage] - [`AvailabilityStoreMessage`][AvailabilityStoreMessage]
- [ChainApiMessage][ChainApiMessage] - [`ChainApiMessage`][ChainApiMessage]
## Functionality ## Functionality
@@ -57,7 +57,7 @@ Conclude.
This requires the parameters `{ candidate_receipt, candidate_hash, session, voted_indices }` as well as a choice of either `Valid` or `Invalid`. This requires the parameters `{ candidate_receipt, candidate_hash, session, voted_indices }` as well as a choice of either `Valid` or `Invalid`.
Invoke [`DisputeCoordinatorMessage::IssueLocalStatement`][DisputeCoordinatorMessage] with `is_valid` according to the parametrization. Invoke [`DisputeCoordinatorMessage::IssueLocalStatement`][DisputeCoordinatorMessage] with `is_valid` according to the parameterization,.
[RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message [RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message
[DisputeParticipationMessage]: ../../types/overseer-protocol.md#dispute-participation-message [DisputeParticipationMessage]: ../../types/overseer-protocol.md#dispute-participation-message
@@ -80,7 +80,7 @@ When a subsystem wants to communicate with another subsystem, or, more typically
First, the subsystem that spawned a job is responsible for handling the first step of the communication. The overseer is not aware of the hierarchy of tasks within any given subsystem and is only responsible for subsystem-to-subsystem communication. So the sending subsystem must pass on the message via the overseer to the receiving subsystem, in such a way that the receiving subsystem can further address the communication to one of its internal tasks, if necessary. First, the subsystem that spawned a job is responsible for handling the first step of the communication. The overseer is not aware of the hierarchy of tasks within any given subsystem and is only responsible for subsystem-to-subsystem communication. So the sending subsystem must pass on the message via the overseer to the receiving subsystem, in such a way that the receiving subsystem can further address the communication to one of its internal tasks, if necessary.
This communication prevents a certain class of race conditions. When the Overseer determines that it is time for subsystems to begin working on top of a particular relay-parent, it will dispatch a `ActiveLeavesUpdate` message to all subsystems to do so, and those messages will be handled asynchronously by those subsystems. Some subsystems will receive those messsages before others, and it is important that a message sent by subsystem A after receiving `ActiveLeavesUpdate` message will arrive at subsystem B after its `ActiveLeavesUpdate` message. If subsystem A maintaned an independent channel with subsystem B to communicate, it would be possible for subsystem B to handle the side message before the `ActiveLeavesUpdate` message, but it wouldn't have any logical course of action to take with the side message - leading to it being discarded or improperly handled. Well-architectured state machines should have a single source of inputs, so that is what we do here. This communication prevents a certain class of race conditions. When the Overseer determines that it is time for subsystems to begin working on top of a particular relay-parent, it will dispatch a `ActiveLeavesUpdate` message to all subsystems to do so, and those messages will be handled asynchronously by those subsystems. Some subsystems will receive those messsages before others, and it is important that a message sent by subsystem A after receiving `ActiveLeavesUpdate` message will arrive at subsystem B after its `ActiveLeavesUpdate` message. If subsystem A maintained an independent channel with subsystem B to communicate, it would be possible for subsystem B to handle the side message before the `ActiveLeavesUpdate` message, but it wouldn't have any logical course of action to take with the side message - leading to it being discarded or improperly handled. Well-architectured state machines should have a single source of inputs, so that is what we do here.
One exception is reasonable to make for responses to requests. A request should be made via the overseer in order to ensure that it arrives after any relevant `ActiveLeavesUpdate` message. A subsystem issuing a request as a result of a `ActiveLeavesUpdate` message can safely receive the response via a side-channel for two reasons: One exception is reasonable to make for responses to requests. A request should be made via the overseer in order to ensure that it arrives after any relevant `ActiveLeavesUpdate` message. A subsystem issuing a request as a result of a `ActiveLeavesUpdate` message can safely receive the response via a side-channel for two reasons:
@@ -10,7 +10,7 @@ This subsystem needs to update its information on the unfinalized chain:
* On every `ChainSelectionMessage::Approve` * On every `ChainSelectionMessage::Approve`
* Periodically, to detect stagnation. * Periodically, to detect stagnation.
Simple implementations of these updates do O(n_unfinalized_blocks) disk operations. If the amount of unfinalized blocks is relatively small, the updates should not take very much time. However, in cases where there are hundreds or thousands of unfinalized blocks the naive implementations of these update algorithms would have to be replaced with more sophisticated versions. Simple implementations of these updates do `O(n_unfinalized_blocks)` disk operations. If the amount of unfinalized blocks is relatively small, the updates should not take very much time. However, in cases where there are hundreds or thousands of unfinalized blocks the naive implementations of these update algorithms would have to be replaced with more sophisticated versions.
### `OverseerSignal::ActiveLeavesUpdate` ### `OverseerSignal::ActiveLeavesUpdate`
@@ -14,6 +14,6 @@ with the `NetworkBridgeMessage::NewGossipTopology` message.
See https://github.com/paritytech/polkadot/issues/3239 for more details. See https://github.com/paritytech/polkadot/issues/3239 for more details.
The gossip topology is used by parachain distribution subsystems, The gossip topology is used by parachain distribution subsystems,
such as Bitfield Distrubution, (small) Statement Distributuion and such as Bitfield Distribution, (small) Statement Distribution and
Approval Distibution to limit the amount of peers we send messages to Approval Distribution to limit the amount of peers we send messages to
and handle view updates. and handle view updates.
@@ -54,7 +54,7 @@ The bulk of the work done by this subsystem is in responding to network events,
Each network event is associated with a particular peer-set. Each network event is associated with a particular peer-set.
### Overseer Signal: ActiveLeavesUpdate ### Overseer Signal: `ActiveLeavesUpdate`
The `activated` and `deactivated` lists determine the evolution of our local view over time. A `ProtocolMessage::ViewUpdate` is issued to each connected peer on each peer-set, and a `NetworkBridgeEvent::OurViewChange` is issued to each event handler for each protocol. The `activated` and `deactivated` lists determine the evolution of our local view over time. A `ProtocolMessage::ViewUpdate` is issued to each connected peer on each peer-set, and a `NetworkBridgeEvent::OurViewChange` is issued to each event handler for each protocol.
@@ -62,51 +62,51 @@ We only send view updates if the node has indicated that it has finished major b
If we are connected to the same peer on both peer-sets, we will send the peer two view updates as a result. If we are connected to the same peer on both peer-sets, we will send the peer two view updates as a result.
### Overseer Signal: BlockFinalized ### Overseer Signal: `BlockFinalized`
We update our view's `finalized_number` to the provided one and delay `ProtocolMessage::ViewUpdate` and `NetworkBridgeEvent::OurViewChange` till the next `ActiveLeavesUpdate`. We update our view's `finalized_number` to the provided one and delay `ProtocolMessage::ViewUpdate` and `NetworkBridgeEvent::OurViewChange` till the next `ActiveLeavesUpdate`.
### Network Event: Peer Connected ### Network Event: `PeerConnected`
Issue a `NetworkBridgeEvent::PeerConnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer. Also issue a `NetworkBridgeEvent::PeerViewChange` and send the peer our current view, but only if the node has indicated that it has finished major blockchain synchronization. Otherwise, we only send the peer an empty view. Issue a `NetworkBridgeEvent::PeerConnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer. Also issue a `NetworkBridgeEvent::PeerViewChange` and send the peer our current view, but only if the node has indicated that it has finished major blockchain synchronization. Otherwise, we only send the peer an empty view.
### Network Event: Peer Disconnected ### Network Event: `PeerDisconnected`
Issue a `NetworkBridgeEvent::PeerDisconnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer. Issue a `NetworkBridgeEvent::PeerDisconnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer.
### Network Event: ProtocolMessage ### Network Event: `ProtocolMessage`
Map the message onto the corresponding [Event Handler](#event-handlers) based on the peer-set this message was received on and dispatch via overseer. Map the message onto the corresponding [Event Handler](#event-handlers) based on the peer-set this message was received on and dispatch via overseer.
### Network Event: ViewUpdate ### Network Event: `ViewUpdate`
- Check that the new view is valid and note it as the most recent view update of the peer on this peer-set. - Check that the new view is valid and note it as the most recent view update of the peer on this peer-set.
- Map a `NetworkBridgeEvent::PeerViewChange` onto the corresponding [Event Handler](#event-handlers) based on the peer-set this message was received on and dispatch via overseer. - Map a `NetworkBridgeEvent::PeerViewChange` onto the corresponding [Event Handler](#event-handlers) based on the peer-set this message was received on and dispatch via overseer.
### ReportPeer ### `ReportPeer`
- Adjust peer reputation according to cost or benefit provided - Adjust peer reputation according to cost or benefit provided
### DisconnectPeer ### `DisconnectPeer`
- Disconnect the peer from the peer-set requested, if connected. - Disconnect the peer from the peer-set requested, if connected.
### SendValidationMessage / SendValidationMessages ### `SendValidationMessage` / `SendValidationMessages`
- Issue a corresponding `ProtocolMessage` to each listed peer on the validation peer-set. - Issue a corresponding `ProtocolMessage` to each listed peer on the validation peer-set.
### SendCollationMessage / SendCollationMessages ### `SendCollationMessage` / `SendCollationMessages`
- Issue a corresponding `ProtocolMessage` to each listed peer on the collation peer-set. - Issue a corresponding `ProtocolMessage` to each listed peer on the collation peer-set.
### ConnectToValidators ### `ConnectToValidators`
- Determine the DHT keys to use for each validator based on the relay-chain state and Runtime API. - Determine the DHT keys to use for each validator based on the relay-chain state and Runtime API.
- Recover the Peer IDs of the validators from the DHT. There may be more than one peer ID per validator. - Recover the Peer IDs of the validators from the DHT. There may be more than one peer ID per validator.
- Send all `(ValidatorId, PeerId)` pairs on the response channel. - Send all `(ValidatorId, PeerId)` pairs on the response channel.
- Feed all Peer IDs to peer set manager the underlying network provides. - Feed all Peer IDs to peer set manager the underlying network provides.
### NewGossipTopology ### `NewGossipTopology`
- Map all `AuthorityDiscoveryId`s to `PeerId`s and issue a corresponding `NetworkBridgeUpdateV1` - Map all `AuthorityDiscoveryId`s to `PeerId`s and issue a corresponding `NetworkBridgeUpdateV1`
to all validation subsystems. to all validation subsystems.
@@ -10,10 +10,10 @@ Output: None
## Functionality ## Functionality
On receipt of `RuntimeApiMessage::Request(relay_parent, request)`, answer the request using the post-state of the relay_parent provided and provide the response to the side-channel embedded within the request. On receipt of `RuntimeApiMessage::Request(relay_parent, request)`, answer the request using the post-state of the `relay_parent` provided and provide the response to the side-channel embedded within the request.
> TODO Do some caching. The underlying rocksdb already has a cache of trie nodes so duplicate requests are unlikely to hit disk. Not required for functionality. > TODO Do some caching. The underlying rocksdb already has a cache of trie nodes so duplicate requests are unlikely to hit disk. Not required for functionality.
## Jobs ## Jobs
> TODO Don't limit requests based on parent hash, but limit caching. No caching should be done for any requests on relay_parents that are not active based on `ActiveLeavesUpdate` messages. Maybe with some leeway for things that have just been stopped. > TODO Don't limit requests based on parent hash, but limit caching. No caching should be done for any requests on `relay_parent`s that are not active based on `ActiveLeavesUpdate` messages. Maybe with some leeway for things that have just been stopped.
@@ -38,11 +38,11 @@ We need two separate keys for the approval subsystem:
- **Approval assignment keys** are sr25519/schnorrkel keys used only for the assignment criteria VRFs. We implicitly sign assignment notices with approval assignment keys by including their relay chain context and additional data in the VRF's extra message, but exclude these from its VRF input. - **Approval assignment keys** are sr25519/schnorrkel keys used only for the assignment criteria VRFs. We implicitly sign assignment notices with approval assignment keys by including their relay chain context and additional data in the VRF's extra message, but exclude these from its VRF input.
- **Approval vote keys** would only sign off on candidate parablock validity and has no natural key type restrictions. There's no need for this to actualy embody a new session key type. We just want to make a distinction between assignments and approvals, although distant future node configurations might favor separate roles. We re-use the same keys as are used for parachain backing in practice. - **Approval vote keys** would only sign off on candidate parablock validity and has no natural key type restrictions. There's no need for this to actually embody a new session key type. We just want to make a distinction between assignments and approvals, although distant future node configurations might favor separate roles. We re-use the same keys as are used for parachain backing in practice.
Approval vote keys could relatively easily be handled by some hardened signer tooling, perhaps even HSMs assuming we select ed25519 for approval vote keys. Approval assignment keys might or might not support hardened signer tooling, but doing so sounds far more complex. In fact, assignment keys determine only VRF outputs that determine approval checker assignments, for which they can only act or not act, so they cannot equivocate, lie, etc. and represent little if any slashing risk for validator operators. Approval vote keys could relatively easily be handled by some hardened signer tooling, perhaps even HSMs assuming we select ed25519 for approval vote keys. Approval assignment keys might or might not support hardened signer tooling, but doing so sounds far more complex. In fact, assignment keys determine only VRF outputs that determine approval checker assignments, for which they can only act or not act, so they cannot equivocate, lie, etc. and represent little if any slashing risk for validator operators.
In future, we shall determine which among the several hardening techniques best benefits the netwrok as a whole. We could provide a multi-process multi-machine architecture for validators, perhaps even reminiscent of GNUNet, or perhaps more resembling smart HSM tooling. We might instead design a system that more resembled full systems, like like Cosmos' sentry nodes. In either case, approval assignments might be handled by a slightly hardened machine, but not necessarily nearly as hardened as approval votes, but approval votes machines must similarly run foreign WASM code, which increases their risk, so assignments being separate sounds helpful. In future, we shall determine which among the several hardening techniques best benefits the network as a whole. We could provide a multi-process multi-machine architecture for validators, perhaps even reminiscent of GNUNet, or perhaps more resembling smart HSM tooling. We might instead design a system that more resembled full systems, like like Cosmos' sentry nodes. In either case, approval assignments might be handled by a slightly hardened machine, but not necessarily nearly as hardened as approval votes, but approval votes machines must similarly run foreign WASM code, which increases their risk, so assignments being separate sounds helpful.
## Assignments ## Assignments
@@ -116,7 +116,7 @@ We track all validators' announced approval assignments for each candidate assoc
We permit at most one assignment per candidate per story per validator, so one validator could be assigned under both the `RelayVRFDelay` and `RelayEquivocation` criteria, but not under both `RelayVRFModulo` and `RelayVRFDelay` criteria, since those both use the same story. We permit only one approval vote per candidate per validator, which counts for any applicable criteria. We permit at most one assignment per candidate per story per validator, so one validator could be assigned under both the `RelayVRFDelay` and `RelayEquivocation` criteria, but not under both `RelayVRFModulo` and `RelayVRFDelay` criteria, since those both use the same story. We permit only one approval vote per candidate per validator, which counts for any applicable criteria.
We announce, and start checking for, our own assignments when their tranche's delay is reached, but only if the tracker says the assignee candidate requires more approval checkers. We never announce an assignment we believe unnecessary because early announcements gives an adversary information. All delay tranche zero assignments always get announced, which includes all `RelayVRFModulo` assignments. We announce, and start checking for, our own assignments when the delay of their tranche is reached, but only if the tracker says the assignee candidate requires more approval checkers. We never announce an assignment we believe unnecessary because early announcements gives an adversary information. All delay tranche zero assignments always get announced, which includes all `RelayVRFModulo` assignments.
In other words, if some candidate `C` needs more approval checkers by the time we reach round `t` then any validators with an assignment to `C` in delay tranche `t` gossip their send assignment notice for `C`, and begin reconstruction and validation for 'C. If however `C` reached enough assignments, then validators with later assignments skip announcing their assignments. In other words, if some candidate `C` needs more approval checkers by the time we reach round `t` then any validators with an assignment to `C` in delay tranche `t` gossip their send assignment notice for `C`, and begin reconstruction and validation for 'C. If however `C` reached enough assignments, then validators with later assignments skip announcing their assignments.
@@ -136,9 +136,9 @@ We escalated so quickly because we worried that Charlie and Cindy might be the o
We therefore require the "no show" timeout to be longer than a relay chain slot so that we can witness "no shows" on-chain. We discuss below how this helps reward validators who replace "no shows". We therefore require the "no show" timeout to be longer than a relay chain slot so that we can witness "no shows" on-chain. We discuss below how this helps reward validators who replace "no shows".
We avoid slashing for "no shows" per se, although being "no show" could enter into some computation that punishes repeated poor performance, presumably replaces ImOnline, and we could reduce their rewards and further rewards those who filled in. We avoid slashing for "no shows" by itself, although being "no show" could enter into some computation that punishes repeated poor performance, presumably replaces `ImOnline`, and we could reduce their rewards and further rewards those who filled in.
As future work, we foresee expanding the "no show" scheme to anonymizes the additional checkers, like by using assignment noticed with a new criteria that employs a ring VRF and then all validators providing cover by requesting a couple erasure coded pieces, but such anonymity scheme sound extremely complex and lie far beyond our initial functionality. As future work, we foresee expanding the "no show" scheme to anonymize the additional checkers, like by using assignment noticed with a new criteria that employs a ring VRF and then all validators providing cover by requesting a couple erasure coded pieces, but such anonymity scheme sound extremely complex and lie far beyond our initial functionality.
## Assignment postponement ## Assignment postponement
@@ -152,7 +152,7 @@ TODO: When? Is this optimal for the network? etc.
## On-chain verification ## On-chain verification
We should verify approval on-chain to reward approval checkers. We therefore require the "no show" timeout to be longer than a relay chain slot so that we can witness "no shows" on-chain, which helps with this goal. The major challenge with an on-chain record of the off-chain process is adversarial block producers who may either censor votes or publish votes to the chain which cause other votes to be ignored and unrewards (reward stealing). We should verify approval on-chain to reward approval checkers. We therefore require the "no show" timeout to be longer than a relay chain slot so that we can witness "no shows" on-chain, which helps with this goal. The major challenge with an on-chain record of the off-chain process is adversarial block producers who may either censor votes or publish votes to the chain which cause other votes to be ignored and unrewarded (reward stealing).
In principle, all validators have some "tranche" at which they're assigned to the parachain candidate, which ensures we reach enough validators eventually. As noted above, we often retract "no shows" when the slow validator eventually shows up, so witnessing their initially being a "no show" helps manage rewards. In principle, all validators have some "tranche" at which they're assigned to the parachain candidate, which ensures we reach enough validators eventually. As noted above, we often retract "no shows" when the slow validator eventually shows up, so witnessing their initially being a "no show" helps manage rewards.
@@ -164,11 +164,11 @@ We need the chain to win in this case, but doing this requires imposing an annoy
## Parameters ## Parameters
We prefer doing approval checkers assignments under `RelayVRFModulo` as opposed to `RelayVRFDelay` because `RelayVRFModulo` avoids giving individual checkers too many assignments and tranche zero assignments benefit security the most. We suggest assigning at least 16 checkers under `RelayVRFModulo` although assignment levels have never been properly analysed. We prefer doing approval checkers assignments under `RelayVRFModulo` as opposed to `RelayVRFDelay` because `RelayVRFModulo` avoids giving individual checkers too many assignments and tranche zero assignments benefit security the most. We suggest assigning at least 16 checkers under `RelayVRFModulo` although assignment levels have never been properly analyzed.
Our delay criteria `RelayVRFDelay` and `RelayEquivocation` both have two primary paramaters, expected checkers per tranche and the zeroth delay tranche width. Our delay criteria `RelayVRFDelay` and `RelayEquivocation` both have two primary paramaters, expected checkers per tranche and the zeroth delay tranche width.
We require expected checkers per tranche to be less than three because otherwise an adversary with 1/3 stake could force all nodes into checking all blocks. We strongly recommend expected checkers per tranche to be less than two, which helps avoid both accedental and intentional explosions. We also suggest expected checkers per tranche be larger than one, which helps prevent adversaries from predicting than advancing one tranche adds only their own validators. We require expected checkers per tranche to be less than three because otherwise an adversary with 1/3 stake could force all nodes into checking all blocks. We strongly recommend expected checkers per tranche to be less than two, which helps avoid both accidental and intentional explosions. We also suggest expected checkers per tranche be larger than one, which helps prevent adversaries from predicting than advancing one tranche adds only their own validators.
We improve security more with tranche zero assignments, so `RelayEquivocation` should consolidates its first several tranches into tranche zero. We describe this as the zeroth delay tranche width, which initially we set to 12 for `RelayEquivocation` and `1` for `RelayVRFDelay`. We improve security more with tranche zero assignments, so `RelayEquivocation` should consolidates its first several tranches into tranche zero. We describe this as the zeroth delay tranche width, which initially we set to 12 for `RelayEquivocation` and `1` for `RelayVRFDelay`.
@@ -184,7 +184,7 @@ VRFs though require adversaries wait far longer between such attacks, which also
Any validator could send their assignment notices and/or approval votes too early. We gossip the approval votes because they represent a major commitment by the validator. We retain but delay gossiping the assignment notices until they agree with our local clock. Any validator could send their assignment notices and/or approval votes too early. We gossip the approval votes because they represent a major commitment by the validator. We retain but delay gossiping the assignment notices until they agree with our local clock.
Assignment notices being gossiped too early might create a denial of service vector. If so, we might exploit the relative time scheme that synchronises our clocks, which conceivably permits just dropping excessively early assignments. Assignment notices being gossiped too early might create a denial of service vector. If so, we might exploit the relative time scheme that synchronizes our clocks, which conceivably permits just dropping excessively early assignments.
## Finality GRANDPA Voting Rule ## Finality GRANDPA Voting Rule
@@ -1,6 +1,6 @@
# Disputes # Disputes
Fast forward to [more detailed disputes requirments](./disputes-flow.md). Fast forward to [more detailed disputes requirements](./disputes-flow.md).
## Motivation and Background ## Motivation and Background
@@ -1,10 +1,10 @@
# Approval Types # Approval Types
## AssignmentId ## `AssignmentId`
The public key of a keypair used by a validator for determining assignments to approve included parachain candidates. The public key of a keypair used by a validator for determining assignments to approve included parachain candidates.
## AssignmentCert ## `AssignmentCert`
An `AssignmentCert`, short for Assignment Certificate, is a piece of data provided by a validator to prove that they have been selected to perform secondary approval checks on an included candidate. An `AssignmentCert`, short for Assignment Certificate, is a piece of data provided by a validator to prove that they have been selected to perform secondary approval checks on an included candidate.
@@ -28,9 +28,9 @@ struct AssignmentCert {
} }
``` ```
> TODO: RelayEquivocation cert. Probably can only be broadcast to chains that have handled an equivocation report. > TODO: `RelayEquivocation` cert. Probably can only be broadcast to chains that have handled an equivocation report.
## IndirectAssignmentCert ## `IndirectAssignmentCert`
An assignment cert which refers to the candidate under which the assignment is relevant by block hash. An assignment cert which refers to the candidate under which the assignment is relevant by block hash.
@@ -43,7 +43,7 @@ struct IndirectAssignmentCert {
} }
``` ```
## ApprovalVote ## `ApprovalVote`
A vote of approval on a candidate. A vote of approval on a candidate.
@@ -51,7 +51,7 @@ A vote of approval on a candidate.
struct ApprovalVote(Hash); struct ApprovalVote(Hash);
``` ```
## SignedApprovalVote ## `SignedApprovalVote`
An approval vote signed with a validator's key. This should be verifiable under the `ValidatorId` corresponding to the `ValidatorIndex` of the session, which should be implicit from context. An approval vote signed with a validator's key. This should be verifiable under the `ValidatorId` corresponding to the `ValidatorIndex` of the session, which should be implicit from context.
@@ -63,7 +63,7 @@ struct SignedApprovalVote {
} }
``` ```
## IndirectSignedApprovalVote ## `IndirectSignedApprovalVote`
A signed approval vote which references the candidate indirectly via the block. If there exists a look-up to the candidate hash from the block hash and candidate index, then this can be transformed into a `SignedApprovalVote`. A signed approval vote which references the candidate indirectly via the block. If there exists a look-up to the candidate hash from the block hash and candidate index, then this can be transformed into a `SignedApprovalVote`.
@@ -80,9 +80,9 @@ struct IndirectSignedApprovalVote {
} }
``` ```
## CheckedAssignmentCert ## `CheckedAssignmentCert`
An assignment cert which has checked both the VRF and the validity of the implied assignment according to the selection criteria rules of the protocol. This type should be declared in such a way as to be instantiable only when the checks have actually been done. Fields should be accessible via getters, not direct struct access. An assignment cert which has checked both the VRF and the validity of the implied assignment according to the selection criteria rules of the protocol. This type should be declared in such a way as to be instantiatable only when the checks have actually been done. Fields should be accessible via getters, not direct struct access.
```rust ```rust
struct CheckedAssignmentCert { struct CheckedAssignmentCert {
@@ -94,7 +94,7 @@ struct CheckedAssignmentCert {
} }
``` ```
## DelayTranche ## `DelayTranche`
```rust ```rust
type DelayTranche = u32; type DelayTranche = u32;
+1 -1
View File
@@ -90,7 +90,7 @@ pub struct FullDeps<C, P, SC, B> {
pub client: Arc<C>, pub client: Arc<C>,
/// Transaction pool instance. /// Transaction pool instance.
pub pool: Arc<P>, pub pool: Arc<P>,
/// The SelectChain Strategy /// The [`SelectChain`] Strategy
pub select_chain: SC, pub select_chain: SC,
/// A copy of the chain spec. /// A copy of the chain spec.
pub chain_spec: Box<dyn sc_chain_spec::ChainSpec>, pub chain_spec: Box<dyn sc_chain_spec::ChainSpec>,
+17 -1
View File
@@ -1,8 +1,10 @@
150 150
accessor/MS accessor/MS
activations activations
acyclic
adversary/SM adversary/SM
annualised annualised
anonymize/D
Apache-2.0/M Apache-2.0/M
API API
APIs APIs
@@ -11,6 +13,7 @@ assignee/SM
async async
asynchrony asynchrony
autogenerated autogenerated
A&V
backable backable
backend/MS backend/MS
benchmark/DSMG benchmark/DSMG
@@ -46,8 +49,10 @@ deinitializing
dequeue/SD dequeue/SD
deregister deregister
deserialize/G deserialize/G
DHT
disincentivize/D disincentivize/D
dispatchable/SM dispatchable/SM
DLEQ
DMP/SM DMP/SM
DMQ DMQ
DoS DoS
@@ -66,11 +71,13 @@ externality/MS
extrinsic extrinsic
extrinsics extrinsics
fedora/M fedora/M
finalize/B
FRAME/MS FRAME/MS
FSMs FSMs
gameable gameable
getter/MS getter/MS
GiB/S GiB/S
GNUNet
GPL/M GPL/M
GPLv3/M GPLv3/M
Grafana/MS Grafana/MS
@@ -78,6 +85,7 @@ Gurke/MS
Handler/MS Handler/MS
HMP/SM HMP/SM
HRMP HRMP
HSM
https https
iff iff
implementer/MS implementer/MS
@@ -164,9 +172,12 @@ phragmen
picosecond/SM picosecond/SM
PoA/MS PoA/MS
polkadot/MS polkadot/MS
PoS/MS
PoV/MS PoV/MS
PoW/MS
PR PR
preconfigured preconfigured
preimage/MS
preopen preopen
prepend/G prepend/G
prevalidation prevalidation
@@ -192,10 +203,13 @@ RPC/MS
runtime/MS runtime/MS
rustc/MS rustc/MS
SAFT SAFT
scalable
scalability scalability
Schnorr
schnorrkel
SDF SDF
sending/S sending/S
ServiceFactory sharding
shareable shareable
Simnet/MS Simnet/MS
spawn/SR spawn/SR
@@ -236,6 +250,8 @@ unreceived
unreserve unreserve
unreserving unreserving
unservable/B unservable/B
untrusted
untyped
unvested unvested
URI URI
utilize utilize