report) step. This page traces that flow; for how blocks are ordered see
Consensus, and for where state lives see the
storage model.
Three phases: propose / verify / report
The consensus layer drives execution through three callbacks:| Phase | What runs | Effect on persistent state |
|---|---|---|
| propose | build a candidate block: run its txs speculatively, compute roots | none (rolled back) |
| verify | replay a peer’s proposed block the same way; confirm the roots match | none (rolled back) |
| report | the block is committed by consensus — apply the cached batch to the DB | commits |
propose and verify do the same speculative run and discard it; only
report writes. This is what lets a validator evaluate a block (and reject a bad
one) without ever dirtying its database.
The speculative run
propose/verify execute this sequence against an in-memory write-buffer
overlay on top of the committed state:
- begin batch — open a speculative overlay over current committed state.
- execute transactions — per-lane selection (System / Timer / Runner / User, see consensus lanes), then VRF ordering; each tx is dispatched, metered (Cycles + Cells), and its writes buffered.
- fire timers — timers whose target height is this block fire (end-of-block),
pre-charged to their
fee_payer. - sweep deferred — engine-generated deferred transactions (off-chain callbacks, mailbox delivery) that are due are swept in.
- compute roots — derive the new state root (BLAKE3), tx root, and receipt root from the buffered write set.
- cache — stash the computed batch + roots keyed by block.
- rollback — discard the overlay; persistent state is untouched.
report — the only commit
When consensus reports the block as committed, the engine applies the cached batch (from step 6) to the persistent QMDB in one shot, and feeds any produced deferred transactions back into the mempool for a future block. No re-execution happens atreport — it replays the already-computed write set,
so commit is cheap and deterministic.
Gas lanes & metering
Execution meters two independent resources — Cycles (compute) and Cells (data) — partitioned across the same lanes consensus uses (User / Runner / Timer / System), each with its own per-block budget and EIP-1559-style basefee. See the fee model for the dual-metered design and metering points for exactly where charges land.Deferred transactions
Off-chain work and cross-actor mailbox delivery don’t block a handler; they become deferred transactions the engine re-admits via the mempool (step 4 /report). Because that re-admission path is shared with user submission,
admission-level filters must exempt deferred/system-origin txs — they carry
payloads the protocol already produced, so dropping one would strand an actor’s
await-resume or an in-flight message. (Continuations are the developer-facing
form of this; see the runner continuation walkthrough.)
