The attestation process in the SA protocol is the part that handles agreement of provisioners over blocks. In particular, the attestation of a block involves, at each round, selecting, among provisioners, a block generator, responsible for producing a candidate block, and two voting committees, responsible for verifying the block and reach agreement.
When an agreement is reached on a candidate block, by a quorum of votes from both committees, the votes are collected, in aggregated form, into an Attestation structure, which serves as a proof of such an agreement.
ToC
A Voting Committee is an array of provisioners entitled to cast votes in the Validation and Ratification steps. Provisioners in a committee are called members of that committee. Each member in a given committee is assigned (by the sortition process) a number of credits (i.e., castable vote), referred to as its power in the committee.
Formally, a voting committee is defined as:
where
where
Note that members are ordered by insertion (a provisioner is added to the committee when being assigned its first credit). That is, the first provisioner to be added to the list by
For the sake of readability, in the rest of this documentation, we will use the following notation:
-
$C[i]$ denotes the$i\text{th}$ member of committee$C$ . Formally:$C[i] = m_i^C$
-
$i_m^C$ denotes the index$i$ of member$m$ in committee$C$ . Formally:$i_m^C = i : m_i^C = m$
-
$m_{pk}^C$ denotes the member of$C$ with publick key$pk$ .$m_{pk}^C = m : m \in C \wedge pk_m = pk$
- We say a provisioner
$P$ is in a committee$C$ if such committee contains a member with$P$ 's public key. Formally:$P \in C \text{ }if\text{ } \exists \text{ } m^C : pk_{m^C}=pk_P$
Voting Committees in the Validation and Ratification steps have a fixed number of credits that is defined by the global consensus parameter
When counting votes, each vote is multiplied by the power of the voter in the committee. For instance, if a member has 3 credits, his vote will be counted 3 times.
Hence, the
In some contexts, it is useful to numerically identify the SA step. For instance, this is done to distinguish Validation votes from Ratification votes, the step number (within the iteration) is included.
In this respect, we define the following parameters:
Parameter | Value |
---|---|
0 | |
1 | |
2 |
The selection of the block generator is done throught the extraction of a one-member committee. Specifically, the
Formally, the block generator (
This procedure extracts the block generator for the Proposal step of round
Parameters
-
$R$ : round number -
$I$ : iteration number
Algorithm
- Get absolute step number
$S$ for Proposal at iteration$I$ - Execute Deterministic Sortition DS to extract the generator
$\mathcal{G}$ - Output
$\mathcal{G}$
Procedure
-
$S =$ GetStepNum$(I, PropStep)$ -
$\mathcal{G}=$ DS$(R, S, 1, Provisioners)$ $\texttt{output }\mathcal{G}$
This procedure extracts the voting committee for the Validation or the Ratification step of round
The procedure excludes the block generator
The next-iteration generator is also excluded to mitigate the Future-Iteration Generator Problem.
Parameters
-
$R$ : round number -
$I$ : iteration number -
$StepNum$ : the step number ($ValStep$ or$RatStep$ )
Algorithm
- Get absolute step number
$S$ for$StepNum$ at iteration$I$ - Extract iteration generator
$\mathcal{G}_{R,I}$ for iteration$I$ - Exclude
$\mathcal{G}_{R,I}$ from the provisioner list - Extract iteration generator
$\mathcal{G}_{R,I+1}$ for iteration$I+1$ - Exclude
$\mathcal{G}_{R,I+1}$ from the provisioner list - Execute Deterministic Sortition DS to extract the committee
$\mathcal{C}$ - Output
$\mathcal{C}$
Procedure
-
$S =$ GetStepNum$(I, StepNum)$ -
$\mathcal{G}_{R,I} =$ ExtractGenerator$(R,I)$ $\boldsymbol{P} = Provisioners - \mathcal{G}_{R,I}$ -
$\mathcal{G}_{R,I+1} =$ ExtractGenerator$(R,I+1)$ $\boldsymbol{P} = Provisioners - \mathcal{G}_{R,I+1}$ -
$\mathcal{C}=$ DS$(R, S, CommitteeCredits, \boldsymbol{P})$ $\texttt{output } \mathcal{C}$
This procedure returns the quorum target depending on the vote
Parameters
-
$\mathsf{V}$ : the vote type ($Valid$ ,$Invalid$ ,$NoCandidate$ ,$NoQuorum$ )
Procedure
$\texttt{if } (\mathsf{V} = Valid): \texttt{output } Supermajority$ $\texttt{else}: \texttt{output } Majority$
This procedure returns the absolute step number within the round. It is used for the DS procedure.
Parameters
-
$I$ : the iteration number -
$StepNum$ : the relative step number ($PropStep$ ,$ValStep$ ,$RatStep$ )
Procedure
$\texttt{output } I \times + StepNum$
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 enumerations, whose data includes the hash of the candidate block in case of
This enum contains the information of a Validation or Ratification vote.
It can have the following values:
Variant | Data | Size | Description |
---|---|---|---|
|
/ | 1 byte | Vote for missing candidate |
|
33 bytes | Vote for valid candidate with specified hash | |
|
33 bytes | Vote for invalid candidate with specified hash | |
|
/ | 1 byte | Vote for no quorum reached |
The enum size is 33 bytes.
To ensure authentication and integrity, votes are digitally signed in the corresponding Validation
and Ratification
messages.
Thanks to the use of BLS signatures, equal votes from different provisioners can be aggregated into a single signature. The aggregated vote can than be propagated, stored, and verified with the corresponding aggregated public keys of the voters. This efficient scheme is implemented in the StepVotes
structure, which is based on the concept of subcommittees.
When votes of a committee reach a quorum they are aggregated into a single vote (i.e. a single, aggregated signature). The subset of the committee members whose vote is included in the aggregation is referred to as a subcommittee, or, if their votes reach a quorum, as a quorum committee (q-committee in short).
To verify an aggregated vote, it is necessary therefore necessary to know the members of the corresponding subcommittee. This is achieved by means of bitsets. A bitset is simply a vector of bits that indicate for a given committee, which member is included and which not.
For instance, in a committee
We make use of bitsets (array of bits) to indicate which members are part of a given subcommittee.
Given a committee
In particular, if the ith bit is set (i.e.,
Note that a 64-bit bitset is enough to represent the maximum number of members in a committee (i.e., CommitteeCredits).
This procedure takes a committee
This procedure sets a committee member's bit in a subcommittee bitset.
Parameters
-
$\boldsymbol{bs}$ : the subcommittee bitset -
$\mathcal{C}$ : the committee -
$M$ : the public key of the committee member
Procedure
$\boldsymbol{bs}[i_M^\mathcal{C}] = 1$
This procedure returns the amount of set bits in a bitset.
This procedure takes a committee
This procedure takes a committee
Parameters
-
$\mathcal{C}$ : a voting committee -
$\boldsymbol{bs}$ : a subcommittee bitset
Procedure
-
$\texttt{for } i=0 \dots CommitteeCredits{-}1 :$ $\texttt{if } (\boldsymbol{bs}[i]=1):$ $credits = credits + \mathcal{C}[i].Power$
$\texttt{output } credits$
An attestation is a proof of a reached agreement for a specific iteration. It includes the quorum-reaching vote along with the aggregated signatures of the quorum committees from the Validation and Ratification steps
As such, an attestation proves a either supermajority of
Note that, for each candidate block, there might be multiple Success Attestations, one for each possible subset of quorum voters. This might generate ambiguity in the handling of quorum-specific mechanisms, such as the assignment of rewards.
To make such mechanisms deterministic, the official set of voters that brought to a Success Attestation is decided by the generator of the following block. This is done by including in the candidate an attestation of the previous block. Such an attestation is referred to as the certificate of the previous block.
We define the following Attestation-related structures:
Attestation
: it contains a quorum of votes for the Validation and Ratification steps of a single iteration, in aggregated form;StepVotes
: it contains votes for a specific step, in aggregated form;StepResult
: it contains the winning vote of a step (the one reaching the quorum), and the corresponding signatures, in aggregated form;
This structure contains the result of an iteration (IterationResult
) along with the aggregated signatures (StepVotes
) of the Validation and Ratification steps.
Field | Type | Size | Description |
---|---|---|---|
IterationResult |
40 bytes | Result and vote of the iteration | |
StepVotes |
56 bytes | Aggregated votes of the Validation step | |
StepVotes |
56 bytes | Aggregated votes of the Ratification step |
The structure has a total size of 152 bytes.
This structure is used to store votes in the Validation and Ratification steps. Votes are stored as the aggregated BLS signatures of the members of the two Voting Committees. In fact, each vote 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 is used.
The structure is defined as follows:
Field | Type | Size | Description |
---|---|---|---|
BitSet | 64 bits | Bitset of the voters | |
BLS Signature | 48 bytes | Aggregated step signatures |
The structure has a total size of 56 bytes.
This structure contains the result of a Validation or Ratification step, that is the step result StepVotes
with the aggregated votes producing
The structure is defined as follows:
Field | Type | Size | Description |
---|---|---|---|
Vote |
33 bytes | The winning vote of the step | |
StepVotes |
56 bytes | Aggregated signatures |
This structure has a total size of 89 bytes.
This enumeration contains the final result of an iteration, which can be
Variant | Data | Size | Description |
---|---|---|---|
Vote |
33 bytes | It represents a successful iteration; Vote can only be |
|
Vote |
33 bytes | It represents a failed iteration; Vote can be NoCandidate , NoQuorum , or Invalid
|
This enumeration's size is 40 bytes
We define the following Attestation-related procedures:
- AggregateVote: adds a vote to a
StepVotes
- VerifyAttestation: verifies an
Attestation
- VerifyVotes: verifies aggregated votes in a
StepVotes
and checks the quorum
This procedure adds a vote to a StepVotes
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 -
$\mathcal{C}$ : the Voting Committee of$\mathsf{SV}$ -
$\sigma$ : the BLS signature to aggregate -
$pk$ : the signer public key
Procedure
-
$\mathsf{SV}.Votes =$ BLS_Aggregate$(\mathsf{SV}.Votes, \sigma)$ -
$\mathsf{SV}.Voters =$ SetBit$(\mathsf{SV}.Voters, \mathcal{C}, pk)$ $\texttt{output } \mathsf{SV}$
This procedure checks an Attestation by verifying the Validation and Ratification aggregated signatures of the Vote against the respective committees.
It takes an optional
Parameters
-
$\mathsf{CI}$ : theConsensusInfo
for the Attestation -
$\mathsf{A}$ : the Attestation to verify -
$ExpectedResult$ : the expected result of the attestation ($Success$ or$Fail$ )
Algorithm
- Check the
$Result$ against the$ExpectedResult$ - Check both Validation and Ratification votes are present
- Verify Validation votes
- If votes are not valid, output
$false$ - Verify Ratification votes
- If votes are not valid, output
$false$ - Output
$true$
Procedure
-
$\texttt{set}:$ $\eta_{\mathsf{B}}^p, R, I \leftarrow \mathsf{CI}$ $\mathsf{IR}, \mathsf{SV}^V, \mathsf{SV}^R \leftarrow \mathsf{A}$ -
$\mathcal{C}^V =$ ExtractCommittee$(R,I, ValStep)$ -
$\mathcal{C}^R =$ ExtractCommittee$(R,I, RatStep)$ $\mathsf{V}: \mathsf{IR}.Vote$ $\upsilon^V = (\mathsf{CI}||\mathsf{V}||ValStep)$ $\upsilon^R = (\mathsf{CI}||\mathsf{V}||RatStep)$ -
$Q =$ GetQuorum$(\mathsf{V})$
-
$\texttt{if } (ExpectedResult \ne NIL) \texttt{ and } (\mathsf{IR} \ne ExpectedResult): \texttt{output } false$ -
$\texttt{if } (\mathsf{SV}^V = NIL) \texttt{ or } (\mathsf{SV}^R = NIL): \texttt{output } false$ -
$isValid =$ VerifyVotes$(\mathsf{SV}^V, \upsilon^V, Q, \mathcal{C}^V)$ -
$\texttt{if } (isValid{=}false): \texttt{output } false$ -
$isValid =$ VerifyVotes$(\mathsf{SV}^R, \upsilon^R, Q, \mathcal{C}^R)$ -
$\texttt{if } (isValid{=}false): \texttt{output } false$ -
$\texttt{output } true$
This procedure checks the aggregated votes are valid and reach the target quorum.
Parameters
-
$\mathsf{SV}$ :$\mathsf{StepVotes}$ with the aggregated votes -
$\upsilon$ : the signature value -
$Q$ : the target quorum -
$\mathcal{C}$ : the step committee
Algorithm
- Compute subcommittee
$C^{\boldsymbol{bs}}$ from$\mathsf{SV}.BitSet$ - If credits in
$C^{\boldsymbol{bs}}$ are less than the target quorum$Q$ - Output
$false$
- Output
- Aggregate public keys of
$C^{\boldsymbol{bs}}$ members - Verify aggregated signature over
$\upsilon$
Procedure
-
$\texttt{set}:$ $\boldsymbol{bs}, \sigma_{\boldsymbol{bs}} \leftarrow \mathsf{SV}$
-
$\mathcal{C}^{\boldsymbol{bs}}=$ SubCommittee$(\mathcal{C}, \boldsymbol{bs})$ -
$\texttt{if } ($ CountCredits$(\mathcal{C}, \boldsymbol{bs}) \lt Q):$ $\texttt{output } false$
$pk_{\boldsymbol{bs}} = AggregatePKs(C^{\boldsymbol{bs}})$ $\texttt{output } Verify_{BLS}(\upsilon, pk_{\boldsymbol{bs}}, \sigma_{\boldsymbol{bs}})$