From 4beb749169deca6b04df2bf226e44a27ac639f9b Mon Sep 17 00:00:00 2001 From: Federico Franzoni <8609060+fed-franz@users.noreply.github.com> Date: Sun, 4 Feb 2024 23:11:51 +0100 Subject: [PATCH 1/3] Format structs with monospace --- blockchain/README.md | 19 ++--- consensus/README.md | 23 +++--- consensus/basics/README.md | 25 +++--- consensus/chain-management/README.md | 16 ++-- consensus/messages/README.md | 116 +++++++++++++-------------- consensus/notation/README.md | 7 +- consensus/proposal/README.md | 8 +- consensus/ratification/README.md | 12 +-- consensus/validation/README.md | 8 +- 9 files changed, 117 insertions(+), 117 deletions(-) diff --git a/blockchain/README.md b/blockchain/README.md index b02e258..a6db9ab 100644 --- a/blockchain/README.md +++ b/blockchain/README.md @@ -2,13 +2,14 @@ This section describes the formal definition of the Dusk chain, block, and transaction structures. #### ToC - - [Chain](#chain) - - [Block](#block) - - [BlockHeader](#blockheader) - - [Transaction](#transaction) + - [**Chain**](#chain) + - [`Block`](#block) + - [`BlockHeader`](#blockheader) + - [`Transaction`](#transaction) -## Chain + +## **Chain** The local copy of the blockchain stored by a node is defined as a vector of [blocks](#block) along with their *consensus status* label (see [Block Finality][fin]): $$\textbf{Chain}: [(\mathsf{B}_0, Status_0), \text{ }\dots, (\mathsf{B}_n, Status_n)],$$ @@ -23,14 +24,14 @@ where $\mathsf{B}_0$ is the genesis block and $Status_0 = Final$ (that is, the g -## Block +## `Block` | Field | Type | Size | Description | |------------------|------------------------|-----------|--------------------| | $Header$ | [`BlockHeader`][bh] | 112 bytes | Block header | | $Transactions$ | [`Transaction`][tx][ ] | variable | Block transactions | -## BlockHeader +## `BlockHeader` | Field | Type | Size | Description | |------------------------|-------------------------|------------|-----------------------------------------------------| @@ -49,7 +50,7 @@ where $\mathsf{B}_0$ is the genesis block and $Status_0 = Final$ (that is, the g | $Hash$ | Sha3 Hash | 32 bytes | Hash of previous fields | | $Attestation$ | [`Attestation`][att] | 112 bytes | Attestation of the $Valid$ votes for the block | -The $\mathsf{BlockHeader}$ structure has a variable total size of 522 to 28970 bytes (28.8 KB). +The `BlockHeader` structure has a variable total size of 522 to 28970 bytes (28.8 KB). This is reduced to 410-28448 bytes for a [*candidate block*][cb], since $Attestation$ is missing. **Notation** @@ -64,7 +65,7 @@ $\hspace{50pt}Generator||TransactionRoot||StateRoot||PrevBlockCertificate||Faile -## Transaction +## `Transaction` | Field | Type | Size | Description | |-----------|------------------|-----------|---------------------| diff --git a/consensus/README.md b/consensus/README.md index 619f27b..7aaa2fc 100644 --- a/consensus/README.md +++ b/consensus/README.md @@ -37,11 +37,11 @@ The SA protocol proceeds in ***rounds***, with each round adding a new block to In turn, each round proceeds in ***iterations***, with each iteration aiming at generating a candidate block and reaching agreement among provisioners. Each iteration is composed of three phases, or ***steps***: - 1. ***Proposal***: in this step, a *generator*, extracted via [*DS*][ds], creates a new candidate block and broadcasts it to the network using a $\mathsf{Candidate}$ message; + 1. [***Proposal***][prop]: in this step, a *generator*, extracted via [*DS*][ds], creates a new candidate block and broadcasts it to the network using a `Candidate` message; - 2. ***Validation***: in this step, a committee of provisioners, extracted via [*DS*][ds], votes on the validity of the candidate block via $\mathsf{Validation}$ messages. The committee can reach a successful *quorum* with a supermajority ($\frac{2}{3}$) of $Valid$ votes or an unsuccessful quorum with a majority ($\frac{1}{2}+1$) of $Invalid$ votes, cast for an invalid candidate, or $NoCandidate$ votes, cast when the candidate is unknown. + 2. [***Validation***][val]: in this step, a committee of provisioners, extracted via [*DS*][ds], votes on the validity of the candidate block via `Validation` messages. The committee can reach a successful *quorum* with a supermajority ($\frac{2}{3}$) of $Valid$ votes or an unsuccessful quorum with a majority ($\frac{1}{2}+1$) of $Invalid$ votes, cast for an invalid candidate, or $NoCandidate$ votes, cast when the candidate is unknown. - 3. ***Ratification***: in this step, a new committee of provisioners, extracted via [*DS*][ds], votes on the result of the previous Validation step via $\mathsf{Ratification}$ messages. If a quorum was reached they cast the winning Validation vote, otherwise they will vote $NoQuorum$. If a quorum is reached, a $\mathsf{Quorum}$ message is broadcast, containing a $\mathsf{Attestation}$ with the votes of the two steps. + 3. [***Ratification***][rat]: in this step, a new committee of provisioners, extracted via [*DS*][ds], votes on the result of the previous Validation step via `Ratification` messages. If a quorum was reached they cast the winning Validation vote, otherwise they will vote $NoQuorum$. If a quorum is reached, a `Quorum` message is broadcast, containing an `Attestation` with the votes of the two steps. Similar to Validation, the step succeeds if a supermajority quorum of $Valid$ votes is received, and it fails with a majority quorum of $Invalid$, $NoCandidate$, or $NoQuorum$ votes. If no quorum is reached, the step result is unknown. @@ -185,7 +185,7 @@ We here define global parameters and state variables of the SA protocol, used an The SA environment is composed of: - *global parameters*: network-wide parameters used by all nodes of the network using a particular protocol version; -- *chain state*: represent the current system state, as per result of the execution of all transactions in the blockchain; +- *chain state*: represents the current system state, as per result of the execution of all transactions in the blockchain; - *round state*: local variables used to handle the consensus state Additionally, we denote the node running the protocol with $\mathcal{N}$ and refer to its provisioner[^1] keys as $sk_\mathcal{N}$ and $pk_\mathcal{N}$. @@ -232,7 +232,7 @@ All global values (except for the genesis block) refer to version $0$ of the pro ## Procedures The SA consensus is defined by the [*SAInit*][init] procedure, which executes an infinite loop ([*SALoop*][sal]) of rounds ([*SARound*][sar]), each executing one or more iterations ([*SAIteration*][sai]) until a *winning block* ($\mathsf{B}^w$) is produced for the round, becoming the new $Tip$ of the chain ([*AcceptBlock*][ab]). The consensus loop could be interrupted when receiving a valid $\mathsf{Block}$ (see [*HandleBlock*][hb]) which could trigger the [*fallback*][fal] or [*synchronization*][syn] procedures. -Similarly, receiving a $\mathsf{Quorum}$ message could interrupt a consensus round by accepting a candidate as the new $Tip$ (see [*HandleQuorum*][hq]). +Similarly, receiving a [`Quorum`][qmsg] message could interrupt a consensus round by accepting a candidate as the new $Tip$ (see [*HandleQuorum*][hq]). ### *SAInit* @@ -240,7 +240,7 @@ Similarly, receiving a $\mathsf{Quorum}$ message could interrupt a consensus rou Upon boot, the node checks if there is a local state saved and, if so, loads it. Otherwise, it sets the local $Tip$ to *GenesisBlock*. Then, it probes the network to check if it is in sync or not with the main chain. If not, it starts a synchronization procedure. -When the node is synchronized, it starts [*SALoop*][sal] to execute the consensus *rounds* and [*HandleBlock*][hb] to handle incoming $\mathsf{Block}$ messages. +When the node is synchronized, it starts [*SALoop*][sal] to execute the consensus *rounds* and [*HandleBlock*][hb] to handle incoming [`Block`][bmsg] messages. ***Algorithm*** @@ -289,8 +289,8 @@ $\textit{SALoop}():$


### *SARound* -*SARound* executes a single consensus round. First, it initializes the [*Round State*][cenv] variables; then, it starts the [*HandleQuorum*][hq] process in the background, to handle $\mathsf{Quorum}$ messages for the round, and starts executing consensus iterations ([*SAIteration*][sai]). -If, at any time, a winning block $\mathsf{B}^w$ is produced, as the result of a successful iteration or due to a $\mathsf{Quorum}$ message, it is accepted to the [local chain][lc] and the round ends. +*SARound* executes a single consensus round. First, it initializes the [*Round State*][cenv] variables; then, it starts the [*HandleQuorum*][hq] process in the background, to handle [`Quorum`][qmsg] messages for the round, and starts executing consensus iterations ([*SAIteration*][sai]). +If, at any time, a winning block $\mathsf{B}^w$ is produced, as the result of a successful iteration or due to a `Quorum` message, it is accepted to the [local chain][lc] and the round ends. If, for any reason, the round ends without a winning block, the consensus is deemed unsafe and the whole protocol is halted. Such an event requires a manual recovery procedure. ***Algorithm*** @@ -338,10 +338,10 @@ $\textit{SARound}():$


### *SAIteration* -*SAIteration* executes the sequence of *Proposal*, *Validation*, and *Ratification* steps. +*SAIteration* executes the sequence of [*Proposal*][prop], [*Validation*][val], and [*Ratification*][rat] steps. The *Proposal* outputs the candidate block $\mathsf{B}^c$ for the iteration; this is passed to *Validation*, which, if a quorum is reached, outputs the aggregated Validation votes $\mathsf{SV}^V$; these are passed to *Ratification*, which, if a quorum is reached, outputs the aggregated Ratification votes $\mathsf{SV}^R$. -If a quorum was reached in both Validation and Ratification, a $\mathsf{Quorum}$ message is broadcast with the $\mathsf{Attestation}$ of the iteration (i.e. the two $\mathsf{StepVotes}$ $\mathsf{SV}^V$ and $\mathsf{SV}^R$). +If a quorum was reached in both Validation and Ratification, a `Quorum` message is broadcast with the [`Attestation`][atts] of the iteration (i.e. the two `StepVotes` $\mathsf{SV}^V$ and $\mathsf{SV}^R$). ***Algorithm*** 1. Run *Proposal* to generate the *candidate* block $\mathsf{B}^c$ @@ -380,7 +380,7 @@ $\textit{SAIteration}(R, I):$ 4. [*Broadcast*][mx]$(\mathsf{M}^\mathsf{Q})$ 5. $\texttt{if } (v = Success):$ 1. [*MakeWinning*][mw]$(\mathsf{B}^c, \mathsf{A})$ - 6. $\texttt{else }:$ + 6. $\texttt{else}:$ 1. $\boldsymbol{FailedAttestations}[I] = {\mathsf{A}}$


@@ -483,6 +483,7 @@ $\textit{GetStepNum}(I, Step):$ [qmsg]: https://github.com/dusk-network/dusk-protocol/tree/main/consensus/messages/README.md#quorum [rmsg]: https://github.com/dusk-network/dusk-protocol/tree/main/consensus/messages/README.md#ratification [cmsg]: https://github.com/dusk-network/dusk-protocol/tree/main/consensus/messages/README.md#candidate +[bmsg]: https://github.com/dusk-network/dusk-protocol/tree/main/consensus/messages/README.md#block [sla]: #slashing \ No newline at end of file diff --git a/consensus/basics/README.md b/consensus/basics/README.md index be5addb..667843e 100644 --- a/consensus/basics/README.md +++ b/consensus/basics/README.md @@ -22,9 +22,9 @@ In this section, we describe the building blocks of the SA consensus protocol, s - [*CountCredits*](#countcredits) - [Attestations](#attestations) - [Structures](#structures) - - [Attestation](#attestation) - - [StepVotes](#stepvotes) - - [StepResult](#stepresult) + - [`Attestation`](#attestation) + - [`StepVotes`](#stepvotes) + - [`StepResult`](#stepresult) - [Procedures](#procedures-1) - [*AggregateVote*](#aggregatevote) @@ -108,7 +108,6 @@ When counting votes, each vote is multiplied by the power of the voter in the co Hence, the $CommitteeCredits$ parameter determines the maximum number of members in a committee, and, indirectly, the degree of distribution of the voting process. ### Votes - In the Validation and Ratification steps, members of the voting committees cast their vote on the validity of the block, and to ratify the result of the Validation step. Votes are in the form of BLS signatures, which allow them to be aggregated and verified together. This removes the necessity to store multiple signatures in the block or in the messages. Instead, a single aggregated signature, along with a *bitset* to indicate the signature of which committee members are included, is sufficient to validate the quorum on a candidate block. @@ -253,8 +252,8 @@ An *Attestation* is an aggregate collection of votes from a specific iteration. We use the terms *Valid Attestation* and *Failed Attestation* to refer to the two types of quorum being proved. ### Structures -#### Attestation -The $\mathsf{Attestation}$ structure contains the aggregated votes of the [Validation][val] and [Ratification][rat] steps of a single iteration. The votes of each step are contained in a [`StepVotes`][sv] structure. +#### `Attestation` +The `Attestation` structure contains the aggregated votes of the [Validation][val] and [Ratification][rat] steps of a single iteration. The votes of each step are contained in a [`StepVotes`][sv] structure. | Field | Type | Size | Description | @@ -262,11 +261,11 @@ The $\mathsf{Attestation}$ structure contains the aggregated votes of the [Valid | $Validation$ | [`StepVotes`][sv] | 56 bytes | Aggregated votes of the Validation step | | $Ratification$ | [`StepVotes`][sv] | 56 bytes | Aggregated votes of the Ratification step | -The $\mathsf{Attestation}$ structure has a total size of 112 bytes. +The structure has a total size of 112 bytes. -#### StepVotes -The $\mathsf{StepVotes}$ structure is used to store votes from the [Validation][val] and [Ratification][rat] steps. -Votes are stored as the aggregated BLS signatures of the members of the two Voting Committees. In fact, each [vote][vot] is signed together with the related *Consensus Information* (round, iteration, step) and the hash of the candidate to which the vote refers to. +#### `StepVotes` +The `StepVotes` structure is used to store votes from the [Validation][val] and [Ratification][rat] steps. +Votes are stored as the aggregated BLS signatures of the members of the two Voting Committees. In fact, each [vote][vot] is signed together with the related *Consensus Information* (round, iteration, step) and the hash of the candidate to which the vote refers. To specify the votes from which committee members included in the aggregated signature, a [sub-committee bitset][bs] is used. The structure is defined as follows: @@ -276,10 +275,10 @@ The structure is defined as follows: | $Voters$ | BitSet | 64 bits | Bitset of the voters | | $Votes$ | BLS Signature | 48 bytes | Aggregated step signatures | -The $\mathsf{StepVotes}$ structure has a total size of 56 bytes. +The structure has a total size of 56 bytes. -#### StepResult -The $\mathsf{StepResult}$ structure contains the result of a [Validation][val] or [Ratification][rat] step, that is the step result $Vote$ and the $\mathsf{StepVotes}$ with the aggregated votes producing $Vote$. +#### `StepResult` +The `StepResult` structure contains the result of a [Validation][val] or [Ratification][rat] step, that is the step result $Vote$ and the `StepVotes` with the aggregated votes producing $Vote$. The structure is defined as follows: diff --git a/consensus/chain-management/README.md b/consensus/chain-management/README.md index e5b0e3b..1ede951 100644 --- a/consensus/chain-management/README.md +++ b/consensus/chain-management/README.md @@ -188,7 +188,7 @@ If the block is an [Emergency Block][eb], the block $Attestation$ and $FailedIte $\textit{VerifyBlock}(\mathsf{B}):$ - $\textit{set }:$ - $\mathsf{A}_{\mathsf{B}^p} = \mathsf{B}.PrevBlockCertificate$ - - $\mathsf{A}_\mathsf{B} = \mathsf{B}.Attestation$ + - $\mathsf{A_B} = \mathsf{B}.Attestation$ - $\upsilon_\mathsf{B} = (\mathsf{B}.PrevBlock,\mathsf{B}.Round,\mathsf{B}.Iteration,Valid,\eta_\mathsf{B})$ - $\upsilon_{\mathsf{B}^p} = (\mathsf{B}^p.PrevBlock,\mathsf{B}^p.Round,\mathsf{B}^p.Iteration,Valid,\eta_{\mathsf{B}^p})$ 1. $isValid$ = [*VerifyBlockHeader*][vbh]$(\mathsf{B}^p,\mathsf{B})$ @@ -245,7 +245,7 @@ $\textit{VerifyBlockHeader}(\mathsf{B}, \mathsf{B}^p)$: #### *VerifyAttestation* -*VerifyAttestation* checks a block's Attestation by verifying the Validation and Ratification aggregated signatures against the respective committees. +*VerifyAttestation* checks a block's Attestation by verifying the [Validation][val] and [Ratification][rat] aggregated signatures against the respective committees. ***Parameters*** - $\mathsf{A}$: the attestation to verify @@ -296,7 +296,7 @@ $\textit{VerifyAttestation}(\mathsf{A}, \upsilon):$ ***Procedure*** -$VerifyVotes(\mathsf{SV}, \upsilon, Q)$: +$\textit{VerifyVotes}(\mathsf{SV}, \upsilon, Q)$: - $\texttt{set}:$ - $\boldsymbol{bs}, \sigma_{\boldsymbol{bs}} \leftarrow \mathsf{SV}$ 1. $\mathcal{C}^{\boldsymbol{bs}}=$ [*SubCommittee*][sc]$(\mathcal{C}, \boldsymbol{bs})$ @@ -308,8 +308,8 @@ $VerifyVotes(\mathsf{SV}, \upsilon, Q)$: ## Chain Management We here define block-management procedures: - - [*HandleBlock*][hb]: handle $\mathsf{Block}$ messages from the network - - [*HandleQuorum*][hq]: handle $\mathsf{Quorum}$ messages from the network + - [*HandleBlock*][hb]: handle `Block` messages from the network + - [*HandleQuorum*][hq]: handle `Quorum` messages from the network - [*MakeWinning*][mw]: sets a candidate block as the winning block of the round - [*AcceptBlock*][ab]: accept a block as the new tip - [*Fallback*][fal]: reverts the chain to a specific block @@ -375,7 +375,7 @@ $\textit{HandleBlock}():$ 4. $\texttt{start}($[*SALoop*][sl]$)$ #### *HandleQuorum* -*HandleQuorum* manages $\mathsf{Quorum}$ messages for the current round $R$. If the message was received from the network, it is first verified ([*VerifyQuorum*][vq]) and then propagated. +*HandleQuorum* manages `Quorum` messages for the current round $R$. If the message was received from the network, it is first verified ([*VerifyQuorum*][vq]) and then propagated. The corresponding candidate block is then marked as the winning block of the round ([*MakeWinning*][mw]). ***Parameters*** @@ -434,7 +434,7 @@ $\textit{HandleQuorum}( R ):$ ***Procedure*** -$MakeWinning(\mathsf{B}, \mathsf{A}):$ +$\textit{MakeWinning}(\mathsf{B}, \mathsf{A}):$ 1. $\mathsf{B}.Attestation = \mathsf{A}$ 2. $\mathsf{B}^w = \mathsf{B}$ @@ -559,7 +559,7 @@ When receiving blocks with higher height than the $Tip$'s successor, they are st If an invalid $Tip$'s successor is received by a sync peer while running the protocol, the protocol is ended. ***Parameters*** -- $\mathsf{M^B} = (\mathsf{B}, \mathcal{S})$: received $\mathsf{Block}$ message +- $\mathsf{M^B} = (\mathsf{B}, \mathcal{S})$: received `Block` message ***Algorithm*** diff --git a/consensus/messages/README.md b/consensus/messages/README.md index 9c7712d..450ba40 100644 --- a/consensus/messages/README.md +++ b/consensus/messages/README.md @@ -5,16 +5,16 @@ This section describes the network messages exchanged by nodes to participate in ## ToC - [Consensus Messages](#consensus-messages) - [Sender](#sender) - - [ConsensusInfo](#consensusinfo) - - [VoteInfo](#voteinfo) + - [`ConsensusInfo`](#consensusinfo) + - [`VoteInfo`](#voteinfo) - [Signatures](#signatures) - [SignInfo](#signinfo) - [Messages](#messages) - - [Candidate](#candidate) - - [Validation](#validation) - - [Ratification](#ratification) - - [Quorum](#quorum) - - [Block](#block) + - [`Candidate`](#candidate) + - [`Validation`](#validation) + - [`Ratification`](#ratification) + - [`Quorum`](#quorum) + - [`Block`](#block) - [Sync messages](#sync-messages) - [Procedures](#procedures) - [*Msg*](#msg) @@ -26,24 +26,24 @@ This section describes the network messages exchanged by nodes to participate in ## Consensus Messages To run the SA protocol, nodes exchange four main types of messages: -- $\mathsf{Candidate}$: it stores a candidate block for a specific round and iteration; it is used during the [Proposal][prop] step; -- $\mathsf{Validation}$: it contains the vote of a member of the voting committee for a [Validation][val] step; -- $\mathsf{Ratification}$: it contains the vote of a member of the voting committee for a [Ratification][rat] step; -- $\mathsf{Quorum}$: it contains the aggregated votes of a specific iteration's Validation and Ratification steps; it is generated at the end of an SA iteration if a quorum was reached in the Ratification step; +- `Candidate`: it stores a candidate block for a specific round and iteration; it is used during the [Proposal][prop] step; +- `Validation`: it contains the vote of a member of the voting committee for a [Validation][val] step; +- `Ratification`: it contains the vote of a member of the voting committee for a [Ratification][rat] step; +- `Quorum`: it contains the aggregated votes of a specific iteration's Validation and Ratification steps; it is generated at the end of an SA iteration if a quorum was reached in the Ratification step; -Consensus messages are composed of a [ConsensusInfo][cinf] structure, some fields specific to the message type, and, with the exception of the $\mathsf{Quorum}$ message, a [SignInfo][sinf] structure, containing the public key and signature of the provisioner that created the message. +Consensus messages are composed of a [`ConsensusInfo`][cinf] structure, some fields specific to the message type, and, with the exception of the `Quorum` message, a [`SignInfo`][sinf] structure, containing the public key and signature of the provisioner that created the message. #### Sender All messages include a $Sender$ field indicating the network identity (e.g. the IP address) of the peer from which the message was received. For the sake of readability, this field is omitted from the structure definition. -#### ConsensusInfo -All consensus messages share a common $\mathsf{ConsensusInfo}$ structure that allows identifying the candidate block they refer to. The information included is: the previous block hash, and the round and iteration numbers. +#### `ConsensusInfo` +All consensus messages share a common `ConsensusInfo` structure that allows identifying the candidate block they refer to. The information included is the previous block hash, and the round and iteration numbers. Recall that there's a different candidate block for each round and iteration. However, in the case of a fork, two candidates could exist for the same round and iteration. Including the previous block's hash allows distinguishing the two candidates. -The $\mathsf{ConsensusInfo}$ structure is defined as follows: +The `ConsensusInfo` structure is defined as follows: | Field | Type | Size | Description | |-------------|---------|----------|---------------------| @@ -53,8 +53,8 @@ The $\mathsf{ConsensusInfo}$ structure is defined as follows: The structure's total size is 48 bytes. -#### VoteInfo -$\mathsf{VoteInfo}$ contains the information of a Validation or Ratification vote. +#### `VoteInfo` +`VoteInfo` contains the information of a Validation or Ratification vote. | Field | Type | Size | Description | |-----------------|---------|----------|------------------------| @@ -65,7 +65,7 @@ $Vote$ can be $NoCandidate$ ($0$), $Valid$ ($1$), $Invalid$ ($2$), or $NoQuorum$ When $Vote$ is $NoCandidate$ or $NoQuorum$, $CandidateHash$ is empty. Note that an empty $CandidateHash$ is not included in the [*signature value*][sigs]. -The $\mathsf{VoteInfo}$ structure has a total size of 33 bytes. +The structure has a total size of 33 bytes. ### Signatures Each message contains a *message signature* (included in the $Signature$ field) which is used to verify the message authenticity but is also functional to prove the reached agreement over a candidate block (see [Attestations][atts]) @@ -83,97 +83,97 @@ With respect to message signatures, we also define the following procedures: - $SignMessage(\mathsf{M})$: takes a message $\mathsf{M}$ and outputs the message signature $\sigma_\mathsf{M}$; - $VerifyMessage(\mathsf{M})$: takes a message $\mathsf{M}$ and outputs $true$ if $\sigma_\mathsf{M}$ is a valid signature of $Signer$ over the signature value $\upsilon_\mathsf{M}$. -#### SignInfo -$\mathsf{SignInfo}$ contains the public key of the provisioner creating the message and its signature over the message. +#### `SignInfo` +`SignInfo` contains the public key of the provisioner creating the message and its signature over the message. | Field | Type | Size | Description | |-------------|-------------------|-----------|-----------------------------------| | $Signer$ | BLS Key | 96 bytes | Public Key of the message creator | | $Signature$ | BLS Signature | 48 bytes | Message signature | -The $\mathsf{SignInfo}$ structure has a total size of 144 bytes. +The structure has a total size of 144 bytes. -The $Signer$ field identifies the provisioner sending the message. For instance, in a $Candidate$ message, this field identifies the block generator, while, in a $\mathsf{Validation}$ message, it identifies the committee member who cast the vote. +The $Signer$ field identifies the provisioner sending the message. For instance, in a `Candidate` message, this field identifies the block generator, while, in a `Validation` message, it identifies the committee member who cast the vote. -The $Signature$ field is not just the signature of the whole message but varies depending on the message type. This signature is used for the consensus protocol, especially for $\mathsf{Validation}$ and $\mathsf{Ratification}$ messages, whose signature is used to prove the vote and, if a quorum is reached, to certify the quorum in an iteration. +The $Signature$ field is not just the signature of the whole message but varies depending on the message type. This signature is used for the consensus protocol, especially for `Validation` and `Ratification` messages, whose signature is used to prove the vote and, if a quorum is reached, to certify the quorum in an iteration. ### Messages -#### Candidate -The $\mathsf{Candidate}$ message is used by a block generator to broadcast a candidate block. +#### `Candidate` +The `Candidate` message is used by a block generator to broadcast a candidate block. The message has the following structure: | Field | Type | Size | Description | |-----------------|-----------------------|-----------|-----------------| -| $ConsensusInfo$ | [ConsensusInfo][cinf] | 48 bytes | Consensus info | -| $Candidate$ | [Block][b] | | Candidate block | -| $SignInfo$ | [SignInfo][sinf] | 144 bytes | Signature info | +| $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | +| $Candidate$ | [`Block`][b] | | Candidate block | +| $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | -The $\mathsf{Candidate}$'s *signature value* $\upsilon_\mathcal{M^C}$ is: +The `Candidate`'s *signature value* $\upsilon_\mathcal{M^C}$ is: $$\upsilon_\mathcal{M^C} = (ConsensusInfo || \eta_{Candidate})$$ -The $\mathsf{Candidate}$ message has a variable size of 192 bytes plus the block size. +The `Candidate` message has a variable size of 192 bytes plus the block size. -#### Validation -The $\mathsf{Validation}$ message is used by a member of a [Validation][val] committee to cast a vote on a candidate block. +#### `Validation` +The `Validation` message is used by a member of a [Validation][val] committee to cast a vote on a candidate block. The message has the following structure: | Field | Type | Size | Description | |-----------------|-----------------------|-----------|-----------------| -| $ConsensusInfo$ | [ConsensusInfo][cinf] | 48 bytes | Consensus info | -| $VoteInfo$ | [VoteInfo][vinf] | 33 byte | Validation vote | -| $SignInfo$ | [SignInfo][sinf] | 144 bytes | Signature info | +| $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | +| $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Validation vote | +| $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | In this message, $Vote$ (part of $VoteInfo$) can be $Valid$, $Invalid$, or $NoCandidate$. -The $\mathsf{Validation}$'s *signature value* $\upsilon_\mathcal{M^V}$ is: +The `Validation`'s *signature value* $\upsilon_\mathcal{M^V}$ is: $$\upsilon_\mathcal{M^V} = (ConsensusInfo || VoteInfo || ValStep)$$ -The $\mathsf{Validation}$ message has a total size of 225 bytes. +The `Validation` message has a total size of 225 bytes. -#### Ratification -The $\mathsf{Ratification}$ message is used by a member of a [Ratification][rat] committee to cast a vote on a candidate block. +#### `Ratification` +The `Ratification` message is used by a member of a [Ratification][rat] committee to cast a vote on a candidate block. The message has the following structure: | Field | Type | Size | Description | |-------------------|-----------------------|-----------|-----------------------------| -| $ConsensusInfo$ | [ConsensusInfo][cinf] | 48 bytes | Consensus info | -| $VoteInfo$ | [VoteInfo][vinf] | 33 byte | Ratification vote | -| $ValidationVotes$ | [StepVotes][sv] | 56 byte | Aggregated Validation votes | +| $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | +| $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Ratification vote | +| $ValidationVotes$ | [`StepVotes`][sv] | 56 byte | Aggregated Validation votes | | $Timestamp$ | Unsigned Integer | 64 bits | Timestamp in Unix format | -| $SignInfo$ | [SignInfo][sinf] | 144 bytes | Signature info | +| $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | In this message, $Vote$ (part of $VoteInfo$) can be $NoCandidate$, $Valid$, $Invalid$, or $NoQuorum$. The $Timestamp$ field is reserved for a future feature. -The $\mathsf{Ratification}$'s *signature value* $\upsilon_\mathcal{M^R}$ is: +The `Ratification`'s *signature value* $\upsilon_\mathcal{M^R}$ is: $$\upsilon_\mathcal{M^R} = (ConsensusInfo || VoteInfo || RatStep)$$ -The $\mathsf{Ratification}$ message has a total size of 281 bytes. +The `Ratification` message has a total size of 281 bytes. -#### Quorum -The $\mathsf{Quorum}$ message is used at the end of a successful SA iteration to communicate to the network that a quorum of votes has been reached. The message is generated by any node collecting a quorum of votes for Ratification. The payload includes the $Attestation$ with votes from both Validation and Ratification steps. +#### `Quorum` +The `Quorum` message is used at the end of a successful SA iteration to communicate to the network that a quorum of votes has been reached. The message is generated by any node collecting a quorum of votes for Ratification. The payload includes the `Attestation` with votes from both [Validation][val] and [Ratification][rat] steps. | Field | Type | Size | Description | |-----------------|-----------------------|-----------|-----------------------| -| $ConsensusInfo$ | [ConsensusInfo][cinf] | 48 bytes | Consensus info | -| $VoteInfo$ | [VoteInfo][vinf] | 33 byte | Quorum vote | -| $Attestation$ | [Attestation][att] | 112 bytes | Iteration attestation | +| $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | +| $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Quorum vote | +| $Attestation$ | [`Attestation`][att] | 112 bytes | Iteration attestation | -Note that the $\mathsf{Quorum}$ message is not signed, since the $Attestation$ is already made of aggregated signatures, which can be verified against the $ConsensusInfo$ and the $VoteInfo$. As a consequence, any node of the network can broadcast this message, when collecting a quorum of Ratification votes. +Note that the `Quorum` message is not signed, since the $Attestation$ is already made of aggregated signatures, which can be verified against the $ConsensusInfo$ and the $VoteInfo$. As a consequence, any node of the network can broadcast this message, when collecting a quorum of Ratification votes. -The $\mathsf{Quorum}$ message has a total size of 249 bytes. +The `Quorum` message has a total size of 249 bytes. -#### Block +#### `Block` -The $\mathsf{Block}$ message is used to propagate a winning block to other peers. -This message only contains a full block structure ([Block][b]) including an Attestation. +The `Block` message is used to propagate a winning block to other peers. +This message only contains a full block structure ([`Block`][b]) including an Attestation. #### Sync messages The following messages are used to synchronize the node with other peers: @@ -193,10 +193,10 @@ While the underlying network protocol is described in the [Network][net] section We define a common *Msg* procedure, which is used to create a consensus message: $Msg(\mathsf{T}, f_1,\dots,f_2):$ -1. $ConsensusInfo = (\eta_{Tip}, R, I)$ +1. $\mathsf{ConsensusInfo} = (\eta_{Tip}, R, I)$ 2. $\sigma_{M^T} = Sign_{BLS}(\upsilon_\mathsf{M^T}, sk_\mathcal{N})$ -3. $SignInfo = (pk_\mathcal{N}, \sigma_{M^T})$ -4. $\mathsf{M^T} = (ConsensusInfo, f_1, \dots, f_n, SignInfo)$ +3. $\mathsf{SignInfo} = (pk_\mathcal{N}, \sigma_{M^T})$ +4. $\mathsf{M^T} = (\mathsf{ConsensusInfo}, f_1, \dots, f_n, SignInfo)$ 5. $\texttt{output } \mathsf{M^T}$ The procedure uses the local consensus parameters ($Tip$, $R$, and $I$) and the node secret key $sk_\mathcal{N}$ to generate the message header and then builds the message with the other parameters $(f_1,\dots,f_2)$. diff --git a/consensus/notation/README.md b/consensus/notation/README.md index 47ed09e..140c9d8 100644 --- a/consensus/notation/README.md +++ b/consensus/notation/README.md @@ -1,14 +1,13 @@ # Notation - In this documentation we will use the following notation: - $Latex$ is used for: - variables, with lowercase letters (e.g. a variable $v$) - simple objects, with uppercase letters (e.g. a committee $C$) - consensus parameters, state variables, and object fields, with whole words, (e.g. the $Epoch$ parameter) -- $\boldsymbol{Bold}$ is used for vectors (e.g. a bitset $\boldsymbol{bs}$) +- $\boldsymbol{Bold}$ is used for arrays (e.g. a bitset $\boldsymbol{bs}$) - $\mathcal{Calligrafic}$ is used for actors (e.g. a provisioner $\mathcal{P}$) -- $\mathsf{Sans Serif}$ is used for structures (e.g. a block $\mathsf{B}$, or a $\mathsf{Candidate}$ message) +- Markdown's `code` format is used for structure reference in texts (e.g., the `Block` structure), while $\mathsf{Sans Serif}$ is used for structures in pseudocode (e.g., a $\mathsf{Candidate}$ message) - *Italic* is used for function names (e.g. the *Hash* function) Moreover, we will use the following symbols: @@ -27,7 +26,7 @@ When using the dot notation, we will omit intermediate fields when possible. For We use $\leftarrow$ to assign object fields to separate variables. For instance, $\mathsf{H_B}, \boldsymbol{txs} \leftarrow \mathsf{B}$ will assign $\mathsf{B}.Header$ to $\mathsf{H_B}$, and $B.Transactions$ to $\boldsymbol{txs}$. The assignation follows the field order in the related structure definition. If a field is not needed in the algorithm, we ignore it by assigning it to a null variable $`\_`$. ## Procedure Control -Some procedures (typically containing a loop) are executed concurrently to each other (e.g., as parallel threads). We have these procedures be controlled using the following commands: +Some procedures (typically containing a loop) are executed concurrently (e.g., as parallel threads). We have these procedures be controlled using the following commands: - $\texttt{start}(P)$: initiates the procedure $P$; - $\texttt{stop}(P)$: interrupts the procedure $P$; - $\texttt{restart}(P)$: stops and restart the procedure $P$. diff --git a/consensus/proposal/README.md b/consensus/proposal/README.md index b060ff4..6a60587 100644 --- a/consensus/proposal/README.md +++ b/consensus/proposal/README.md @@ -9,7 +9,7 @@ - [*SelectTransactions*](#selecttransactions) ## Overview -In the Proposal step, each provisioner node first executes the [*Deterministic Sortition*][ds] algorithm to extract the *block generator*. If the node is selected, it creates a new *candidate block*, and broadcasts it using a $\mathsf{Candidate}$ message (see [`Candidate`][cmsg]). +In the Proposal step, each provisioner node first executes the [*Deterministic Sortition*][ds] algorithm to extract the *block generator*. If the node is selected, it creates a new *candidate block*, and broadcasts it using a [`Candidate`][cmsg] message. In this step, all other nodes wait to receive the candidate block until the step timeout expires. If it was generated or received from the network, the step returns the candidate block; otherwise, it returns $NIL$. The step output will then be passed on as input to the [*Validation*][val] step, where a committee of provisioners will verify its validity and vote accordingly. @@ -51,7 +51,7 @@ In the procedure, the node first extracts the *generator* $\mathcal{G}$ with [*E ***Procedure*** -$\textit{Proposal}(R, I)$: +$\textit{ProposalStep}(R, I)$: 1. $\mathcal{G} =$ [*ExtractGenerator*][eg]$(R,I)$ 2. $\texttt{if } (pk_\mathcal{N} = \mathcal{G}):$ 1. $\mathsf{B}^c =$ [*GenerateBlock*][gb]$(R,I)$ @@ -89,7 +89,7 @@ $\textit{Proposal}(R, I)$: ### *GenerateBlock* *GenerateBlock* creates a candidate block for round $R$ and iteration $I$ by selecting a set of transactions from the Mempool and executing them to obtain the new state $S$. -It is called by [*ProposalStep*][props], which will broadcast the returned block in a $\mathsf{Candidate}$ message. +It is called by [*ProposalStep*][props], which will broadcast the returned block in a `Candidate` message. ***Parameters*** - [SA Environment][env] @@ -107,7 +107,7 @@ It is called by [*ProposalStep*][props], which will broadcast the returned block ***Procedure*** -$GenerateBlock(R,I)$ +$\textit{GenerateBlock}(R,I)$ 1. $`\boldsymbol{txs} = [tx_1, \dots, tx_n] = `$ [*SelectTransactions*][st]$()$ 2. $State_R =$ [*ExecuteStateTransition*][xt]$`(State_{R-1}, \boldsymbol{txs}, BlockGas,pk_\mathcal{N})`$ 3. $`TxRoot_R = MerkleTree(\boldsymbol{txs}).Root`$ diff --git a/consensus/ratification/README.md b/consensus/ratification/README.md index d220dc3..821bb32 100644 --- a/consensus/ratification/README.md +++ b/consensus/ratification/README.md @@ -1,7 +1,7 @@ # Ratification *Ratification* is the third step in an [*SA iteration*][sai]. In this step, the result of the [Validation][val] step is agreed upon by another committee of randomly chosen provisioners. -Members of the extracted committee cast a vote with the output of the [Validation][val] step as resulting from the $\mathsf{Validation}$ messages received. At the same time, all provisioners, including committee members, collect Ratification votes from the network until a target quorum is reached or the step timeout expires. +Members of the extracted committee cast a vote with the output of the [Validation][val] step as resulting from the `Validation` messages received. At the same time, all provisioners, including committee members, collect Ratification votes from the network until a target quorum is reached or the step timeout expires. If a quorum is reached for any result, a [`Quorum`][qmsg] message is generated with the aggregated signatures of both Validation and Ratification steps. Since the attestation proves a candidate reached a quorum, receiving this message is sufficient to accept the candidate into the local chain. @@ -18,15 +18,15 @@ The main purpose of the Ratification step is to ensure provisioners are "aligned In the Ratification step, each node first executes the [*Deterministic Sortition*][ds] algorithm to extract the [Voting Committee][vc] for the step. If the node is part of the committee, it casts a vote with the winning [Validation][val] vote ($Valid$, $Invalid$, $NoCandidate$, $NoQuorum$). -The vote is broadcast using a $\mathsf{Ratification}$ message (see [`Ratification`][rmsg]), which includes the $\mathsf{StepVotes}$ of the aggregated Validation votes. +The vote is broadcast using a [`Ratification`][rmsg] message, which includes the `StepVotes` of the aggregated Validation votes. Then, all nodes, including the committee members, collect votes from the network until a *supermajority* ($\frac{2}{3}$ of the committee credits) of $Valid$ votes is reached, a *majority* ($\frac{1}{2}{+}1$) of $\text{non-}Valid$ votes is reached, or the step timeout expires. -Ratification votes (except for $NoQuorum$) are only considered valid if accompanied by a $\mathsf{StepVotes}$ with a quorum of matching Validation votes. +Ratification votes (except for $NoQuorum$) are only considered valid if accompanied by a [`StepVotes`][sv] with a quorum of matching Validation votes. Note that, since Ratification votes require a quorum of Validation votes (except for $NoQuorum$) to be valid, only one vote between $Valid$, $Invalid$, and $NoCandidate$ can be received, plus $NoQuorum$. In other words, $Valid$, $Invalid$, and $NoCandidate$ are mutually exclusive in Ratification. In fact, it's impossible to receive a valid $NoCandidate$ vote (which requires a majority) and $Valid$ vote in the same Ratification step, unless a provisioner casts a double vote[^1]. If any quorum is reached, the step outputs the winning vote ($Valid$, $Invalid$, $NoCandidate$). Otherwise, if the step timeout expires, the step outputs $NoQuorum$. -In all cases, except $NoQuorum$, the output of the step includes a $\mathsf{StepVotes}$ structure (see [`StepVotes`][sv]) with the aggregated votes that determined the result. +In all cases, except $NoQuorum$, the output of the step includes a [`StepVotes`][sv] structure with the aggregated votes that determined the result. The output, together with the Validation output, will be used to determine the outcome of the iteration. @@ -38,9 +38,9 @@ The output, together with the Validation output, will be used to determine the o The procedure performs two tasks: -1. If the node is part of the Ratification committee $\mathcal{C}$, it broadcasts a $\mathsf{Ratification}$ message with the Validation result $(v^V, \mathsf{SV}_{v^V})$. +1. If the node is part of the Ratification committee $\mathcal{C}$, it broadcasts a `Ratification` message with the Validation result $(v^V, \mathsf{SV}_{v^V})$. -2. It collects $\mathsf{Ratification}$ messages from all committee members, and sets the result depending on the votes: +2. It collects `Ratification` messages from all committee members, and sets the result depending on the votes: - if $Valid$ votes reach $Supermajority$, the step outputs $Valid$; - if $Invalid$ votes reach $Majority$, the step outputs $Invalid$; - if $NoCandidate$ votes reach $Majority$, the step outputs $NoCandidate$; diff --git a/consensus/validation/README.md b/consensus/validation/README.md index 4eb2fc7..7744fa2 100644 --- a/consensus/validation/README.md +++ b/consensus/validation/README.md @@ -15,7 +15,7 @@ In the Validation step, each node first executes the [*Deterministic Sortition*] If the node is part of the committee, it validates the output from the [Proposal][prop] step. If the output was $NIL$, it votes $NoCandidate$. Otherwise, it verifies the candidate block's validity against its previous block (i.e., the node's local $Tip$). If the candidate is valid, the node votes $Valid$, otherwise, it votes $Invalid$. $\text{Non-}Valid$ outputs are used to prove an iteration failed (i.e., it can't reach a quorum of $Valid$ votes), which is functional to block [*Attestation*][fin]; additionally, these votes are used for [slashing][sla]. -The vote is broadcast using a $\mathsf{Validation}$ message (see [`Validation`][vmsg]). +The vote is broadcast using a [`Validation`][vmsg] message. Then, all nodes, including the committee members, collect votes from the network until a *supermajority* ($\frac{2}{3}$ of the committee credits[^1]) of $Valid$ votes is reached, a *majority* ($\frac{1}{2}{+}1$) of $\text{non-}Valid$ votes is reached, or the step timeout expires. Specifically, if a supermajority of $Valid$ votes is received, the step outputs $Valid$; if a majority of $Invalid$ or $NoCandidate$ votes is received, the step outputs $Invalid$ or $NoCandidate$, respectively. @@ -23,7 +23,7 @@ Note that, while $\frac{1}{3}{+}1$ of $Invalid$ or $NoCandidate$ votes would be If the step timeout expires, the step outputs $NoQuorum$, which represents an unknown result: it is possible that casted votes reach a quorum or a majority but the node did not see it. -In all cases, except $NoQuorum$, the output of the step includes a $\mathsf{StepVotes}$ structure (see [`StepVotes`][sv]) with the aggregated votes that determined the result. +In all cases, except $NoQuorum$, the output of the step includes a [`StepVotes`][sv] structure with the aggregated votes that determined the result. The step output will be used as the input for the [Ratification][rat] step. @@ -34,9 +34,9 @@ The step output will be used as the input for the [Ratification][rat] step. The procedure performs two tasks: -1. If the node is part of the Validation committee $\mathcal{C}$, it verifies the candidate $\mathsf{B}^c$ and broadcasts a $\mathsf{Validation}$ message with its vote: $Valid$ if $\mathsf{B}^c$ is a valid successor of the local $Tip$, $Invalid$ if it's not, and $NoCandidate$ if it's $NIL$ (no candidate has been received). +1. If the node is part of the Validation committee $\mathcal{C}$, it verifies the candidate $\mathsf{B}^c$ and broadcasts a [`Validation`][vmsg] message with its vote: $Valid$ if $\mathsf{B}^c$ is a valid successor of the local $Tip$, $Invalid$ if it's not, and $NoCandidate$ if it's $NIL$ (no candidate has been received). -2. It collects $\mathsf{Validation}$ messages from all committee members, and sets the result depending on the votes: +2. It collects `Validation` messages from all committee members, and sets the result depending on the votes: - if $Valid$ votes reach $Supermajority$, the step outputs $Valid$; - if $Invalid$ votes reach $Majority$, the step outputs $Invalid$; - if $NoCandidate$ votes reach $Majority$, the step outputs $NoCandidate$; From 5bf04a755e0fa43e26ef1aebc8db504ad26bd3c7 Mon Sep 17 00:00:00 2001 From: Federico Franzoni <8609060+fed-franz@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:40:44 +0100 Subject: [PATCH 2/3] Update procedure text --- consensus/README.md | 40 ++++++++++---------- consensus/basics/README.md | 18 ++++----- consensus/chain-management/README.md | 36 +++++++++--------- consensus/messages/README.md | 56 +++++++++++++++------------- consensus/notation/README.md | 6 ++- consensus/proposal/README.md | 6 +-- consensus/ratification/README.md | 2 +- consensus/validation/README.md | 2 +- 8 files changed, 87 insertions(+), 79 deletions(-) diff --git a/consensus/README.md b/consensus/README.md index 7aaa2fc..6fd196e 100644 --- a/consensus/README.md +++ b/consensus/README.md @@ -104,7 +104,7 @@ With $Step = Proposal, Validation, Ratification$ ### Procedures #### *SetRoundTimeouts* -Set the initial step timeout for all steps +This procedure sets the initial step timeout for all steps $\textit{SetRoundTimeouts}()$ - $\texttt{for } Step \texttt{ in } [Proposal, Validation, Ratification] :$ @@ -112,7 +112,7 @@ $\textit{SetRoundTimeouts}()$ - $\tau_{Step} = BaseTimeout_{Step}$ #### *StoreElapsedTime* -*StoreElapsedTime* adds a new elapsed time to $ElapsedTimes_{Step}$. +This procedure adds a new elapsed time to $ElapsedTimes_{Step}$. $ElapsedTimes$ storage is a queue structure with a max capacity of $MaxElapsedTimes$. As such, if there are $MaxElapsedTimes$ values stored, when a new value is inserted, the oldest one is removed. $\textit{StoreElapsedTime}(Step, \tau_{Elapsed})$ @@ -121,7 +121,7 @@ $\textit{StoreElapsedTime}(Step, \tau_{Elapsed})$ - $ElapsedTimes_{Step}.push(\tau_{Elapsed})$ #### *AdjustBaseTimeout* -*AdjustBaseTimeout* adjusts the first-iteration timeout for step $Step$ based on the stored elapsed time values. +This procedure adjusts the first-iteration timeout for step $Step$ based on the stored elapsed time values. The new timeout is the rounded-up average value of the stored elapsed times. ***Parameters*** @@ -137,7 +137,7 @@ $\textit{AdjustBaseTimeout}(Step):$ 2. $BaseTimeout_{Step} =$ *Max*$(AvgElapsed, MinStepTimeout)$ #### *IncreaseTimeout* -*IncreaseTimeout* increases a step timeout by $TimeoutIncrease$ seconds up to $MaxStepTimeout$. +This procedure increases a step timeout by $TimeoutIncrease$ seconds up to $MaxStepTimeout$. ***Parameters*** - $Step$: the step timeout @@ -167,12 +167,12 @@ Note that multiple nodes owned by Dusk can produce the exact same block, since i ### Procedures #### *BroadcastEmergencyBlock* -*BroadcastEmergencyBlock* creates a block $\mathsf{B}$ with no transactions and signed with the private $DuskKey$. +This procedure creates a block $\mathsf{B}$ with no transactions and signed with the private $DuskKey$. #### *isEmergencyBlock* -*isEmergencyBlock* outputs $true$ if the input block $\mathsf{B}$ is a valid Emergency Block. +This procedure outputs $true$ if the input block $\mathsf{B}$ is a valid Emergency Block. -$`\textit{*isEmergencyBlock*}(\mathsf{B})`$ +$`\textit{isEmergencyBlock}(\mathsf{B})`$ - $\texttt{if} (\mathsf{B}.Iteration = MaxIterations)$ - $\texttt{and} (\mathsf{B}.Transactions = NIL)$ - $\texttt{and} (\mathsf{B}.Generator = DuskKey):$ @@ -231,12 +231,12 @@ All global values (except for the genesis block) refer to version $0$ of the pro ## Procedures The SA consensus is defined by the [*SAInit*][init] procedure, which executes an infinite loop ([*SALoop*][sal]) of rounds ([*SARound*][sar]), each executing one or more iterations ([*SAIteration*][sai]) until a *winning block* ($\mathsf{B}^w$) is produced for the round, becoming the new $Tip$ of the chain ([*AcceptBlock*][ab]). -The consensus loop could be interrupted when receiving a valid $\mathsf{Block}$ (see [*HandleBlock*][hb]) which could trigger the [*fallback*][fal] or [*synchronization*][syn] procedures. +The consensus loop could be interrupted when receiving a valid [`Block`][bmsg] message (see [*HandleBlock*][hb]) which could trigger the [*fallback*][fal] or [*synchronization*][syn] procedures. Similarly, receiving a [`Quorum`][qmsg] message could interrupt a consensus round by accepting a candidate as the new $Tip$ (see [*HandleQuorum*][hq]). ### *SAInit* -*SAInit* is the entry point of a consensus node. +This procedure is the entry point of a consensus node. Upon boot, the node checks if there is a local state saved and, if so, loads it. Otherwise, it sets the local $Tip$ to *GenesisBlock*. Then, it probes the network to check if it is in sync or not with the main chain. If not, it starts a synchronization procedure. @@ -270,7 +270,7 @@ $\textit{SAInit}():$


### *SALoop* -*SALoop* executes an infinite loop of consensus rounds ([*SARound*][sar]). +This procedure executes an infinite loop of consensus rounds ([*SARound*][sar]). It is initially started by [*SAInit*][init] but it can be stopped and restarted due to [fallback][fal] or [synchronization][syn]. ***Algorithm*** @@ -289,7 +289,7 @@ $\textit{SALoop}():$


### *SARound* -*SARound* executes a single consensus round. First, it initializes the [*Round State*][cenv] variables; then, it starts the [*HandleQuorum*][hq] process in the background, to handle [`Quorum`][qmsg] messages for the round, and starts executing consensus iterations ([*SAIteration*][sai]). +This procedure executes a single consensus round. First, it initializes the [*Round State*][cenv] variables; then, it starts the [*HandleQuorum*][hq] process in the background, to handle [`Quorum`][qmsg] messages for the round, and starts executing consensus iterations ([*SAIteration*][sai]). If, at any time, a winning block $\mathsf{B}^w$ is produced, as the result of a successful iteration or due to a `Quorum` message, it is accepted to the [local chain][lc] and the round ends. If, for any reason, the round ends without a winning block, the consensus is deemed unsafe and the whole protocol is halted. Such an event requires a manual recovery procedure. @@ -338,7 +338,7 @@ $\textit{SARound}():$


### *SAIteration* -*SAIteration* executes the sequence of [*Proposal*][prop], [*Validation*][val], and [*Ratification*][rat] steps. +This procedure executes the sequence of [*Proposal*][prop], [*Validation*][val], and [*Ratification*][rat] steps. The *Proposal* outputs the candidate block $\mathsf{B}^c$ for the iteration; this is passed to *Validation*, which, if a quorum is reached, outputs the aggregated Validation votes $\mathsf{SV}^V$; these are passed to *Ratification*, which, if a quorum is reached, outputs the aggregated Ratification votes $\mathsf{SV}^R$. If a quorum was reached in both Validation and Ratification, a `Quorum` message is broadcast with the [`Attestation`][atts] of the iteration (i.e. the two `StepVotes` $\mathsf{SV}^V$ and $\mathsf{SV}^R$). @@ -350,11 +350,11 @@ If a quorum was reached in both Validation and Ratification, a `Quorum` message 4. If Ratification reached a quorum on $v$: 1. Create an attestation $\mathsf{A}$ with the Validation and Ratification votes 2. Set vote to $(v, \eta_{\mathsf{B}^c})$ - 3. Create $\mathsf{Quorum}$ message $\mathsf{M}^\mathsf{Q}$ - 4. Broadcast $\mathsf{M}^\mathsf{Q}$ - 5. If the Ratification result is $Success$: + 1. Create $\mathsf{Quorum}$ message $\mathsf{M^Q}$ + 3. Broadcast $\mathsf{M^Q}$ + 4. If the Ratification result is $Success$: 1. Make $\mathsf{B}^c$ the winning block [*MakeWinning*][mw] - 6. If the Ratification result is $Fail$ + 5. If the Ratification result is $Fail$ 1. Add $\mathsf{A}$ to the $\boldsymbol{FailedAttestations}$ list ***Procedure*** @@ -368,7 +368,7 @@ $\textit{SAIteration}(R, I):$ 4. $\texttt{if } (v \ne NoQuorum):$ 1. $\mathsf{A} = ({\mathsf{SV}^V, \mathsf{SV}^R})$ 2. $\mathsf{VI} = (v, \eta_{\mathsf{B}^c})$ - 3. $\mathsf{M}^\mathsf{Q} =$ [*Msg*][msg]$(\mathsf{Quorum}, \mathsf{VI}, \mathsf{A})$ + 3. $\mathsf{M^Q} =$ [*Msg*][msg]$(\mathsf{Quorum}, \mathsf{VI}, \mathsf{A})$ | Field | Value | |-----------------|-----------------------| | $PrevHash$ | $\eta_{Tip}$ | @@ -377,7 +377,7 @@ $\textit{SAIteration}(R, I):$ | $Vote$ | $v$ | | $CandidateHash$ | $\eta_{\mathsf{B}^c}$ | | $Attestation$ | $\mathsf{A}$ | - 4. [*Broadcast*][mx]$(\mathsf{M}^\mathsf{Q})$ + 4. [*Broadcast*][mx]$(\mathsf{M^Q})$ 5. $\texttt{if } (v = Success):$ 1. [*MakeWinning*][mw]$(\mathsf{B}^c, \mathsf{A})$ 6. $\texttt{else}:$ @@ -386,7 +386,7 @@ $\textit{SAIteration}(R, I):$


### *GetQuorum* -*GetQuorum* returns the quorum target depending on the vote $v$ +This procedure returns the quorum target depending on the vote $v$ ***Parameters*** - $v$: the vote type ($Valid$, $Invalid$, $NoCandidate$, $NoQuorum$) @@ -398,7 +398,7 @@ $\textit{GetQuorum}(v):$ - $\texttt{else}: \texttt{output } Majority$ ### *GetStepNum* -*GetStepNum* returns the absolute step number within the round. It is used for the [*DS*][ds] procedure. +This procedure returns the absolute step number within the round. It is used for the [*DS*][ds] procedure. ***Parameters*** - $I$: the iteration number diff --git a/consensus/basics/README.md b/consensus/basics/README.md index 667843e..fdc99af 100644 --- a/consensus/basics/README.md +++ b/consensus/basics/README.md @@ -157,7 +157,7 @@ Note that a 64-bit bitset is enough to represent the maximum number of members i ### Procedures #### *ExtractGenerator* -*ExtractGenerator* extracts the block generator for the [Proposal][prop] step of round $R$ and iteration $I$ using the [*Deterministic Sortition*][ds] procedure. +This procedure extracts the block generator for the [Proposal][prop] step of round $R$ and iteration $I$ using the [*Deterministic Sortition*][ds] procedure. ***Parameters*** - $R$: round number @@ -177,7 +177,7 @@ $\textit{ExtractGenerator}(R,I)$ #### *ExtractCommittee* -*ExtractGenerator* extracts the voting committee for the [Validation][val] or the [Ratification][rat] step of round $R$ and iteration $I$ using the [*Deterministic Sortition*][ds] procedure. +This procedure extracts the voting committee for the [Validation][val] or the [Ratification][rat] step of round $R$ and iteration $I$ using the [*Deterministic Sortition*][ds] procedure. The procedure excludes the block generator $\mathcal{G}$ of the same iteration to prevent it from being part of the committee. In other words, a candidate generator cannot vote over its own block. @@ -204,12 +204,12 @@ $\textit{ExtractCommittee}(R,I, StepNum)$ #### *BitSet* -*BitSet* takes a committee $C$ and list of provisioners $\boldsymbol{P}$, and outputs the bitset corresponding to the subcommittee of $C$ including provisioners in $\boldsymbol{P}$. +This procedure takes a committee $C$ and list of provisioners $\boldsymbol{P}$, and outputs the bitset corresponding to the subcommittee of $C$ including provisioners in $\boldsymbol{P}$. $\textit{BitSet}(C, \boldsymbol{P}=[pk_1,\dots,pk_n]) \rightarrow \boldsymbol{bs}_{\boldsymbol{P}}^C$ #### *SetBit* -*SetBit* sets a committee member's bit in a subcommittee bitset. +This procedure sets a committee member's bit in a subcommittee bitset. ***Parameters*** - $\boldsymbol{bs}$: the subcommittee bitset @@ -222,17 +222,17 @@ $\textit{BitSet}(C, \boldsymbol{P}=[pk_1,\dots,pk_n]) \rightarrow \boldsymbol{bs - $\boldsymbol{bs}[i_M^\mathcal{C}] = 1$ #### *CountSetBits* -*CountSetBits* returns the amount of set bits in a bitset. +This procedure returns the amount of set bits in a bitset. $\textit{CountSetBits}(\boldsymbol{bs}) \rightarrow setbits$ #### *SubCommittee* -$SubCommittee$ takes a committee $C$ and a bitset $\boldsymbol{bs}^C$ and outputs the corresponding subcommittee. +This procedure takes a committee $C$ and a bitset $\boldsymbol{bs}^C$ and outputs the corresponding subcommittee. -$SubCommittee(C, \boldsymbol{bs}^C) \rightarrow \boldsymbol{P}=[pk_1,\dots,pk_n]$ +$\textit{SubCommittee}(C, \boldsymbol{bs}^C) \rightarrow \boldsymbol{P}=[pk_1,\dots,pk_n]$ #### *CountCredits* -*CountCredits* takes a committee $\mathcal{C}$ and a bitset $\boldsymbol{bs}$ and returns the cumulative amount of credits belonging to members of the subcommittee with respect to $\mathcal{C}$. +This procedure takes a committee $\mathcal{C}$ and a bitset $\boldsymbol{bs}$ and returns the cumulative amount of credits belonging to members of the subcommittee with respect to $\mathcal{C}$. ***Parameters*** - $\mathcal{C}$: a voting committee @@ -292,7 +292,7 @@ $Vote$ can be $Valid$, $Invalid$, $NoCandidate$, or $NoQuorum$. ### Procedures #### *AggregateVote* -*AggregateVote* adds a vote to a [`StepVotes`][sv] by aggregating the BLS signature and setting the signer bit in the committee bitset. +This procedure adds a vote to a [`StepVotes`][sv] by aggregating the BLS signature and setting the signer bit in the committee bitset. **Parameters** - $\mathsf{SV}$: the $\mathsf{StepVotes}$ structure with the aggregated votes diff --git a/consensus/chain-management/README.md b/consensus/chain-management/README.md index 1ede951..ff8e06c 100644 --- a/consensus/chain-management/README.md +++ b/consensus/chain-management/README.md @@ -132,7 +132,7 @@ $\textit{GetBlockState}(\mathsf{B}):$ #### *CheckRollingFinality* -*CheckRollingFinality* checks if the last $RollingFinality$ blocks are all "Attested" and, if so, finalizes all non-final blocks. +This procedure checks if the last $RollingFinality$ blocks are all "Attested" and, if so, finalizes all non-final blocks. ***Procedure*** $\textit{CheckRollingFinality}():$ @@ -141,7 +141,7 @@ $\textit{CheckRollingFinality}():$ 1. *MakeChainFinal*$()$ #### *HasRollingFinality* -*HasRollingFinality* outputs true if the last $RollingFinality$ are all Attested and false otherwise. +This procedure outputs true if the last $RollingFinality$ are all Attested and false otherwise. ***Procedure*** $\textit{HasRollingFinality}():$ @@ -152,7 +152,7 @@ $\textit{HasRollingFinality}():$ 2. $\texttt{output } true$ #### *MakeChainFinal* -*MakeChainFinal* set to "Final" the state of all non-final blocks in $\textbf{Chain}$ +This procedure set to "Final" the state of all non-final blocks in $\textbf{Chain}$ @@ -162,7 +162,7 @@ We here define the procedures to verify the validity of a block: [*VerifyBlock*] ### Procedures #### *VerifyBlock* -The *VerifyBlock* procedure verifies a block is a valid successor of another block $\mathsf{B}^p$ (commonly, the $Tip$) and contains a valid Attestation. If both conditions are met, it returns $true$, otherwise, it returns $false$. +This procedure verifies a block is a valid successor of another block $\mathsf{B}^p$ (commonly, the $Tip$) and contains a valid Attestation. If both conditions are met, it returns $true$, otherwise, it returns $false$. If the block is an [Emergency Block][eb], the block $Attestation$ and $FailedIterations$ are not verified. @@ -177,7 +177,7 @@ If the block is an [Emergency Block][eb], the block $Attestation$ and $FailedIte 4. If $\mathsf{A}^p$ is not valid, output $false$ 5. If $\mathsf{B}$ is an Emergency Block 1. Output $true$ -6. Verify $\mathsf{B}$'s attestation $\mathsf{A}_\mathsf{B}$ ([*VerifyAttestation*][va]) +6. Verify $\mathsf{B}$'s attestation $\mathsf{A_B}$ ([*VerifyAttestation*][va]) 7. If attestation is not valid, output $false$ 8. For each attestation $\mathsf{A}_i$ in $FailedIterations$ 1. Verify $\mathsf{A}_i$ ([*VerifyAttestation*][va]) @@ -209,7 +209,7 @@ $\textit{VerifyBlock}(\mathsf{B}):$ 9. $\texttt{output } true$ #### *VerifyBlockHeader* -*VerifyBlockHeader* returns $true$ if all block header fields are valid with respect to the previous block and the included transactions. If so, it outputs $true$, otherwise, it outputs $false$. +This procedure returns $true$ if all block header fields are valid with respect to the previous block and the included transactions. If so, it outputs $true$, otherwise, it outputs $false$. ***Parameters*** - $\mathsf{B}$: block to verify @@ -245,7 +245,7 @@ $\textit{VerifyBlockHeader}(\mathsf{B}, \mathsf{B}^p)$: #### *VerifyAttestation* -*VerifyAttestation* checks a block's Attestation by verifying the [Validation][val] and [Ratification][rat] aggregated signatures against the respective committees. +This procedure checks a block's Attestation by verifying the [Validation][val] and [Ratification][rat] aggregated signatures against the respective committees. ***Parameters*** - $\mathsf{A}$: the attestation to verify @@ -279,7 +279,7 @@ $\textit{VerifyAttestation}(\mathsf{A}, \upsilon):$ 6. $\texttt{output } true$ #### *VerifyVotes* -*VerifyVotes* checks the aggregated votes are valid and reach the target quorum. +This procedure checks the aggregated votes are valid and reach the target quorum. ***Parameters*** - $\mathsf{SV}$: $\mathsf{StepVotes}$ with the aggregated votes @@ -324,7 +324,7 @@ We here define block-management procedures: ### Procedures #### *HandleBlock* -The *HandleBlock* procedure processes a full block received from the network and decides whether to trigger the synchronization or fallback procedures. +This procedure processes a full block received from the network and decides whether to trigger the synchronization or fallback procedures. The procedure acts depending on the block's height: if the block has the same height as a local chain block, but it has lower $Iteration$, it starts the [*Fallback*][fal] procedure; if the block's height is more than $Tip.Height+1$, it executes the [*SyncBlock*][sb] is executed to start or continue the synchronization process. ***Parameters*** @@ -375,7 +375,7 @@ $\textit{HandleBlock}():$ 4. $\texttt{start}($[*SALoop*][sl]$)$ #### *HandleQuorum* -*HandleQuorum* manages `Quorum` messages for the current round $R$. If the message was received from the network, it is first verified ([*VerifyQuorum*][vq]) and then propagated. +This procedure manages `Quorum` messages for the current round $R$. If the message was received from the network, it is first verified ([*VerifyQuorum*][vq]) and then propagated. The corresponding candidate block is then marked as the winning block of the round ([*MakeWinning*][mw]). ***Parameters*** @@ -422,7 +422,7 @@ $\textit{HandleQuorum}( R ):$ #### *MakeWinning* -*MakeWinning* adds an attestation to a candidate block and sets the winning block variable $\mathsf{B}^w$. +This procedure adds an attestation to a candidate block and sets the winning block variable $\mathsf{B}^w$. ***Parameters*** - $\mathsf{B}$: candidate block @@ -440,7 +440,7 @@ $\textit{MakeWinning}(\mathsf{B}, \mathsf{A}):$ #### *AcceptBlock* -*AcceptBlock* sets a block $\mathsf{B}$ as the new chain $Tip$. It also updates the local state accordingly by executing all transactions in the block and setting the $Provisioners$ state variable. +This procedure sets a block $\mathsf{B}$ as the new chain $Tip$. It also updates the local state accordingly by executing all transactions in the block and setting the $Provisioners$ state variable. ***Parameters*** - $\mathsf{B}$: the block to accept as the new chain tip @@ -472,7 +472,7 @@ $\textit{AcceptBlock}(\mathsf{B}):$ #### *Fallback* -The *Fallback* procedure takes the hash $\eta$ of a block in the local chain and deletes all blocks from $Tip$ to $\mathsf{B}_\eta$ excluded. +This procedure takes the hash $\eta$ of a block in the local chain and deletes all blocks from $Tip$ to $\mathsf{B}_\eta$ excluded. It is triggered by [*HandleBlock*][hb] when receiving a block with height equal or lower than the local $Tip$ and with lower $Iteration$. @@ -552,7 +552,7 @@ The environment of synchronization procedures includes node-level parameters, co ### Procedures #### *SyncBlock* -The *SyncBlock* procedure handles potential successors of the local $Tip$. The procedure accepts valid $Tip$'s successors and is responsible for initiating ([*StartSync*][ss]) and handling synchronization protocols run with nodes peers. Only one synchronization protocol can be run at a time, and only with a single peer (the *sync peer*). +This procedure handles potential successors of the local $Tip$. The procedure accepts valid $Tip$'s successors and is responsible for initiating ([*StartSync*][ss]) and handling synchronization protocols run with nodes peers. Only one synchronization protocol can be run at a time, and only with a single peer (the *sync peer*). When receiving blocks with higher height than the $Tip$'s successor, they are stored in the $BlockPool$. If receiving a valid $Tip$'s successor, this is accepted along with all valid successors in the $BlockPool$. @@ -628,7 +628,7 @@ $\textit{SyncBlock}(\mathsf{M^B}):$ #### *PreSync* -*PreSync* requests to a peer the successor of $Tip$ to ensure it knows it before starting the synchronization process. This is done to prevent a peer from stopping our consensus loop just by sending a block in the future. When $Tip+1$ is received from $\mathcal{S}$, the synchronization will start ([*StartSync*][ss]). +This procedure requests to a peer the successor of $Tip$ to ensure it knows it before starting the synchronization process. This is done to prevent a peer from stopping our consensus loop just by sending a block in the future. When $Tip+1$ is received from $\mathcal{S}$, the synchronization will start ([*StartSync*][ss]). A timeout $\tau_{Sync}$ is setup to prevent a peer from blocking our node with sync. $syncPeer$ has maximum $PreSyncTimeout$ to send the first block, and $SyncTimeout$ time to send the following ones. With each valid block the timeout is reset (that is, the peer has $SyncTimeout$ time to send each block). @@ -657,7 +657,7 @@ $\textit{PreSync}(\mathsf{B}, \mathcal{S}):$ 6. $\texttt{start}($[*HandleSyncTimeout*][hst]$)$ #### *StartSync* -The *StartSync* procedure initiates the synchronization protocol with $syncPeer$ on the base of the block $syncTo$ previously received from this peer. +This procedure initiates the synchronization protocol with $syncPeer$ on the base of the block $syncTo$ previously received from this peer. While syncing, the [*SALoop*][sl] is kept stopped to improve performance. @@ -672,7 +672,7 @@ $\textit{StartSync}():$ 2. $inSync = false$ #### *HandleSyncTimeout* -The *HandleSyncTimeout* procedure checks if the sync timeout $\tau_{Sync}$ expires when synchronizing or pre-synchronizing with a peer. +This procedure checks if the sync timeout $\tau_{Sync}$ expires when synchronizing or pre-synchronizing with a peer. If the timeout expires while synchronizing, the synchronization is ended and the [*SALoop*][sl] restarted, if needed. If it expires when pre-syncing, the sync information is reset. Only a single synchronization process is done at a time, so $\tau_{Sync}$ is unique. @@ -695,7 +695,7 @@ $\textit{HandleSyncTimeout}():$ #### *AcceptPoolBlocks* -*AcceptPoolBlocks* accepts all successive blocks in $BlockPool$ from height $Tip.Height+1$ until no successor is available. It is called after receiving a valid block at height $Tip.Height+1$ (which updates the $Tip$) to accept previously-collected blocks. +This procedure accepts all successive blocks in $BlockPool$ from height $Tip.Height+1$ until no successor is available. It is called after receiving a valid block at height $Tip.Height+1$ (which updates the $Tip$) to accept previously-collected blocks. ***Algorithm*** 1. Get all successive blocks in $BlockPool$ starting from $Tip$'s successor diff --git a/consensus/messages/README.md b/consensus/messages/README.md index 450ba40..2f63217 100644 --- a/consensus/messages/README.md +++ b/consensus/messages/README.md @@ -61,11 +61,12 @@ The structure's total size is 48 bytes. | $Vote$ | Integer | 1 byte | Validation vote | | $CandidateHash$ | SHA3 | 32 bytes | Candidate block's hash | +The structure's total size is 33 bytes. + $Vote$ can be $NoCandidate$ ($0$), $Valid$ ($1$), $Invalid$ ($2$), or $NoQuorum$ ($3$). When $Vote$ is $NoCandidate$ or $NoQuorum$, $CandidateHash$ is empty. Note that an empty $CandidateHash$ is not included in the [*signature value*][sigs]. -The structure has a total size of 33 bytes. ### Signatures Each message contains a *message signature* (included in the $Signature$ field) which is used to verify the message authenticity but is also functional to prove the reached agreement over a candidate block (see [Attestations][atts]) @@ -91,7 +92,7 @@ With respect to message signatures, we also define the following procedures: | $Signer$ | BLS Key | 96 bytes | Public Key of the message creator | | $Signature$ | BLS Signature | 48 bytes | Message signature | -The structure has a total size of 144 bytes. +The structure's total size is 144 bytes. The $Signer$ field identifies the provisioner sending the message. For instance, in a `Candidate` message, this field identifies the block generator, while, in a `Validation` message, it identifies the committee member who cast the vote. @@ -101,7 +102,7 @@ The $Signature$ field is not just the signature of the whole message but varies ### Messages #### `Candidate` -The `Candidate` message is used by a block generator to broadcast a candidate block. +This message is used by a block generator to broadcast a candidate block. The message has the following structure: @@ -111,14 +112,15 @@ The message has the following structure: | $Candidate$ | [`Block`][b] | | Candidate block | | $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | -The `Candidate`'s *signature value* $\upsilon_\mathcal{M^C}$ is: +The message has a variable size of 192 bytes plus the block size. + +The message's [signature value][sigs] $\upsilon_\mathcal{M^C}$ is: $$\upsilon_\mathcal{M^C} = (ConsensusInfo || \eta_{Candidate})$$ -The `Candidate` message has a variable size of 192 bytes plus the block size. #### `Validation` -The `Validation` message is used by a member of a [Validation][val] committee to cast a vote on a candidate block. +This message is used by a member of a [Validation][val] committee to cast a vote on a candidate block. The message has the following structure: @@ -128,16 +130,17 @@ The message has the following structure: | $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Validation vote | | $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | +The message has a total size of 225 bytes. + In this message, $Vote$ (part of $VoteInfo$) can be $Valid$, $Invalid$, or $NoCandidate$. -The `Validation`'s *signature value* $\upsilon_\mathcal{M^V}$ is: +The message's [signature value][sigs] $\upsilon_\mathcal{M^V}$ is: $$\upsilon_\mathcal{M^V} = (ConsensusInfo || VoteInfo || ValStep)$$ -The `Validation` message has a total size of 225 bytes. #### `Ratification` -The `Ratification` message is used by a member of a [Ratification][rat] committee to cast a vote on a candidate block. +This message is used by a member of a [Ratification][rat] committee to cast a vote on a candidate block. The message has the following structure: | Field | Type | Size | Description | @@ -148,17 +151,18 @@ The message has the following structure: | $Timestamp$ | Unsigned Integer | 64 bits | Timestamp in Unix format | | $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | +The message has a total size of 281 bytes. + In this message, $Vote$ (part of $VoteInfo$) can be $NoCandidate$, $Valid$, $Invalid$, or $NoQuorum$. The $Timestamp$ field is reserved for a future feature. -The `Ratification`'s *signature value* $\upsilon_\mathcal{M^R}$ is: +The message's [signature value][sigs] $\upsilon_\mathcal{M^R}$ is: $$\upsilon_\mathcal{M^R} = (ConsensusInfo || VoteInfo || RatStep)$$ -The `Ratification` message has a total size of 281 bytes. #### `Quorum` -The `Quorum` message is used at the end of a successful SA iteration to communicate to the network that a quorum of votes has been reached. The message is generated by any node collecting a quorum of votes for Ratification. The payload includes the `Attestation` with votes from both [Validation][val] and [Ratification][rat] steps. +This message is used at the end of a successful SA iteration to communicate to the network that a quorum of votes has been reached. The message is generated by any node collecting a quorum of votes for Ratification. The payload includes the `Attestation` with votes from both [Validation][val] and [Ratification][rat] steps. | Field | Type | Size | Description | |-----------------|-----------------------|-----------|-----------------------| @@ -166,24 +170,24 @@ The `Quorum` message is used at the end of a successful SA iteration to communic | $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Quorum vote | | $Attestation$ | [`Attestation`][att] | 112 bytes | Iteration attestation | -Note that the `Quorum` message is not signed, since the $Attestation$ is already made of aggregated signatures, which can be verified against the $ConsensusInfo$ and the $VoteInfo$. As a consequence, any node of the network can broadcast this message, when collecting a quorum of Ratification votes. +The message has a total size of 249 bytes. -The `Quorum` message has a total size of 249 bytes. +Note that this message is not signed, since the $Attestation$ is already made of aggregated signatures, which can be verified against the $ConsensusInfo$ and the $VoteInfo$. As a consequence, any node of the network can broadcast this message, when collecting a quorum of Ratification votes. -#### `Block` -The `Block` message is used to propagate a winning block to other peers. -This message only contains a full block structure ([`Block`][b]) including an Attestation. +#### `Block` +This message is used to propagate a winning block to other peers. +It contains a full block structure ([`Block`][b]) including an Attestation. #### Sync messages The following messages are used to synchronize the node with other peers: -- $\mathsf{GetBlocks}$: request blocks from a peer; +- $\mathsf{GetBlocks}$: requests blocks from a peer; - $\mathsf{Inv}$: advertises blocks or transactions by their hash -- $\mathsf{GetData}(T, data)$: request blocks by their hash or height, or transactions by their hash +- $\mathsf{GetData}(T, data)$: requests blocks by their hash or height, or transactions by their hash - The payload type $T$ can be: $BlockFromHeight$, $BlockFromHash$, or $MempoolTx$ -- $\mathsf{GetCandidate}$: request a candidate block from its hash -- $\mathsf{GetCandidateResp}$: transmit a candidate block in response to $\mathsf{GetCandidate}$ message; +- $\mathsf{GetCandidate}$: requests a candidate block from its hash +- $\mathsf{GetCandidateResp}$: transmits a candidate block in response to $\mathsf{GetCandidate}$ message; ### Procedures @@ -201,17 +205,17 @@ $Msg(\mathsf{T}, f_1,\dots,f_2):$ The procedure uses the local consensus parameters ($Tip$, $R$, and $I$) and the node secret key $sk_\mathcal{N}$ to generate the message header and then builds the message with the other parameters $(f_1,\dots,f_2)$. -We assume the procedure is able to automatically generate $\upsilon_\mathsf{M^T}$ based ont he message type and inputs. +We assume the procedure is able to automatically generate $\upsilon_\mathsf{M^T}$ based on the message type and inputs. $\mathsf{T}$ indicates the message type: $\mathsf{Candidate}$, $\mathsf{Validation}$, $\mathsf{Ratification}$, or $\mathsf{Quorum}$. #### *Broadcast* -The *Broadcast* function is used by the creator of a new message to initiate the network propagation of the message. The function simply takes any consensus message in input and is assumed to not fail (only within the context of this description) so it does not return anything. +This procedure is used by the creator of a new message to initiate the network propagation of the message. The function simply takes any consensus message in input and is assumed to not fail (only within the context of this description) so it does not return anything. Note that, for the sake of readability, broadcast messages are also received by the local node (as in a self-sending). #### *Receive* -We use the *Receive* function to process incoming messages. Specifically, $\textit{Receive}(\mathsf{T},R,I)$ returns a message $\mathsf{M}$ of type $\mathsf{T}$ ($\mathsf{M^T}$) if it was received from the network and it has $Round_\mathsf{M}=R$ and $Iteration_\mathsf{M}=I$. +This procedure is used to process incoming messages. Specifically, $\textit{Receive}(\mathsf{T},R,I)$ returns a message $\mathsf{M}$ of type $\mathsf{T}$ ($\mathsf{M^T}$) if it was received from the network and it has $Round_\mathsf{M}=R$ and $Iteration_\mathsf{M}=I$. If no new message has been received, it returns $NIL$. When not relevant (e.g. with $\mathsf{Block}$ messages) $R$ and $I$ are ignored. @@ -220,12 +224,12 @@ Messages received before calling the *Receive* function are stored in a queue an Note that also messages broadcasted by the node are received by this function. #### *Propagate* -The *Propagate* function represents a re-broadcast operation. It is used by a node when receiving a message from the network and propagating to other nodes. +This procedure represents a re-broadcast operation. It is used by a node when receiving a message from the network and propagating to other nodes. We assume that if the message was originally broadcasted by the local node it is not re-propagated. #### *Send* -The *Send* function represents a point-to-point message from the node to one of its peers. Its defined as *Send*$(\mathcal{P},\mathsf{M})$, where $\mathcal{P}$ is the recipient peer, and $\mathsf{M}$ is the message to send. +This procedure represents a point-to-point message from the node to one of its peers. Its defined as *Send*$(\mathcal{P},\mathsf{M})$, where $\mathcal{P}$ is the recipient peer, and $\mathsf{M}$ is the message to send. diff --git a/consensus/notation/README.md b/consensus/notation/README.md index 140c9d8..4540803 100644 --- a/consensus/notation/README.md +++ b/consensus/notation/README.md @@ -7,7 +7,7 @@ In this documentation we will use the following notation: - consensus parameters, state variables, and object fields, with whole words, (e.g. the $Epoch$ parameter) - $\boldsymbol{Bold}$ is used for arrays (e.g. a bitset $\boldsymbol{bs}$) - $\mathcal{Calligrafic}$ is used for actors (e.g. a provisioner $\mathcal{P}$) -- Markdown's `code` format is used for structure reference in texts (e.g., the `Block` structure), while $\mathsf{Sans Serif}$ is used for structures in pseudocode (e.g., a $\mathsf{Candidate}$ message) +- Markdown's `code` format is used for structure reference in texts (e.g., the `Block` structure), while $\mathsf{Sans Serif}$ is used for structures in pseudocode (e.g., a $\mathsf{Candidate}$ message)[^1] - *Italic* is used for function names (e.g. the *Hash* function) Moreover, we will use the following symbols: @@ -34,3 +34,7 @@ Some procedures (typically containing a loop) are executed concurrently (e.g., a Additionally, we define the function $\texttt{running}(P)$ which outputs $true$ if $P$ is currently running, and $false$ otherwise. When in a $\texttt{loop}$ we use $\texttt{break}$ to stop the execution and move on to the next iteration. + + + +[^1]: This duality is mostly due to limitations in Markdown's formatting diff --git a/consensus/proposal/README.md b/consensus/proposal/README.md index 6a60587..4061d34 100644 --- a/consensus/proposal/README.md +++ b/consensus/proposal/README.md @@ -18,7 +18,7 @@ If it was generated or received from the network, the step returns the candidate ## Procedures ### *ProposalStep* -*ProposalStep* takes in input the round $R$ and the iteration $I$, and outputs the *candidate block* $\mathsf{B}^c$, if it was generated or received, or $NIL$ otherwise. +This procedure takes in input the round $R$ and the iteration $I$, and outputs the *candidate block* $\mathsf{B}^c$, if it was generated or received, or $NIL$ otherwise. It is called by [*SAIteration*][sai], which will pass the result to [*ValidationStep*][val]. In the procedure, the node first extracts the *generator* $\mathcal{G}$ with [*ExtractGenerator*][eg]. If the node is extracted as $\mathcal{G}$, it generates the candidate block $\mathsf{B}^c$ and broadcasts it. Otherwise, it waits the Proposal timeout $\tau_{Proposal}$ to receive the candidate block from the network. If $\mathsf{B}^c$ is received, it outputs it, otherwise, it outputs $NIL$. @@ -88,7 +88,7 @@ $\textit{ProposalStep}(R, I)$:


### *GenerateBlock* -*GenerateBlock* creates a candidate block for round $R$ and iteration $I$ by selecting a set of transactions from the Mempool and executing them to obtain the new state $S$. +This procedure creates a candidate block for round $R$ and iteration $I$ by selecting a set of transactions from the Mempool and executing them to obtain the new state $S$. It is called by [*ProposalStep*][props], which will broadcast the returned block in a `Candidate` message. ***Parameters*** @@ -139,7 +139,7 @@ $\textit{GenerateBlock}(R,I)$


### *SelectTransactions* -*SelectTransactions* selects a set of transactions from the Mempool to be included in a new block. +This procedure selects a set of transactions from the Mempool to be included in a new block. The criteria used for the selection is arbitrary and is left to the Block Generator. Typically, the Generator's strategy will aim at maximizing profits by selecting transactions paying higher gas price. diff --git a/consensus/ratification/README.md b/consensus/ratification/README.md index 821bb32..e8e0c6a 100644 --- a/consensus/ratification/README.md +++ b/consensus/ratification/README.md @@ -34,7 +34,7 @@ The output, together with the Validation output, will be used to determine the o ### Procedures #### *RatificationStep* -*RatificationStep* takes in input the round $R$, the iteration $I$, and the Validation result $\mathsf{SR}^V$ (as returned from [*ValidationStep*][vals]) and outputs the Ratification result $`\mathsf{SR}^R=(v^R, \eta_{\mathsf{B}^c}, \mathsf{SV}_{v^R})`$, where $v^R$ is $Valid$, $Invalid$, $NoCandidate$, or $NoQuorum$, $\eta_{\mathsf{B}^c}$ is the candidate hash, and $\mathsf{SV}_{v^R}$ is the aggregated vote of the quorum committee. +This procedure takes in input the round $R$, the iteration $I$, and the Validation result $\mathsf{SR}^V$ (as returned from [*ValidationStep*][vals]) and outputs the Ratification result $`\mathsf{SR}^R=(v^R, \eta_{\mathsf{B}^c}, \mathsf{SV}_{v^R})`$, where $v^R$ is $Valid$, $Invalid$, $NoCandidate$, or $NoQuorum$, $\eta_{\mathsf{B}^c}$ is the candidate hash, and $\mathsf{SV}_{v^R}$ is the aggregated vote of the quorum committee. The procedure performs two tasks: diff --git a/consensus/validation/README.md b/consensus/validation/README.md index 7744fa2..ff1e733 100644 --- a/consensus/validation/README.md +++ b/consensus/validation/README.md @@ -30,7 +30,7 @@ The step output will be used as the input for the [Ratification][rat] step. ### Procedures #### *ValidationStep* -*ValidationStep* takes in input the round $R$, the iteration $I$, and the candidate block $\mathsf{B}^c$ (as returned by [*ProposalStep*][props]) and outputs the Validation result $`(v^V, \mathsf{SV}_{v^V})`$, where $v^V$ is $Valid$, $Invalid$, $NoCandidate$, or $NoQuorum$, and $\mathsf{SV}_{v^V}$ is the aggregated vote of the quorum committee. +This procedure takes in input the round $R$, the iteration $I$, and the candidate block $\mathsf{B}^c$ (as returned by [*ProposalStep*][props]) and outputs the Validation result $`(v^V, \mathsf{SV}_{v^V})`$, where $v^V$ is $Valid$, $Invalid$, $NoCandidate$, or $NoQuorum$, and $\mathsf{SV}_{v^V}$ is the aggregated vote of the quorum committee. The procedure performs two tasks: From db6fb13409468ed3d90a8cd12f65a1549ab93cbc Mon Sep 17 00:00:00 2001 From: Federico Franzoni <8609060+fed-franz@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:46:45 +0100 Subject: [PATCH 3/3] Update structure text --- consensus/basics/README.md | 6 +++--- consensus/messages/README.md | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/consensus/basics/README.md b/consensus/basics/README.md index fdc99af..75a06cc 100644 --- a/consensus/basics/README.md +++ b/consensus/basics/README.md @@ -253,7 +253,7 @@ We use the terms *Valid Attestation* and *Failed Attestation* to refer to the tw ### Structures #### `Attestation` -The `Attestation` structure contains the aggregated votes of the [Validation][val] and [Ratification][rat] steps of a single iteration. The votes of each step are contained in a [`StepVotes`][sv] structure. +This structure contains the aggregated votes of the [Validation][val] and [Ratification][rat] steps of a single iteration. The votes of each step are contained in a [`StepVotes`][sv] structure. | Field | Type | Size | Description | @@ -264,7 +264,7 @@ The `Attestation` structure contains the aggregated votes of the [Validation][va The structure has a total size of 112 bytes. #### `StepVotes` -The `StepVotes` structure is used to store votes from the [Validation][val] and [Ratification][rat] steps. +This structure is used to store votes from the [Validation][val] and [Ratification][rat] steps. Votes are stored as the aggregated BLS signatures of the members of the two Voting Committees. In fact, each [vote][vot] is signed together with the related *Consensus Information* (round, iteration, step) and the hash of the candidate to which the vote refers. To specify the votes from which committee members included in the aggregated signature, a [sub-committee bitset][bs] is used. @@ -278,7 +278,7 @@ The structure is defined as follows: The structure has a total size of 56 bytes. #### `StepResult` -The `StepResult` structure contains the result of a [Validation][val] or [Ratification][rat] step, that is the step result $Vote$ and the `StepVotes` with the aggregated votes producing $Vote$. +This structure contains the result of a [Validation][val] or [Ratification][rat] step, that is the step result $Vote$ and the `StepVotes` with the aggregated votes producing $Vote$. The structure is defined as follows: diff --git a/consensus/messages/README.md b/consensus/messages/README.md index 2f63217..4e79fef 100644 --- a/consensus/messages/README.md +++ b/consensus/messages/README.md @@ -54,7 +54,7 @@ The `ConsensusInfo` structure is defined as follows: The structure's total size is 48 bytes. #### `VoteInfo` -`VoteInfo` contains the information of a Validation or Ratification vote. +This contains the information of a [Validation][val] or [Ratification][rat] vote. | Field | Type | Size | Description | |-----------------|---------|----------|------------------------| @@ -85,7 +85,7 @@ With respect to message signatures, we also define the following procedures: - $VerifyMessage(\mathsf{M})$: takes a message $\mathsf{M}$ and outputs $true$ if $\sigma_\mathsf{M}$ is a valid signature of $Signer$ over the signature value $\upsilon_\mathsf{M}$. #### `SignInfo` -`SignInfo` contains the public key of the provisioner creating the message and its signature over the message. +This structure contains the public key of the provisioner creating the message and its signature over the message. | Field | Type | Size | Description | |-------------|-------------------|-----------|-----------------------------------| @@ -106,8 +106,8 @@ This message is used by a block generator to broadcast a candidate block. The message has the following structure: -| Field | Type | Size | Description | -|-----------------|-----------------------|-----------|-----------------| +| Field | Type | Size | Description | +|-----------------|-------------------------|-----------|-----------------| | $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | | $Candidate$ | [`Block`][b] | | Candidate block | | $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | @@ -124,8 +124,8 @@ This message is used by a member of a [Validation][val] committee to cast a vote The message has the following structure: -| Field | Type | Size | Description | -|-----------------|-----------------------|-----------|-----------------| +| Field | Type | Size | Description | +|-----------------|-------------------------|-----------|-----------------| | $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | | $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Validation vote | | $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | @@ -143,12 +143,12 @@ $$\upsilon_\mathcal{M^V} = (ConsensusInfo || VoteInfo || ValStep)$$ This message is used by a member of a [Ratification][rat] committee to cast a vote on a candidate block. The message has the following structure: -| Field | Type | Size | Description | -|-------------------|-----------------------|-----------|-----------------------------| +| Field | Type | Size | Description | +|-------------------|-------------------------|-----------|-----------------------------| | $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | | $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Ratification vote | | $ValidationVotes$ | [`StepVotes`][sv] | 56 byte | Aggregated Validation votes | -| $Timestamp$ | Unsigned Integer | 64 bits | Timestamp in Unix format | +| $Timestamp$ | Unsigned Integer | 64 bits | Timestamp in Unix format | | $SignInfo$ | [`SignInfo`][sinf] | 144 bytes | Signature info | The message has a total size of 281 bytes. @@ -164,8 +164,8 @@ $$\upsilon_\mathcal{M^R} = (ConsensusInfo || VoteInfo || RatStep)$$ #### `Quorum` This message is used at the end of a successful SA iteration to communicate to the network that a quorum of votes has been reached. The message is generated by any node collecting a quorum of votes for Ratification. The payload includes the `Attestation` with votes from both [Validation][val] and [Ratification][rat] steps. -| Field | Type | Size | Description | -|-----------------|-----------------------|-----------|-----------------------| +| Field | Type | Size | Description | +|-----------------|-------------------------|-----------|-----------------------| | $ConsensusInfo$ | [`ConsensusInfo`][cinf] | 48 bytes | Consensus info | | $VoteInfo$ | [`VoteInfo`][vinf] | 33 byte | Quorum vote | | $Attestation$ | [`Attestation`][att] | 112 bytes | Iteration attestation |