## 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 proposal handler is triggered when a node receives a _full proposal_ message.

A _proposal-value_ and a _full proposal_ are related but separate constructions.
This is motivated by a slower gossiping time of a _full proposal_, compared to a
much more succinct and therefore quickly gossiped _proposal-value_.

A proposal-value contains four fields:

1. The original _period_ in which this block was proposed.
2. The original proposer’s address.
3. The block digest, equal to the block header’s hash (including a domain separator).
   This field expands to Hash(“BH”\|\|Encode(bh))Hash(“BH”\|\|Encode(bh)), where “BH”
   is the domain separator for a “block header”, and the encoding function is the msgpack
   of the block header (bh).
4. A hash of the proposal, Hash(Proposal)Hash(Proposal). This field expands to
   Hash(“PL”\|\|Encode(Proposal))Hash(“PL”\|\|Encode(Proposal)), where Proposal
   represents the unauthenticated proposal, “PL” is the domain separator
   for a “payload”, and the encoding function is the msgpack of the Proposal.

On the other hand, an _unauthenticated proposal_ contains a full block and all extra
data for the block validation:

1. The original period in which this block was proposed.
2. The original proposer’s address.
3. A full block (header and payset).
4. A seed proof πseed.

Note that the _original period_ and proposer’s address are the same as the associated
_proposal-value_. The seed proof πseed is used to verify the seed computation.

In the following pseudocode the _frozen value_ μ is either:

- The highest priority observed proposal-value in the current (r,p) context
  (i.e., the lowest hashed according to the [priority function](https://specs.algorand.co/abft/abft-player-state#special-values)), or
- ⊥ if the node has observed no valid proposal vote.

The _staged value_ σ is either:

- The sole proposal-value for which a Bundle soft has been observed in
the current (r,p) context (see [normative section](https://specs.algorand.co/abft/abft-player-state#special-values)), or
- ⊥ if the node has observed no valid Bundle soft.

The _pinned value_ \( v̄ \) is a proposal-value that was a _staged value_
in a previous period. When available, this value is used to fast-forward the first
steps of the protocol when a next vote has been successful.

* * *

Algorithm 6: Handle Proposal

1: function HandleProposal(proposal)
2: v ← Proposal v (proposal, proposal p, proposal I)
3: if ∃ Bundle (r+1,0,soft,v) ∈ B then
4: Relay(proposal)
5: return Future round, do not observe (node is behind)
6: endif
7: if not VerifyProposal(proposal) ∨ proposal ∈ P then
8: return Ignore proposal
9: endif
10: if v ∉ {σ, v̄, μ} then
11: return Ignore proposal
12: endif
13: Relay(proposal)
14: P ← P ∪ proposal
15: if IsCommittable(v) ∧ s ≤ cert then
16: for a ∈ A do
17: credentials ← Sortition(a I, r, p, cert)
18: if credentials j > 0 then
19: Broadcast(Vote(a I, r, p, cert, v, credentials))
20: endif
21: end for
22: endif
23: end function

* * *

The node starts by performing a series of checks, after which it will either:
- Ignore the received proposal, discarding it and emitting no output, or
- Relay, observe, and produce an output according to the current context and the
  characteristics of the proposal.

The node checks if the proposal is from the first period of the next round, in which
case, the node relays this proposal and then ignores it for the operations
of the current round.

Whenever the node catches up (i.e., observes a round change), and only if necessary,
it will request this proposal back from the network.

The node checks if the proposal is invalid or has already been observed.
Any one of those conditions is enough to discard and ignore the incoming proposal.

Finally, the node checks if the associated proposal value is either a
_special proposal-value_ for the current round and period (σ, μ)
or the _pinned proposal-value_ (v̄). Any _full proposal_ whose _proposal-value_
does not match one of these is ignored.

Once the checks have been passed, the node relays and observes the proposal,
by adding it to the observed proposals set P.

Next, only if the _proposal-value_ is committable (meaning the _staged value_ is
set for a proposal, and said proposal has already been observed and is available)
and the current step is lower than or equal to a cert step (i.e., is not
  yet in a recovery step), the node plays for each _online_ account (registered on
the node), performing a Sortition to select the certification committee
members.

For each selected account, a Vote cert for the current _proposal-value_
is broadcast.
