Skip to main content
The Sundial L2 ledger is a chain of blocks. Each block turns the previous block’s set of unspent transaction outputs (UTXOs) into a new one. Unlike an L1 ledger, it is an open system. Blocks create and destroy UTXOs in response to events on L1 (deposits and withdrawal orders) as well as L2 transactions.

Blocks

A block is a header hash, a header and a body. The body holds four sets: The full block is published to the data availability layer. Only the header hash and header go to L1. That is sufficient because the header holds the Merkle Patricia Trie root of each set, and each root can be checked on L1 by streaming over the set.

Order of application

A block applies its events in a fixed order:
  1. Withdrawals
  2. Transaction orders
  3. Transaction requests
  4. Deposits
A block that breaks this order is invalid. Orders come before requests so that a transaction order, which costs more to create, is never invalidated in favour of a request.

The block header

The header hash is the Blake2b-224 hash of the header, 28 bytes.

The UTXO set

The UTXO set maps output references to outputs. An output has an address, a value, an optional inline datum and an optional script. An output reference is the ID of the event that created the output (a transaction or a deposit) and its index. Every L2 address carries the network ID of the Sundial instance, which separates the L2 ledger from the settlement L1 and from other Sundial instances.

Transactions

There are two ways a transaction reaches a block: Both land in the same transactions set.

How the transaction type differs from Cardano’s

The L2 transaction type is based on Cardano’s Conway-era transaction, restricted to what a contract-secured L2 can validate. Violating any of these is fraud under the ledger rules.

Hashed fields

In the form that L1 scripts work with, every variable-length field of a transaction is replaced by its hash. This lets a fraud proof step through a transaction at bounded cost. The data availability layer holds the preimages, and a mismatch between a hash and its preimage is itself provable.

Confirmed state

A block is confirmed once all its predecessors are confirmed and its maturity period has passed without a verified fraud proof. Confirmation is irreversible, which lets the L1 representation be condensed:
  • ConfirmedState keeps only the last confirmed header’s hash, its UTXO root, its time bounds and its protocol version. Each merge overwrites it. Earlier headers are pinned by the chain of header hashes.
  • Settlement takes the block’s deposit, withdrawal and transaction roots into a separate settlement UTXO. Users reference it to absorb deposits and pay out withdrawals. See Consensus.