mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-08-10 03:25:44 +00:00
a30092ab42
* Add markdown linting - add linter default rules - adapt rules to current code - fix the code for linting to pass - add CI check fix #1243 * Fix markdown for Substrate * Fix tooling install * Fix workflow * Add documentation * Remove trailing spaces * Update .github/.markdownlint.yaml Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix mangled markdown/lists * Fix captalization issues on known words
26 lines
1.9 KiB
Markdown
26 lines
1.9 KiB
Markdown
# GRANDPA Voting Rule
|
|
|
|
Specifics on the motivation and types of constraints we apply to the GRANDPA voting logic as well as the definitions of
|
|
**viable** and **finalizable** blocks can be found in the [Chain Selection Protocol](../protocol-chain-selection.md)
|
|
section. The subsystem which provides us with viable leaves is the [Chain Selection
|
|
Subsystem](utility/chain-selection.md).
|
|
|
|
GRANDPA's regular voting rule is for each validator to select the longest chain they are aware of. GRANDPA proceeds in
|
|
rounds, collecting information from all online validators and determines the blocks that a supermajority of validators
|
|
all have in common with each other.
|
|
|
|
The low-level GRANDPA logic will provide us with a **required block**. We can find the best leaf containing that block
|
|
in its chain with the
|
|
[`ChainSelectionMessage::BestLeafContaining`](../types/overseer-protocol.md#chain-selection-message). If the result is
|
|
`None`, then we will simply cast a vote on the required block.
|
|
|
|
The **viable** leaves provided from the chain selection subsystem are not necessarily **finalizable**, so we need to
|
|
perform further work to discover the finalizable ancestor of the block. The first constraint is to avoid voting on any
|
|
unapproved block. The highest approved ancestor of a given block can be determined by querying the Approval Voting
|
|
subsystem via the [`ApprovalVotingMessage::ApprovedAncestor`](../types/overseer-protocol.md#approval-voting) message. If
|
|
the response is `Some`, we continue and apply the second constraint. The second constraint is to avoid voting on any
|
|
block containing a candidate undergoing an active dispute. The list of block hashes and candidates returned from
|
|
`ApprovedAncestor` should be reversed, and passed to the
|
|
[`DisputeCoordinatorMessage::DetermineUndisputedChain`](../types/overseer-protocol.md#dispute-coordinator-message) to
|
|
determine the **finalizable** block which will be our eventual vote.
|