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 \BonusDecayInterval {B_{b,\mathrm{decay}}} \newcommand \MaxProposedExpiredOnlineAccounts {B_{N_\mathrm{e},\max}} \newcommand \MinBalance {b_{\min}} \newcommand \PayoutsMaxBalance {A_{r,\max}} \newcommand \PayoutsMinBalance {A_{r,\min}} \newcommand \Heartbeat {\mathrm{hb}} \newcommand \PayoutsChallengeBits {\Heartbeat_\mathrm{bits}} \newcommand \PayoutsChallengeGracePeriod {\Heartbeat_\mathrm{grace}} \newcommand \PayoutsChallengeInterval {\Heartbeat_r} \newcommand \PayoutMaxMarkAbsent {B_{N_\mathrm{a},\max}} \newcommand \MaxTxnBytesPerBlock {B_{\max}} $$

Blocks

A block is a data structure that specifies the transition between states.

The data in a block is divided between the block header and its block body.

Block Header

The block header contains the following components:

Round

The block’s round, which matches the round of the state it is transitioning into. (The block with round \( 0 \) is special in that this block specifies not a transition but rather the entire initial state, which is called the genesis state. This block is correspondingly called the genesis block). The round is stored under msgpack key rnd.

Genesis Identifier

The block’s genesis identifier and genesis hash, which match the genesis identifier and hash of the states it transitions between (i.e., they stay constant since the initial state forwards). The genesis identifier is stored under msgpack key gen, and the genesis hash is stored under msgpack key gh.

Upgrade Vote

The block’s upgrade vote, which results in the new upgrade state. The block also duplicates the upgrade state of the state it transitions into. The msgpack representations of the upgrade vote components are described in detail below.

Timestamp

The block’s timestamp, which matches the timestamp of the state it transitions into. The timestamp is stored under msgpack key ts.

Seed

The block’s seed, which matches the seed of the state it transitions into. The seed is stored under msgpack key seed.

Reward Updates

The block’s reward updates, which results in the new reward state. The block also duplicates the reward state of the state it transitions into. The msgpack representations of the reward updates components are described in detail below.

Transaction Commitments

Cryptographic commitments to the block’s transaction sequence, described below (referred also as payset), using:

Previous Hash

The block’s previous hash, which is the cryptographic hash of the previous Block Header in the sequence, using:

The previous hash of the genesis block is \( 0 \)).

Transaction Counter

The block’s transaction counter, which is the total number of transactions issued prior to this block. This count starts from the first block with a protocol version that supports the transaction counter. The counter is stored in msgpack field tc.

Proposer

The block’s proposer, which is the address of the account that proposed the block. The proposer is stored in msgpack field prp.

Fees Collected

The block’s fees collected is the sum of all fees paid by transactions in the block and is stored in msgpack field fc.

Bonus

The potential bonus incentive is the amount, in μALGO, that may be paid to the proposer of this block beyond the amount available from fees. It is stored in msgpack field bi. It may be set during a consensus upgrade, or else it must be equal to the value from the previous block in most rounds, or be \( 99 \% \) of the previous value (rounded down) if the round of this block is \( 0 \mod \BonusDecayInterval \).

Proposer Payout

The proposer payout is the actual amount that is moved from the \( I_f \) to the proposer, and is stored in msgpack field pp. If the proposer is not eligible, as described below, the proposer payout MUST be \( 0 \). The proposer payout MUST NOT exceed

  • The sum of the bonus incentive and half of the fees collected.
  • The fee sink balance minus \( \MinBalance \).

Load

The block’s load measures how full the block is, based on the total size of its transactions relative to the maximum permitted. It is stored in msgpack field ld as a fixed-point value in millionths (six digits of precision), so that \( 1{,}000{,}000 \) denotes a completely full block. The load MUST equal

$$ \min\left( \left\lfloor \frac{1{,}000{,}000 \cdot s}{\MaxTxnBytesPerBlock} \right\rfloor, ; 1{,}000{,}000 \right) $$

where \( s \) is the sum of the byte lengths of the canonical msgpack encoding of each SignedTxnInBlock in the block’s payset. The payset’s array framing is not included. This is the same total used to enforce \( \MaxTxnBytesPerBlock \), the maximum number of transaction bytes in a block.

Congestion Tax

The block’s congestion tax measures network congestion. It is stored in msgpack field ct as a fixed-point value in millionths, and is derived deterministically from the previous block’s load and congestion tax: it rises when the previous block was more than half full, falls when it was less than half full, and remains unchanged when it was exactly half full. The congestion tax currently does not affect the fee required by any transaction.

Let \( L \) and \( C \) be the load and congestion tax of the previous block, and let

$$ d = \left\lfloor \frac{100{,}000 , (500{,}000 - L)}{500{,}000} \right\rfloor, \qquad u = \left\lfloor \frac{100{,}000 , (L - 500{,}000)}{500{,}000} \right\rfloor. $$

The congestion tax of this block MUST equal

$$ \begin{cases} \max!\left( \left\lfloor \dfrac{C , (1{,}000{,}000 - d)}{1{,}000{,}000} \right\rfloor - d, ; 0 \right), & L \le 500{,}000, \[2.5ex] \left\lfloor \dfrac{C , (1{,}000{,}000 + u)}{1{,}000{,}000} \right\rfloor + u, & L > 500{,}000. \end{cases} $$

The subtraction is floored at \( 0 \) and the addition saturates at the maximum representable value. The target load is half full (\( 500{,}000 \)); the multiplicative factor changes the tax by at most \( 10% \) per block, while the additive term (also at most \( 100{,}000 \)) lets the tax grow away from and return to \( 0 \).

Expired Participation Accounts

The block’s expired participation accounts, which contains an optional list of account addresses. These accounts’ participation key expire by the end of the current round, with exact rules below. The list is stored in msgpack key partupdrmv.

Suspended Participation Accounts

The block’s suspended participation accounts, which contains an optional list of account addresses. These accounts have not recently demonstrated that they are available and participating, with exact rules below. The list is stored in msgpack key partupdabs.

A proposer is eligible for bonus payouts if the account’s IncentiveEligible flag is true and its online balance is between \( \PayoutsMinBalance \) and \( \PayoutsMaxBalance \).

The expired participation accounts list is valid as long as:

  • The participation keys of all the accounts in the slice are expired by the end of the round;

  • The accounts themselves would have been online at the end of the round if they were not included in the list;

  • The number of elements in the list is less than or equal to \( \MaxProposedExpiredOnlineAccounts \). A block proposer may not include all such accounts in the list and may even omit the list completely.

The suspended participation accounts list is valid if, for each included address, the account is:

  • Online;
  • Incentive eligible;
  • Either absent or failing a challenge as of the current round.

An account is absent if its LastHeartbeat and LastProposed rounds are both more than \( 20n \) rounds before current, where \( n \) is the reciprocal of the account’s fraction of online stake.

An account is failing a challenge if:

  • The first \( \PayoutsChallengeBits \) bits of the account’s address matches the first \( \PayoutsChallengeBits \) bits of an active challenge round’s block seed;
  • The active challenge round is between \( \PayoutsChallengeGracePeriod \) and \( 2\PayoutsChallengeGracePeriod \) rounds before the current round.

An active challenge round is a round that is \( 0 \mod \PayoutsChallengeInterval \).

The length of the list MUST not exceed \( \PayoutMaxMarkAbsent \).

A block proposer MAY NOT include all such accounts in the list and MAY even omit the list completely.

Block Body

The block body is the block’s transaction sequence (also known as payset), which describes the sequence of updates (transactions) to the account state and box state.

Block Validity

A block is valid if each component is also valid. (The genesis block is always valid).

Applying a valid block to a state produces a new state by updating each of its components.

The rest of this document defines block validity and state transitions by describing them for each component.