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

Ledger: Blocks

Blocks are a fundamental component of all blockchains and represent one of two basic units of exchange between nodes (the other being transactions).

A block can itself be broken down into multiple parts:

block-beta
block
  columns 1
  H["Header"]
  block
    columns 2
    BB["Transactions"]
    BW["Witnesses"]
    BA["Auxiliary Data"]
    BV["Transaction Validity"]
  end
end

See also the Block CDDL for the Conway era (the latest era at the time of writing).

The header/body split

The most important distinction in the above diagram is that there is a split between the header of the block and the body. The general guiding principle behind this is the following:

  • The header contains the parts of the block relevant to the consensus protocol.
  • The body contains the parts of the block relevant to the ledger.

The full details and implications of this split are covered in Implications of the Header/Body Split. For now, we can assume that the contents of the header are not important for the ledger processing.

The block body

The block body itself is split into four parts. This division is not conceptually necessary but is helpful for efficient processing:

  1. The ‘Transactions’ section contains the bodies of all transactions. This is the only part of the block body necessary to compute the resulting ledger state (see The ledger state transition) - that is, provided that the block is valid with regard to some ledger state, the resulting new state can be computed using only the data in this section.

  2. The ‘Witnesses’ section contains the cryptographic witnessing necessary to evaluate the validity of the transactions contained in the block. For more details on validity, please see the Validity section.

  3. The ‘AuxData’ section contains “auxiliary data” which is not processed as part of the ledger state. It instead contains data which may be of use to either users directly or other software interfacing with the chain. In Shelley, this was limited to “metadata’, which were indeed simply binary blobs. In the Mary and Alonzo eras slightly more structure was provided to allow including native and Plutus scripts respectively.

  4. The transaction validity contains a list of transactions in this block which are phase-2 invalid. This is held separately since this map is provided, effectively, by the node which created the block, rather than by the creators of the transactions.

Leios block structure changes

Leios changes the block structure in two ways:

  • Block headers are re-used as announcements of endorser blocks, via an eb_announcement field
  • Blocks may certify an EB and then
    • set block_body_contains_leios_cert in the header
    • contain a leios_certificate instead of transactions in the body

How the committee behind such a certificate is derived, and how the certificate is verified against it, is described under Leios key registration and committee selection.

Note

The djikstra.cddl in the cardano-blueprint is matching the same-named branch of the cardano-ledger upstream repository. This is the block format currently used on the https://www.musashi.network/ Leios testnet.

Changed dijkstra header_body

header_body =
  [ block_number                   : block_number
  , slot                           : slot
  , prev_hash                      : hash32/ nil
  , issuer_vkey                    : vkey
  , vrf_vkey                       : vrf_vkey
  , vrf_result                     : vrf_cert
  , block_body_size                : uint .size 4
  , block_body_hash                : hash32                ; merkle triple root
  , operational_cert
  , protocol_version
  , block_body_contains_leios_cert : bool
  , eb_announcement                : eb_announcement/ nil
  ]

with

eb_announcement =
  [ eb_hash : hash32
  , eb_size : uint .size 4 ; size of the EB references
  ]

Changed dijkstra block

block_body =
  [ transactions      : [* block_transaction]
  , leios_certificate : leios_certificate/ nil
  , peras_certificate : peras_certificate/ nil
  ]

with

leios_certificate =
  [ signers   : bytes .size (0 .. 8192) ;bitfield with up to 65536 entries
  , signature : leios_signature
  ]

leios_signature = bytes .size 48