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

$$ \newcommand \pk {\mathrm{pk}} \newcommand \sk {\mathrm{sk}} \newcommand \Vote {\mathrm{Vote}} \newcommand \fv {\text{first}} \newcommand \Record {\mathrm{Record}} \newcommand \lv {\text{last}} \newcommand \Stake {\mathrm{Stake}} \newcommand \Seed {\mathrm{Seed}} \newcommand \CommitteeThreshold {\mathrm{CommitteeThreshold}} \newcommand \CommitteeSize {\mathrm{CommitteeSize}} \newcommand \Sign {\mathrm{Sign}} \newcommand \Bundle {\mathrm{Bundle}} \newcommand \Soft {\mathit{soft}} \newcommand \Cert {\mathit{cert}} \newcommand \Proposal {\mathrm{Proposal}} \newcommand \Entry {\mathrm{Entry}} \newcommand \Rand {\mathrm{Rand}} \newcommand \Hash {\mathrm{Hash}} \newcommand \Digest {\mathrm{Digest}} \newcommand \Encoding {\mathrm{Encoding}} \newcommand \FilterTimeout {\mathrm{FilterTimeout}} \newcommand \Next {\mathit{next}} \newcommand \DeadlineTimeout {\mathrm{DeadlineTimeout}} \newcommand \Late {\mathit{late}} \newcommand \Redo {\mathit{redo}} \newcommand \Down {\mathit{down}} $$

Broadcast Rules

Upon observing messages or receiving timeout events, the player state machine emits network outputs, which are externally visible. The player may also append an entry to the ledger.

A correct player emits only valid votes. Suppose the player is identified with the address \( I \) and possesses the secret key \( \sk \), and the agreement is occurring on the ledger \(L\). Then the player constructs a vote \( \Vote(I, r, p, s, v) \) by doing the following:

  • Let

    • \(( \pk, B, r_\fv, r_\lv) = \Record(L, r - \delta_b, I) \),
    • \( \bar{B} = \Stake(L, r - \delta_b) \),
    • \( Q = \Seed(L, r - \delta_s) \),
    • \( \tau = \CommitteeThreshold(s) \),
    • \( \bar{\tau} = \CommitteeSize(s) \).
  • Encode \( x := (I, r, p, s, v), x’ := (I, r, p, s) \).

  • Try to set \( y := \Sign(x, x’, \sk, B, \bar{B}, Q, \tau, \bar{\tau}) \).

If the signing procedure succeeds, the player broadcasts \( Vote(I, r, p, s, v) = (I, r, p, s, v, y) \). Otherwise, the player does not broadcast anything.

For certain broadcast vote-messages specified here, a node is forbidden to equivocate (i.e., produce a pair of votes which contain the same round, period, and step but which vote for different proposal values). These messages are marked with an asterisk (*) below. To prevent accidental equivocation after a power failure, nodes SHOULD checkpoint their state to crash-safe storage before sending these messages.

Note

For further details on these checkpoint strategies, refer to the non-normative Ledger specification. For an in-depth review of broadcasting functionalities, refer to the non-normative Network specification.

Resynchronization Attempt

Where specified, a player attempts to resynchronize.

A resynchronization attempt involves the following stages.

First, the player broadcasts its freshest bundle, if one exists.

A player’s freshest bundle is a complete bundle defined as follows:

  • \( \Bundle(r, p, \Soft, v) \subset V \) for some \( v \), if it exists, or else

  • \( \Bundle(r, p-1, s, \bot) \subset V \) for some \( s > \Cert \), if it exists, or else

  • \( \Bundle(r, p-1, s, v) \subset V \) for some \( s > \Cert, v \neq \bot \), if it exists.

Important

IMPLEMENTATION:

Freshness relation reference implementation.

Second, if the player broadcasted a bundle \( \Bundle(r, p, s, v) \), and \( v \neq \bot \), then the player broadcasts \( \Proposal(v) \) if the player has it.

Specifically, a resynchronization attempt:

  • Corresponds to no additional outputs if no freshest bundle exists

$$ N(S, L, \ldots) = (S’, L’, \ldots), $$

  • Corresponds to a broadcast of the freshest bundle after a relay output and before any subsequent broadcast outputs, if said bundle exists, no matching proposal exists

$$ N(S, L, \ldots) = (S’, L’, (\ldots, \Bundle^\ast(r, p, s, v), \ldots)), $$

  • Otherwise corresponds to a broadcast of both a bundle and its associated proposal after a relay output and before any subsequent broadcast outputs

$$ N(S, L, \ldots) = (S’, L’, (\ldots, \Bundle^\ast(r, p, s, v), \Proposal(v), \ldots)). $$

Proposals

On observing that \( (r, p) \) has begun, the player attempts to resynchronize, and then

  • if \( p = 0 \) or there exists some \( s > \Cert \) where \( \Bundle(r, p-1, s, \bot) \) was observed, then a player generates a new proposal \( (v’, \Proposal(v’)) \) and then broadcasts \( (\Vote(I, r, p, 0, v’), \Proposal(v’)) \).

  • if \( p > 0 \) and there exists some \( s_0 > \Cert, v \) where \( \Bundle(r, p-1, s_0, v) \) was observed, while there exists no \( s_1 > \Cert \) where \( \Bundle(r, p-1, s_1, \bot) \) was observed, then the player broadcasts \( \Vote(I, r, p, 0, v) \). Moreover, if \( \Proposal(v) \in P \), the player then broadcasts \( \Proposal(v) \).

A player generates a new proposal by executing the entry-generation procedure and by setting the fields of the proposal accordingly. Specifically, the player creates a proposal payload \( ((o, s), y) \) by setting

  • \( o := \Entry(L) \),

  • \( Q := \Seed(L, r-1) \),

  • \( y := \Sign(Q, Q, 0, 0, 0, 0, 0, 0) \),

  • and \( s := \Rand(y, \pk)\) if \( p = 0 \) or \( s := \Hash(\Seed(L, r-1)) \) otherwise.

This consequently defines the matching proposal-value \( v = (I, p, \Digest(e), \Hash(\Encoding(e))) \).

Note

For an in-depth overview of how proposal generation may be implemented, refer to the Algorand Ledger non-normative section.

In other words, if the player generates a new proposal,

$$ N(S, L, \ldots) = (S’, L’, (\ldots, \Vote(I, r, p, 0, v’), \Proposal(v’))), $$

while if the player broadcasts an old proposal,

$$ N(S, L, \ldots) = (S’, L’, (\ldots, \Vote(I, r, p-1, 0, v), \Proposal(v))) $$

if \( \Proposal(v) \in P \) and

$$ N(S, L, \ldots) = (S’, L’, (\ldots, \Vote(I, r, p-1, 0, v))) $$

otherwise.

Reproposal Payloads

On observing \( \Vote(I, r, p, 0, v) \), if \( \Proposal(v) \in P \) then the player broadcasts \( \Proposal(v) \).

In other words, if \( \Proposal(v) \in P \),

$$ N(S, L, \Vote(I, r, p, 0, v)) = (S’, L’, (\Proposal(v))). $$

Filtering

On observing a timeout event of \( \FilterTimeout(p) \) (where \( \mu = (H, H’, l, p_\mu) = \mu(S, r, p) \)),

  • if \( \mu \neq \bot \) and if

    • \( p_\mu = p \) or
    • there exists some \( s > \Cert \) such that \( \Bundle(r, p-1, s, \mu) \) was observed then the player broadcasts \( \Vote(I, r, p, \Soft, \mu) \).
  • if there exists some \( s_0 > \Cert \) such that \( \Bundle(r, p-1, s_0, \bar{v}) \) was observed and there exists no \( s_1 > \Cert \) such that \( \Bundle(r, p-1, s_1, \bot) \) was observed, then the player broadcasts* \( \Vote(I, r, p, \Soft, \bar{v}) \).

  • otherwise, the player does nothing.

Note

For a detailed overview of how the filtering step may be implemented, refer to the Algorand ABFT non-normative section.

In other words, in the first case above,

$$ N(S, L, t(\FilterTimeout(p), p)) = (S, L, \Vote(I, r, p, \Soft, \mu)); $$

while in the second case above,

$$ N(S, L, t(\FilterTimeout(p), p)) = (S, L, \Vote(I, r, p, \Soft, \bar{v})); $$

and if neither case is true,

$$ N(S, L, t(\FilterTimeout(p), p)) = (S, L, \epsilon). $$

Certifying

On observing that some proposal-value \( v \) is committable for its current round \( r \), and some period \( p’ \geq p \) (its current period), if \( s \leq \Cert \), then the player broadcasts* \( \Vote(I, r, p, \Cert, v) \). (It can be shown that this occurs either after a proposal is received or a soft-vote, which can be part of a bundle, is received.)

Note

For a detailed overview of how the certification step may be implemented, refer to the Algorand ABFT non-normative section.

In other words, if observing a soft-vote causes a proposal-value to become committable,

$$ N(S, L, \Vote(I, r, p, \Soft, v)) = (S’, L, (\ldots, \Vote(I, r, p, \Cert, v))); $$

while if observing a bundle causes a proposal-value to become committable,

$$ N(S, L, \Bundle(r, p, \Soft, v)) = (S’, L, (\ldots, \Vote(I, r, p, \Cert, v))); $$

and if observing a proposal causes a proposal-value to become committable,

$$ N(S, L, \Proposal(v)) = (S’, L, (\ldots, \Vote(I, r, p, \Cert, v))); $$

as long as \( s \leq \Cert \).

Commitment

On observing \( \Bundle(r, p, \Cert, v) \) for some value \( v \), the player commits the entry \( e \) corresponding to \( \Proposal(v) \); i.e., the player appends \( e \) to the sequence of entries on its ledger \( L \). (Evidently, this occurs either after a vote is received or after a bundle is received.)

Note

For further details on how entry commitment may be implemented, refer to the Algorand Ledger non-normative section.

In other words, if observing a cert-vote causes the player to commit \( e \),

$$ N(S, L, \Vote(I, r, p, \Cert, v)) = (S’, L || e, \ldots)); $$

while if observing a bundle causes the player to commit \( e \),

$$ N(S, L, \Bundle(r, p, \Cert, v)) = (S’, L || e, \ldots)). $$

Note

Occasionally, an implementation may not have \( e \) at the point \( e \) becomes committed. In this case, the implementation may wait until it receives \( e \) somehow (perhaps by requesting peers for \( e \)). Alternatively, the implementation may continue running the protocol until it receives \( e \). However, if the protocol chooses to continue running, it may not transmit any vote for which \( v \neq \bot \) until it has committed \( e \).

Recovery

On observing a timeout event of

  • \( T = \DeadlineTimeout(p) \) or

  • \( T = \DeadlineTimeout(p) + 2^{s_t}\lambda + u \) where \( u \in [0, 2^{s_t}\lambda] \) sampled uniformly at random,

the player attempts to resynchronize and then broadcasts* \( \Vote(I, r, p, \Next_h, v) \) where

  • \( v = \sigma(S, r, p) \) if \( v \) is committable in \( (r, p) \),

  • \( v = \bar{v} \) if there does not exist a \( s_0 > \Cert \) such that \( \Bundle(r, p-1, s_0, \bot) \) was observed and there exists an \( s_1 > \Cert \) such that \( \Bundle(r, p-1, s_1, \bar{v} )\) was observed,

  • and \( v = \bot \) otherwise.

Important

IMPLEMENTATION:

Next vote issuance reference implementation.

Next vote timeout ranges computation reference implementation.

Call to \( \Next_0 \) reference implementation.

Subsequent calls to \( \Next_{st} \) reference implementation.

Step increase in recovery step timeouts reference implementation.

Note

For a detailed overview of how the recovery routine may be implemented, refer to the Algorand ABFT non-normative section.

In other words, if a proposal-value \( v \) is committable in the current period,

$$ N(S, L, t(T, p)) = (S’, L, (\ldots, \Vote(I, r, p, \Next_h, v))); $$

while in the second case,

$$ N(S, L, t(T, p)) = (S’, L, (\ldots, \Vote(I, r, p, \Next_h, \bar{v}))); $$

and otherwise,

$$ N(S, L, t(T, p)) = (S’, L, (\ldots, \Vote(I, r, p, \Next_h, \bot))). $$

Fast Recovery

On observing a timeout event of \( T = k\lambda_f + u \) where \( k \) is a positive integer and \( u \in [0, \lambda_f] \) sampled uniformly at random, the player attempts to resynchronize. Then,

  • The player broadcasts* \( \Vote(I, r, p, \Late, v) \) if \( v = \sigma(S, r, p) \) is committable in \( (r, p) \).

  • The player broadcasts* \( \Vote(I, r, p, \Redo, \bar{v}) \) if there does not exist a \( s_0 > \Cert \) such that \( \Bundle(r, p-1, s_0, \bot) \) was observed and there exists an \( s_1 > \Cert \) such that \( \Bundle(r, p-1, s_1, \bar{v}) \) was observed.

  • Otherwise, the player broadcasts* \( \Vote(I, r, p, \Down, \bot) \).

Finally, the player broadcasts all \( \Vote(I, r, p, \Late, v) \in V\), all \( \Vote(I, r, p, \Redo, v) \in V\), and all \( \Vote(I, r, p, \Down, \bot) \in V \) that it has observed.

Important

IMPLEMENTATION:

Fast recovery reference implementation.

Note

For a detailed pseudocode overview of the fast recovery routine, along with protocol recovery run examples, refer to the Algorand ABFT non-normative section.