Skip to content

feat: continuously processing blocks - #13

Merged
eigmax merged 1 commit into
ProjectZKM:mainfrom
felicityin:continues
Mar 25, 2026
Merged

eigmax merged 1 commit into
ProjectZKM:mainfrom
felicityin:continues

Conversation

@felicityin

@felicityin felicityin commented Mar 25, 2026 •

Copy link
Copy Markdown
Collaborator

To execute blocks in parallel, use the continuous binary. See the example in bin/continuous/ for usage.

The number of blocks executed in parallel can be customized with the MAX_CONCURRENT_EXECUTIONS environment variable.

ZKM_DUMP=1 RUST_LOG=info cargo run -r --bin continuous -- --block-number <START_NUMBER> --rpc-url <RPC_URL> --chain-id <CHAIN_ID>

@eigmax
eigmax merged commit cc6af1d into ProjectZKM:main Mar 25, 2026
1 check passed
eigmax added a commit that referenced this pull request Oct 21, 2026
* modify build to use llvm specific optimise (#2)

* chore: update deps to fix goat prague hardfork

* fix: error TransferError::CreateCollision in revm

* chore: upgrade ziren to v1.1.2

* chore: upgrade ziren to v1.1.3

* fix serde

* fix: disable rpc_db.preload_accounts_and_storage()

* chore: upgrade deps

* perf: reduce guest cycles

* chore: upgrade alloy-primitives to v1.4.1

* perf: set the elf id only once

* style: cargo clippy

* chore: upgrade ziren to v1.2.3

* feat: goat osaka hardfork (#6)

* fix: goat system tx err

* feat: continuously processing blocks (#13)

* chore: cache a smaller block (#18)

* chore: upgrade ziren to v1.2.7 (#19)

* chore: upgrade ziren to v2.0

The Ziren crates are git dependencies on Ziren's default branch; the
lockfiles pinned it at c736a41c (host) and 7c2071ea (guest), both 1.2.5.
Move both to the current main (2.0.0), which the provers now run. The
precompile forks stay at the locked commits that declare Ziren without a
tag, so each lockfile holds one Ziren source.

* feat: integrate the Ziren 2.0 EthProofs client into a durable Fleet worker

* fix: accept structured execution witness headers from live Geth

* fix: preserve untouched storage roots and remove empty accounts

* fix: accept omitted authenticated empty storage in guest witnesses

* Revert "merge: resolve main conflicts while retaining Ziren 2.0 Fleet worker"

This reverts commit fd9589c, reversing
changes made to 41317cd.

* fix: use the reth ELF name in the host cycle-count test

* feat: follow the latest Ethereum head without proving the backlog

* fix: reconcile duplicate reports against published proof bytes

* Overlap latest-head witness preparation with serial proving

* Retry latest-head preparation while witness RPC catches up

* Recover verified bytecode omitted from execution witnesses

* Enable gzip responses for execution witness RPC

* EthProofs worker: the optimized guest (in-guest JUMPDEST table, zkVM syscalls) (#26)

* Prepare consecutive EthProofs blocks in parallel

* guest: the optimised guest line in the Ziren 2.0 EthProofs worker

The Fleet worker (4849354, chore/ziren-v2-stateless + fix/ethproofs-consecutive)
forked from the guest optimisation line at 9215aa6 and shipped the older guest:
no in-guest JUMPDEST table (the host's revm JumpTable was trusted under a code
hash that covers only the code bytes), no zkVM syscalls for 256-bit arithmetic
and the curves, no arena tries. This squashes perf/guest-hashed-key-memo (7147f4e:
feat/guest-syscalls 4a15fee plus the trie-key memo and the checked logs bloom).

Resolution:
- bin/eth-proofs, the root Cargo.toml and Cargo.lock: the worker's. The worker
  keeps the git-locked Ziren 2.0 graph; the opt line's sibling-checkout [patch]
  section is dropped.
- Guest, mpt and the witness RPC db: the opt line's. The worker's
  2c0245a (preserve untouched storage roots, remove empty accounts) was already
  in ArenaState::update; its 41317cd (omitted storage of an absent account or
  an authenticated empty storage root reads zero, any other missing storage
  trie is an error) is now ArenaState::storage, with its three tests.
  a75cb33 (verified bytecode recovery) is the opt line's complete_account_code;
  the duplicated structured-header decoder is kept once.
- bin/guest keeps the opt line's graph (precompile forks); its zkm-zkvm/zkm-lib
  [patch] points at the sibling Ziren checkout, whose guest-side crates
  (crates/zkvm, crates/build) are identical to 0dd65a15 and 31f6e8eb.

Validation:
- cargo test -p mpt: 24 passed (the arena storage rule and the update rule).
- host (this tree) fetched and executed 26184581-26184583 natively: 278.70M,
  269.57M, 52.72M cycles, block hashes as the chain's.
- GPU, one card through Fleet (image e786dd = Ziren 31f6e8eb), guest
  941629f6: 53.73/53.40/18.01 s, every proof verified against a 31f6e8eb
  client, public values identical to the deployed guest's
  (334b45b8: 73.97/73.64/20.61 s on the same blocks, -24.5% overall).

* perf(guest): bind the chain to mainnet, gate the precompile tracker

The proof commits only the block hash, so the chain spec and the
beneficiary override in the input came from the prover unchecked. The
guest now accepts mainnet inputs only, with no custom beneficiary.

The cycle-tracker wrapper around every precompile call turned the
precompile set into a map probed on each call. It is now behind the
precompile-tracking feature, for profiling builds.

Measured on the executor (blocks 26184948 / 26184949, same committed
hashes): cycles -0.19% / -0.28%, main-trace area -0.11% / -0.16%.

* perf(guest): walk the JUMPDEST map in assembly on the zkVM

The guest derives every executed code's jump table itself, a walk over
~3 M opcodes per mainnet block. Compiled, the walk is nine instructions
per opcode, two of them nops in branch delay slots. jumpdest.s fills the
slots (the cursor advance, and the next opcode's load, which reads at
most 32 bytes into the code's zero padding): six per opcode. Off the
zkVM the Rust walk stays.

Checked in the executor against the Rust walk on every code of two
mainnet blocks and 2,000 random codes. Measured (blocks 26184948 /
26184949, same committed hashes): cycles -1.39% / -1.79%, main-trace
area -0.80% / -1.00%.

* perf(guest): revm fork with cheaper dispatch and jumps

Moves the guest to the fork's patch-31.0.2-mips32-dispatch branch, which
adds to the 32-bit fast paths: static gas charged on the low word of the
remaining gas, JUMPDEST folded into the taken jump that lands on it, and
PUSH2 + JUMP / JUMPI run as one instruction.

Measured on the executor (blocks 26184948 / 26184949, same committed
hashes): cycles -3.20% / -3.44%, main-trace area -2.06% / -2.16%.

* deps: Ziren from perf/shamir-msm

Every Ziren dependency now names the perf/shamir-msm branch (Ziren
#562: Shamir's trick in the zkVM lib's two-point MSM, which ECDSA
recovery runs per transaction), and the guest's comment says the Ziren
checkout next to this repo, which its zkvm crates come from, is to be
on that branch.

The precompile patches still declare Ziren unbranched, and cargo cannot
redirect a git source to another branch of it, so the lockfile also
keeps their main-branch zkm-lib, zkm-primitives and zkm-zkvm. Those
edges exist only for the zkVM target, where the guest's path patch
replaces both with the one checkout. Back to main when #562 lands.

Measured on the executor (blocks 26184948 / 26184949, same committed
hashes): main-trace area -1.83% / -1.71%, cycles -1.05% / -1.00%.

* deps: Ziren from perf/glv-msm, revm compare + PUSH2 + JUMPI fusion

Ziren moves to perf/glv-msm (Ziren #563, stacked on #562): the zkVM
lib's secp256k1 two-point MSM uses the GLV endomorphism, about half the
doublings and two thirds of the additions per signature recovery, each a
precompile call. The guest's revm fork moves to 2a9844a0 on
patch-31.0.2-mips32-dispatch (ziren-patches/revm#4): ISZERO / EQ / LT /
GT + PUSH2 + JUMPI run as one instruction, and the stack pushes in
place. The lock also picks up the bn patch's newer branch tip, whose
only change is its zkm-lib dependency losing a pinned tag; the guest
path-patches zkm-lib, so its code is unchanged.

Measured on the executor (blocks 26184948 / 26184949, same committed
hashes) against the previous commit: cycles +0.46% / +0.34%, main-trace
cells -0.23% / -0.26%. On one GPU, with every proof verified, proving
time is -1.4% / -5.6% (GLV alone -2.5% / -5.0%): a secp256k1 precompile
call costs about 30 us there, far more than its cells suggest.

* deps: Ziren from perf/shamir-msm (Ziren #562)

The Ziren optimizations are one pull request now, #562 on
perf/shamir-msm, so every Ziren dependency names that branch. The lock
stays at 8a9ab4fe, the GLV commit this guest was built and measured
with: the branch goes on to change the keccak AIR, which the client
must not pick up before the GPU prover does. The guest ELF is
unchanged (766ff6ce).

---------

Co-authored-by: weilzkm <140377101+weilzkm@users.noreply.github.com>
Co-authored-by: Jingping Yin <yinjingping2022@gmail.com>
Co-authored-by: Blake <blake.h@zkm.io>
Co-authored-by: Ubuntu <ubuntu@ip-10-20-100-196.us-west-2.compute.internal>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants