Vote Handler - Algorand Specifications
Keyboard shortcuts
Press ← or → to navigate between chapters
Press S or / to search in the book
Press ? to show this help
Press Esc to hide this help
- Auto
- Light
- Dark
Algorand Specifications
The algorithms presented in this section abstract away a series of behaviors as a single vote handler for ease of understanding and to provide an implementation-agnostic engineering overview.
In the reference implementation, the vote verification and vote observation, although dependent on each other, are performed by separate processes.
Note that an equivocation vote is a pair of votes that differ only in their proposal values vv. In other words, given a player II and a node’s context tuple (r,p,s)(r,p,s), Equivocation(I,r,p,s)=(Vote(I,r,p,s,v1),Vote(I,r,p,s,v2))Equivocation(I,r,p,s)=(Vote(I,r,p,s,v1),Vote(I,r,p,s,v2)) for some v1≠v2v1≠v2.
Algorithm5: Handle VoteAlgorithm 5: Handle Vote
1: functionValidateVote(vote):2: ifnotVerifyVote(vote)then3: DisconnectFromPeer(SenderPeer(vote))4: returnIgnore invalid vote5: endif6: ifvotes=0∧(vote∈V∨IsEquivocation(vote))then7: returnIgnore vote, equivocation not allowed in proposal votes8: endif9: ifvotes>0∧IsSecondEquivocation(vote)then10:returnIgnore vote if it’s a second equivocation11:endif12:ifvoter<rthen13:returnIgnore vote of past round14:endif15:ifvoter=r+1∧(votep>0∨votes∈{next0,…,next249})then16:returnIgnore vote of next round if non-zero period or next-k step17:endif18:ifvoter=r∧(votep∉{p−1,p,p+1}∨(votep=p+1∧votes∈{next1,…,next249})∨(votep=p∧votes∈{next1,…,next249}∧votes∉{s−1,s,s+1})∨(votep=p−1∧votes∈{next1,…,next249}∧votes∉{s¯−1,s¯,s¯+1}))then19:returnIgnore vote20:endif21: endfunction1: function ValidateVote(vote):2: if not VerifyVote(vote) then3: DisconnectFromPeer(SenderPeer(vote))4: return Ignore invalid vote5: end if6: if votes=0∧(vote∈V∨IsEquivocation(vote)) then7: return Ignore vote, equivocation not allowed in proposal votes8: end if9: if votes>0∧IsSecondEquivocation(vote) then10:return Ignore vote if it’s a second equivocation11:end if12:if voter
22: functionHandleVote(vote):23:ValidateVote(vote)Check the validity of the vote24:V←V∪voteObserve the vote25:Relay(vote)26:ifvotes=proposethen27:ifRetrieveProposal(votev)≠⊥then28:Broadcast(RetrieveProposal(votev))29:endif30:elseifvotes=softthen31:if∃v:Bundle(voter,votep,soft,v)⊂Vthen32:fora∈Ado33:credentials←Sortition(ask,r,p,cert)34:ifcredentialsj>0then35:Broadcast(Vote(aI,r,p,cert,v,credentials))36:endif37:endfor38:endif39:elseifvotes=certthen40:if∃v:Bundle(voter,votep,cert,v)⊂Vthen41:ifRetrieveProposal(v)=⊥then42:RequestProposal(v)43:ifpvotepthen44:pold←p45:StartNewPeriod(votep)46:GarbageCollect(r,pold)47:endif48:endif49:Commit(v)50:rold←r51:StartNewRound(voter+1)52:GarbageCollect(rold,p)53:endif54:elseifvotescertthen55:if∃v:Bundle(voter,votep,votes,v)⊂Vthen56:pold←p57:StartNewPeriod(votep+1)58:GarbageCollect(r,pold)59:endif60:endif61: endfunction22: function HandleVote(vote):23:ValidateVote(vote)Check the validity of the vote24:V←V∪voteObserve the vote25:Relay(vote)26:if votes=propose then27:if RetrieveProposal(votev)≠⊥ then28:Broadcast(RetrieveProposal(votev))29:end if30:else if votes=soft then31:if ∃v:Bundle(voter,votep,soft,v)⊂V then32:for a∈A do33:credentials←Sortition(ask,r,p,cert)34:if credentialsj>0 then35:Broadcast(Vote(aI,r,p,cert,v,credentials))36:end if37:end for38:end if39:else if votes=cert then40:if ∃v:Bundle(voter,votep,cert,v)⊂V then41:if RetrieveProposal(v)=⊥ then42:RequestProposal(v)43:if p<votep then44:pold←p45:StartNewPeriod(votep)46:GarbageCollect(r,pold)47:end if48:end if49:Commit(v)50:rold←r51:StartNewRound(voter+1)52:GarbageCollect(rold,p)53:end if54:else if votes>cert then55:if ∃v:Bundle(voter,votep,votes,v)⊂V then56:pold←p57:StartNewPeriod(votep+1)58:GarbageCollect(r,pold)59:end if60:end if61: end function
The vote handler is triggered when a node receives a message containing a vote for a given proposal value, round, period, or step.
It first performs a series of checks, and if the received vote passes all of them, then it is broadcast by all accounts selected as the appropriate committee members.
On Line 2, the ValidateVoteValidateVote function checks if the vote is valid. If invalid, this is considered adversarial behavior. Therefore, a node may disconnect from the vote sender node, retrieving the network ID of the original message sender with the ( SenderPeer \ helper network module function.
Equivocation votes on a proposal step are not allowed, so a check for this condition is performed (Line 6).
Furthermore, second equivocations are never allowed (Line 9).
Any votes for rounds before the current round are discarded (Line 12).
In the special case of receiving a message vote for a round immediately after the current round, the node observes it only if it is related to the first period (p=0p=0), in any of the following steps: proposal, soft, cert, late, down, or redo (ignoring votes for further periods p>0p>0 or for nextknextk steps).
Finally, the node checks that (Line 18) if the vote’s round is for the currently executing round, and one of the following:
Vote’s period is not the current node period, the period before, or the next period, or
Vote’s period is the next period, and
- Its step is nextknextk with k≥1k≥1, or
Vote’s period is the current node period, and
- Its step is nextknextk with k≥1k≥1, and
- Its step is not the current step, the step before, or the next step, or
Vote’s period is the period before, and
- Its step is nextknextk with k≥1k≥1, and
- Its step distance is not one or less from the node’s last finished step.
Then the vote is ignored and discarded. Note that the equivocation vote verification uses the same verification functions, but verifies that both constituent votes are valid separately.
Once finished with the series of validation checks, the vote is observed, relayed, and then processed by the node according to its current context and the vote’s step:
If the vote’s step is proposepropose, and the proposal corresponding to the proposal-value vv has already been observed, the proposal is broadcast (that is, the node performs a re-proposal payload broadcast).
If the vote’s step is SoftSoft, and a softBundlesoftBundle has been observed with the addition of the vote, the SortitionSortition sub-procedure is run for every online account managed by the node. Then, a CertCert vote is cast for each account the lottery selects.
If the vote’s step is CertCert, and observing the vote causes the node to observe a CertBundleCertBundle for a proposal-value vv, then it checks if the full proposal associated with the critical value has been observed. Simultaneous observation of a CertBundleCertBundle for a value vv and of a proposal equal to RetrieveProposal(v)RetrieveProposal(v) implies the associated entry is committable. If the full proposal has not yet been observed, the node may stall and request the full proposal from the network. Once the desired proposal can be committed, the node proceeds to commit, start a new round, and garbage collects all transient data from the round it just finished.
Finally, if the vote is that of a recovery step (s>certs>cert), and a BundleBundle has been observed for a given proposal-value vv, then a new period is started, and the currently executing period-specific data is garbage collected.