Igor Mandrigin

Stateful vs stateless ZK proving

· 2 min read[zk, witnesses, stateless, provers]

Stateful vs stateless Ethereum asked one question: does a node need the full state to do its job, or can it work from a witness?

A witness is a self-contained slice of state. It ships with the block. You can verify it against the state root.

The same split exists inside zk proving. It played out the same way.

Before: stateful proving §

The Hermez prover in its research era was stateful. To prove a batch, it read the state as it went. So it sat coupled to a state database.

The costs are the same costs stateful Ethereum has:

  • State. The proving side has to hold it and maintain it.
  • Scaling. More provers means replicating the state.
  • Performance. State access leaks into proving time.

After: witness in, proof out §

With cdk-erigon, the model flipped. The node produces a witness — the exact slice of state a batch touches. The prover consumes it.

Proving becomes close to a pure function: batch plus witness in, proof out. No state database on the proving side. Provers scale out like any stateless worker.

Before: the prover reads state as it executes. After: the witness travels with the batch, and the prover is a pure funct
Before: the prover reads state as it executes. After: the witness travels with the batch, and the prover is a pure function.

The flip is in the commit logs §

You can watch it happen in both halves at once:

  • cdk-erigon grew SMT witness generation on January 17, 2024 (#50). eth_getWitness and the witness spec followed the same week.
  • Three days later the prover gained its first witness decoder (src/prover/witness.cpp, Jan 20).
  • Stateless batch proving merged on January 31, 2024 — PR #765, from a branch literally named erigon_witness.

Everything before that in the prover's history is coupled to its state database.

One detail I find satisfying. The format the pipeline ships is the first-generation, opcode-based witness from the stateless-Ethereum spec era. KV-Witness — my 2020 research — was the proposed second generation. Production picked gen one. The research lineage is the same either way.

The first-generation format. A witness is a small program: a stack machine executes the opcode tape and rebuilds the par
The first-generation format. A witness is a small program: a stack machine executes the opcode tape and rebuilds the partial trie — touched state as data, everything untouched as a hash.

Stateless Ethereum never shipped on L1. Its core mechanism ships every day inside zk rollups.

Where the idea shows up §

  • KV-Witness — the 2020 second-generation witness proposal: what a witness has to contain, and what a key-value shape buys over opcodes.
  • Semi-Stateless Initial Sync — using witnesses to pre-build caches and speed up sync; the same "ship the state slice, not the state" move.
  • Stateless Ethereum: Binary Tries Experiment — how trie shape drives witness size, measured on mainnet data.
  • cdk-erigon — the witness-based pipeline in production rollups.