Draft 0.4.0#625
Draft
Raid5594 wants to merge 29 commits into
Draft
Conversation
Reimplement the hints for ecrecover from ethproofs. Instead of having a new full implementation of ecrecover, this PR introduces "hooks" for 3 secp256k1 field operations. These hooks have two implmentations: default, where the implementation is straightforward (same implementation as before this PR) and oracle-based, where we use the new callable oracles. This way, most of the logic for ecrecover is reused. Given that this is a critical part of the system, the PR includes: * PBT for "good" case (showing equivalence when using the right oracle) * Tests for the "bad" case (showing panics if the oracle lies) * Modifies the fuzz target for ecrecover to compare the forward and oracle runs. I've ran the fuzzer for over 1h without finding issues. <!-- What are the changes this PR brings about? --> <!-- Example: This PR adds a PR template to the repo. --> <!-- (For bigger PRs adding more context is appreciated) --> <!-- Why are these changes done? What goal do they contribute to? What are the principles behind them? --> <!-- The `Why` has to be clear to non-Matter Labs entities running their own ZK Chain --> <!-- Example: PR templates ensure PR reviewers, observers, and future iterators are in context about the evolution of repos. --> - [ ] Yes - [ ] No <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted.
…coding (#572) ## What ❔ Remove the `artifacts_len` field and artifact bytes from the pubdata diff compression encoding: - **Format 0** (publish bytecode): remove `artifacts_len` field (4 bytes), publish only the raw code bytes (`unpadded_code_len`) instead of the full bytecode blob (code + padding + artifacts) - **Format 4** (not_publish_bytecode): remove `artifacts_len` from the length calculation — fixes a pre-existing bug where `diff_compression_length()` counted +4 bytes for `artifacts_len` but `diff_compression()` never actually wrote it - Bump `PUBDATA_ENCODING_VERSION` from 1 to 2 - Update format documentation comments and unit test ## Why ❔ Bytecode artifacts (jump table, etc.) are fully deterministic from the raw bytecode and do not need to be published in pubdata. Removing them reduces pubdata size for contract deployments without losing any information — the receiver can recompute artifacts from the code. ## Is this a breaking change? - [x] Yes - [ ] No This changes the pubdata encoding format (version 1 → 2). The settlement layer / receiver must be updated to parse the new format. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Claude Code <claude-code@anthropic.com>
## What ❔ Per-opcode EVM benchmarking infrastructure that collects gas, native resource, and RISC-V cycle stats for every EVM opcode execution. Enables computing cycles/gas and native/gas ratios to guide proving cost optimizations. **Components:** - `EvmOpcodeStatsTracer` — forward-mode tracer collecting per-opcode gas, native, count with min/max/median - Per-opcode cycle markers in the interpreter loop (`opcode_start!/opcode_end!`) — aggregated in `print_cycle_markers()` with min/max/median - Per-execution sample dump mode — write `(gas, native)` and `cycles` per execution for detailed ratio analysis - `join_samples.py` — joins tracer + cycle samples, computes per-execution cycles/gas with p50/p95/p99/max - `compare_opcode_stats.py` — CI integration: compact diff table when per-opcode stats change - `visualize_opcode_stats.py` — total cycle bar chart + sorted cycles/gas ratio curves - Integration into `eth_runner` single-run and CI bench workflow **Usage:** ```bash # Basic run (prints per-opcode stats table) bash bench_scripts/bench.sh quick # Full per-execution analysis OPCODE_SAMPLES_DIR=samples OPCODE_CYCLE_SAMPLES_DIR=cycle_samples bash bench_scripts/bench.sh quick python3 bench_scripts/join_samples.py samples/ cycle_samples/ --summary --out-dir joined/ python3 bench_scripts/visualize_opcode_stats.py joined/ --out-dir charts/ ``` **Benchmark impact:** +0.34% effective cycles with benchmarking features enabled. Zero overhead in production builds (all behind `#[cfg(feature = "cycle_marker")]`). ## Why ❔ To compute per-opcode `cycles/gas` and `native/gas` ratios for verifying the native resource model against actual RISC-V proving costs. ## Is this a breaking change? - [ ] Yes - [x] No All code is behind feature flags or in benchmarking-only paths. Production proving builds are unaffected — verified by audit of all changed files and benchmark comparison. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Antonio Locascio <antonio.locascio1@gmail.com> Co-authored-by: vv-dev-ai <vv@matterlabs.dev> Co-authored-by: Claude Code <claude-code@anthropic.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## What Add `compare_opcode_cycles.py` script and wire it into the bench CI workflow so that per-opcode RISC-V cycle diffs are posted on PRs. The bench CI already collected per-opcode cycle stats in `.bench` files on both the base and head sides (via `opcode_start!/opcode_end!` cycle markers), but had no script to compare them. The existing `compare_opcode_stats.py` only compared forward-mode gas/native stats, which don't change when the execution implementation changes without modifying resource accounting (e.g. the custom U256 PR). ## Why Without this, PRs that affect RISC-V execution performance (like the custom U256 migration) show overall effective cycle improvements in the benchmark report but lack visibility into which specific EVM opcodes improved or regressed. This makes it harder to review and reason about performance changes. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This PR changes the way we compute prover input. Before, we needed to run the slow risc-v simulator to do so. Now, we can do on native architecture. This run is also responsible for computing the pubdata. <!-- What are the changes this PR brings about? --> <!-- Example: This PR adds a PR template to the repo. --> <!-- (For bigger PRs adding more context is appreciated) --> <!-- Why are these changes done? What goal do they contribute to? What are the principles behind them? --> <!-- The `Why` has to be clear to non-Matter Labs entities running their own ZK Chain --> <!-- Example: PR templates ensure PR reviewers, observers, and future iterators are in context about the evolution of repos. --> - [ ] Yes - [ ] No <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted.
## What ❔ We had an invalid worst case calculation + small cleanup ## Why ❔ <!-- Why are these changes done? What goal do they contribute to? What are the principles behind them? --> <!-- The `Why` has to be clear to non-Matter Labs entities running their own ZK Chain --> <!-- Example: PR templates ensure PR reviewers, observers, and future iterators are in context about the evolution of repos. --> ## Is this a breaking change? - [ ] Yes - [ ] No ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the removed `risc_v_simulator` crate with `riscv_transpiler` from zksync-airbender dev branch (v2). This migrates the entire RISC-V execution and oracle infrastructure to the new VM API. **Dependencies & toolchain:** - `risc_v_simulator` removed from workspace, replaced by `riscv_transpiler` + `common_constants` (git deps pointing to airbender `dev` branch) - Toolchain bumped to `nightly-2026-02-10` in both root and `zksync_os/` (required by airbender v2's `blake2s_u32`) - `zksync_os/reproduce/Dockerfile` updated to match **oracle_provider:** - `ZkEENonDeterminismSource`, `OracleQueryProcessor`, and `ReadWitnessSource` are **no longer generic** over memory type - Processors take `&dyn RamPeek` instead of `&M` where `M: MemorySource` - `DummyMemorySource` now implements `RamPeek` - Implements new `NonDeterminismCSRSource` trait from `riscv_transpiler::vm` (with `write_with_memory_access`, `write_with_memory_access_dyn`) **callable_oracles:** - All query processors (`ArithmeticQuery`, `BlobCommitmentAndProofQuery`, `FieldOpsQuery`, `HashToPrimeSource`, and their `Native*` variants) simplified to non-generic structs - Memory reads use `peek_word(addr)` instead of `memory.get(addr, AccessType, &mut trap)` - Fixed pre-existing overflow check in `read_memory_as_u64` (now uses byte length for bounds check) **zksync_os_runner:** - Rewritten to use `VM::run_basic_unrolled` with `SimpleTape` + `RamWithRomRegion` - Requires `.bin` + `.text` file pair (already produced by `dump_bin.sh` via `objcopy --only-section=.text`) - `DiagnosticsConfig` parameter removed; flamegraph support via feature-gated `run_basic_unrolled_with_flamegraph` - `simulate_witness_tracing` rewritten using `SimpleSnapshotter` **cycle_marker:** - Fully wired to new `CycleMarkerHooks` API from [zksync-airbender#237](matter-labs/zksync-airbender#237) - `print_cycle_markers` now takes a `CycleMarker` argument (scoped via `CycleMarkerHooks::with()`) - Runner uses `VM::<DelegationsCounters, CycleMarkerHooks>` when feature is enabled - Re-exports `CycleMarkerHooks`, `CycleMarker`, `Mark` from `riscv_transpiler::cycle` - Inline asm now uses hardcoded `x0` to match transpiler's strict `csrrw x0, 0x7ff, x0` decoder **forward_system:** - All 12 query processors and system type aliases updated to non-generic oracle types **tests/rig:** - `flamegraph_output` wired through to `run_default_with_flamegraph_path` (replaces old `ProfilerConfig`) - Oracle factory trait methods return non-generic `ZkEENonDeterminismSource` - `run_prover` rewritten to use `execution_utils::unrolled::prove_unrolled_for_machine_configuration_into_program_proof` **Other:** - Removed stabilized `ptr_as_ref_unchecked` feature gate from `evm_interpreter` - Updated `Cargo.lock` for latest `zksync_os_interface` (adds `pubdata_used` to `BlockOutput`) - Rebuilt blake2s test binaries and committed `.text` files - Fixed pre-existing clippy lints (`sort_by_key`, `default_constructed_unit_structs`, `manual_checked_ops`, conditional `P256VerifyErrors` import) The `risc_v_simulator` crate was removed from zksync-airbender in [zksync-airbender#233](matter-labs/zksync-airbender#233) and [zksync-airbender#235](matter-labs/zksync-airbender#235). The new `riscv_transpiler` provides a more efficient VM with batch execution, optional JIT compilation (x86_64), and integrated witness snapshotting. This migration is required to stay on the airbender dev branch. - [x] Yes - [ ] No **Breaking API changes:** - `zksync_os_runner::run()` and `run_and_get_effective_cycles()` no longer take a `DiagnosticsConfig` parameter - `run_and_get_effective_cycles_from_bytes()` now requires both `img_bytes` and `text_bytes` - `ZkEENonDeterminismSource`, `ReadWitnessSource`, `OracleQueryProcessor` are no longer generic over memory type - `cycle_marker::print_cycle_markers()` now takes a `CycleMarker` argument instead of reading from a global - `MemorySource` trait replaced by `RamPeek` (re-exported from `riscv_transpiler::vm`) - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: antoniolocascio <antonio.locascio1@gmail.com>
## What ❔
Move RISC-V binary artifacts from flat files in `zksync_os/` (e.g.
`for_tests.bin`) to a structured `dist/<app>/app.{bin,elf,text}` layout
(e.g. `dist/for_tests/app.bin`).
## Why ❔
This prepares for the airbender-platform migration where `cargo
airbender build` outputs to this layout natively. Splitting this out as
a separate PR keeps the platform migration PR focused on the actual API
changes.
## Changes
- `dump_bin.sh`: output to `dist/<app>/` instead of flat files
- `chain.rs`: add `get_zksync_os_dist_dir()`, update path resolution
- `binary_checker`: update paths to `dist/<app>/app.text`
- `reproduce.sh`: copy from `dist/<app>/app.bin`
- `.gitignore`: add `/dist`
## Is this a breaking change?
- [ ] Yes
- [x] No
The build script output changes but all consumers are updated in this
PR.
## Checklist
- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] Tests for the changes have been added / updated.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## What ❔ - Removed unused storage-type markers/bitflags. - Split `storage_types` into focused modules. - Moved `MAX_EVENT_TOPICS` from storage types into system constants and updated imports. ## Why ❔ - Reduces dead code and improves module structure. - Places constants with the correct domain ownership for easier maintenance. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted.
## What ❔ Add tests that verify the system correctly validates and rejects invalid/malicious oracle responses. Covers two oracle validation areas: **Block metadata gas limit validation (4 tests):** - `test_block_rejects_excessive_gas_limit` — gas limit just above `MAX_BLOCK_GAS_LIMIT` is rejected - `test_block_accepts_max_gas_limit` — exact boundary value is accepted - `test_block_rejects_u64_max_gas_limit` — extreme overflow value is rejected - `test_empty_block_rejects_excessive_gas_limit` — validation fires before any transactions are processed **DA commitment scheme validation (2 tests):** - `test_da_commitment_scheme_accepts_all_valid_ids` — all valid IDs 0–4 are accepted - `test_da_commitment_scheme_rejects_invalid_ids` — IDs 5, 128, 255 are rejected ## Why ❔ Oracle responses come from an untrusted host and must be validated. These tests confirm that existing validation logic correctly rejects malicious metadata. Gas limit validation prevents resource accounting overflow (ergs = gas × 256). DA commitment scheme validation prevents use of undefined commitment modes. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Claude Code <claude-code@anthropic.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integrate airbender-platform into zksync-os (Phase 1), replacing direct dependencies on `riscv_transpiler`, `execution_utils`, and `prover_examples` with the platform's standardized build, execution, and proving pipeline. - `cargo airbender build` replaces `cargo build --target riscv32i` + `cargo objcopy` in `dump_bin.sh` - Target changed from `riscv32i-unknown-none-elf` to `riscv32im-risc0-zkvm-elf` - Build artifacts use `dist/<app>/` layout with `manifest.toml` (from prep PR #614) - `#[airbender::main(allocator_init = init_allocator)]` replaces manual boot assembly, `.data`/`.rodata` section loading, custom `memcpy.s`/`memset.s`, allocator init, and panic handler - CSR read/write uses `airbender::rt::sys::{read_word, write_word}` instead of `riscv_common` - `heapless` dependency removed; `quasi_uart` simplified accordingly - `TranspilerRunner` (via `Program::load` + `runner.run(&[u32])`) replaces direct `VM` usage - Runner now accepts pre-recorded `&[u32]` input instead of interactive oracle sources - `CpuProver` replaces manual `execution_utils` wiring for e2e proving - `FlamegraphOptions` preserved as public API; flamegraph support now unconditionally available via `airbender-host` - RISC-V run now consumes `prover_input_forward` (pre-recorded words from native run) directly - Interactive oracle wrapping (`ReadWitnessSource`) removed from the RISC-V run path - `simulate_witness_gen` feature removed - it was already obsolete, now became incompatible with new API - eth_stf path: uses `EthereumStorageSystemTypesWithPostOps` with `USE_ADVICE=true` and native callable oracles for prover-input recording - Added: `airbender-guest`, `airbender-host`, `airbender-sdk` (from `matter-labs/airbender-platform` rev `7e559f95`) - Removed: `common_constants`, `prover_examples`, `execution_utils`, `heapless`, `riscv_common` - Kept: `riscv_transpiler` at rev `73f46c2b` (transitive via `airbender-host`) - All workflows install `cargo-airbender` and use it for RISC-V builds - Blake test binaries built in CI instead of committed to git - `ZKSYNC_USE_CUDA_STUBS=true` added to all workflows - `EthereumStorageSystemTypesWithPostOps` changed `USE_ADVICE` from `false` to `true` -- ensures prover-input recording makes the same oracle advice queries (ecrecover/modexp) as the RISC-V proving binary - Native callable oracles (`NativeArithmeticQuery`, `NativeFieldOpsQuery`, `NativeBlobCommitmentAndProofQuery`) used for eth_stf prover-input recording since there is no guest memory to read during native execution - The witness equality check (`prover_input_forward == proof_input`) was removed -- in the new architecture the RISC-V run consumes `prover_input_forward` directly, making the comparison tautological - Crypto crate consolidation with `airbender-crypto` - Wire format migration to airbender-platform codec Airbender-platform provides a standardized, maintained build/run/prove pipeline. Direct dependency on low-level transpiler internals is fragile and duplicates platform functionality. This migration enables future improvements (JIT execution, codec migration, GPU proving) with minimal zksync-os changes. - [x] Yes - [ ] No Wire format is unchanged (still `UsizeSerializable`). Binary target changed from `riscv32i-unknown-none-elf` to `riscv32im-risc0-zkvm-elf`. - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…630) ## What ❔ Two small related cleanups to CI: 1. **Consolidate the toolchain setup into a single composite action.** The old `install-cargo-airbender` action only installed cargo-airbender, so every job using it repeated the same rust + `cargo install cargo-binutils` prelude. Rename to `.github/actions/setup-toolchain` and fold the rust toolchain install + `cargo install cargo-binutils` into it. The 3-step pattern at each call site becomes a single `uses:`. 2. **Migrate `bench-base` to `cargo airbender build`.** The merge-base now includes the airbender-platform migration (#619) so the old `riscv32i-unknown-none-elf` target-add + `|| for-tests` fallback are no longer needed. Setup is kept inline in `bench-base` because that job checks out the merge-base commit, which may predate the `setup-toolchain` composite action itself. ## Why ❔ Less boilerplate; single place to pin the airbender-platform rev used by CI. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR. - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a788be8 to
eef48f3
Compare
…oop (#631) ## What ❔ Block-level overheads (pubdata encoding envelope, future pre-tx-loop system work) must be visible to per-tx block-limit enforcement, not only to the final reported value. Seed block_data.block_pubdata_used and block_data.block_computational_native_used with BLOCK_INTRINSIC_* constants at pre-tx-loop start so check_for_block_limits enforces the true budget. Plumb both counters out through the result keeper via new record_block_native_used / record_block_pubdata_used hooks, so the forward path's BlockOutput.{computational_native_used, pubdata_used} are the bootloader's post-accumulation values rather than an independent per-tx sum (native) or a zero placeholder (pubdata). <!-- What are the changes this PR brings about? --> <!-- Example: This PR adds a PR template to the repo. --> <!-- (For bigger PRs adding more context is appreciated) --> ## Why ❔ <!-- Why are these changes done? What goal do they contribute to? What are the principles behind them? --> <!-- The `Why` has to be clear to non-Matter Labs entities running their own ZK Chain --> <!-- Example: PR templates ensure PR reviewers, observers, and future iterators are in context about the evolution of repos. --> ## Is this a breaking change? - [ ] Yes - [ ] No ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted.
## What Add Pectra (Prague) EVM execution compatibility to the ZK STF: - **Move precompiles to shared location:** Relocate EIP-2537 (BLS12-381) and EIP-152 (BLAKE2F) from `block_flow/ethereum/hooks/` to `bootloader/hooks/`, making them usable by both ZK and Ethereum STFs. The Ethereum hooks module re-exports from the shared location behind feature gates. - **Add `pectra` composite feature flag:** Enables all execution-affecting Pectra EIPs (`eip-7702`, `eip_7623`, `eip-4844`, `eip-2537`, `eip-152`). Propagated through `forward_system`, `rig`, and `evm_tester` crates. Also updates `eth_stf` to include the new `basic_bootloader` feature flags. - **Register precompiles in ZK STF:** Feature-gated initialization of BLS12-381 and BLAKE2F precompiles in `zk/post_init_op.rs`. - **Add `--hardfork` CLI flag to EVM tester:** Global override that takes precedence over per-test/per-directory hardfork settings, enabling `--hardfork Prague` runs. Balance check logic updated to allow full checking for Prague. ## Why The ZK STF (production) only supports Cancun, while the Ethereum STF (unreviewed) already has Pectra. We need Pectra execution compatibility in the ZK STF without taking unreviewed code to production. EIP-7702, EIP-7623, and EIP-4844 were already implemented behind feature flags — this PR moves the remaining precompiles (BLS12-381, BLAKE2F) to a shared location and wires up a single `pectra` feature to enable everything. Usage: ```bash cargo run --bin evm-tester --release \ --features "zksync_os_forward_system/evm_tester_pectra,zksync_os_forward_system/no_print" \ -- --hardfork Prague ``` ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Antonio Locascio <antoniolocascio@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## What ❔ Follow-up cleanup after #619 (airbender-platform migration). Builds on #630 (composite toolchain action + `bench-base` migration), which was split out and merged separately into `draft-0.4.0`. ### CI - **Drop the 10× crypto test loop** — run once, without `--quiet` so failures are readable. - **Remove `-j 3` throttling** across `ci.yml` and `bench.yml`. The flag caps `cargo`'s *build* parallelism to 3 and has no effect on test determinism (that would be `--test-threads`). The CI runners have plenty of cores. - **Speed up fuzzer regression**: - `cargo fuzz build -s none` drops AddressSanitizer for regression replay; this also skips the implicit `-Zbuild-std` (stdlib rebuild). - Drop the redundant `dump_bin.sh --type for-tests` step — `fuzz.sh regression` already does it via `prepare()`. - Replace `fuzz.sh install` (reinstalls cargo-binutils, cargo-airbender, rustfilt, lcov-util, and npm @lcov-viewer/cli) with a targeted `cargo install cargo-fuzz --locked`. - **Simplify `bench-base`** — now that the composite `setup-toolchain` action exists in the merge-base (#630), use it instead of inlining the rust + cargo-airbender setup. ### `reproduce.sh` rewrite Replace the Dockerfile-based reproduce pipeline with `cargo airbender build --reproducible` (which spawns its own pinned container per build and shares a cargo registry volume across builds). - Drop `zksync_os/reproduce/Dockerfile`. - `reproduce.sh` regenerates both `Cargo.lock` files (workspace + guest), then runs `dump_bin.sh --type <t> --reproducible` sequentially for every app type. - Sequential, not parallel: concurrent `--reproducible` builds race on the shared `airbender-cargo-registry` Docker volume (`.cargo-ok` / `.cache` mkdir conflicts). Proper fix belongs in `cargo-airbender` (multi-binary-per-container support). - Copy `dist/<app>/app.bin → zksync_os/<app>.bin` at the end for backwards compatibility with downstream consumers (release workflow, zksync-era). ### `zksync_os_runner` API cleanup Collapse `run` / `run_and_get_effective_cycles` / `run_with_flamegraph` into a single builder: ```rust zksync_os_runner::Runner::new(dist_dir) .with_cycles(1 << 25) // optional; default 1 << 36 .with_flamegraph(opts) // optional .run(&input_words); // -> RunResult { output, block_effective } ``` The default cycle limit is `1 << 36`, which is what every non-test caller was passing. `block_effective` is only populated when the `cycle_marker` feature is enabled. ### Script / binary cleanup in `zksync_os/` - Delete stale helper scripts (`dump_bin_manual.sh`, `objdump.sh`, `objdump_manual.sh`, `sections_layout.sh`, `show_asm.sh`, `build_release_std.sh`, `dump_bin_no_delegation.sh`) — all referenced the obsolete `riscv32i-unknown-none-elf` target, the `_manual` variants hardcoded macOS toolchain paths, and they don't work with the new `cargo airbender build` flow. - Fix `upd_local_era.sh` — source paths (`singleblock_batch.bin`) were broken since the move to `dist/<app>/app.bin` layout. ### Misc - Replace the local `QuasiUART` with airbender-platform's implementation. - Bump `airbender-platform` to `097f1489`. ## Why ❔ Cleaner post-migration state, and CI savings on jobs where every minute counts (fuzzer, bench). ## Is this a breaking change? - [ ] Yes - [x] No (`zksync_os_runner` API change affects only in-repo callers, all updated here.) ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Antonio Locascio <antonio.locascio1@gmail.com> Co-authored-by: vv-dev-ai <vv@matterlabs.dev> Co-authored-by: Claude Code <claude-code@anthropic.com> Co-authored-by: Vladislav Volosnikov <Volosnikov.apmath@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Lyova Potyomkin <lyova.potyomkin@gmail.com> Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com>
## What ❔ Bumps `airbender-platform` dependency from `097f1489` to `ff643be8` across all Cargo.toml files. ## Why ❔ Latest changes in `zksync-airbender` cause `airbender-platform` to not compile. This commit pins `zksync-airbender` in `airbender-platform`. Bench-base will still fail ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## What ❔ Removes the unused `callable_oracles::hash_to_prime` module and tightens `read_memory_as_u8` to require word-aligned offsets. ## Why ❔ `hash_to_prime` is not registered in the callable oracle wiring and its evaluator was unfinished. The only remaining caller of `read_memory_as_u8` already requires a 4-byte aligned pointer, so the helper now asserts the same contract instead of carrying an unused unaligned branch. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted.
## What ❔ Migrate from the local `crypto` crate to the upstream `airbender-crypto` from `airbender-platform`. The local crate is deleted and replaced with a workspace dependency using `package = "airbender-crypto"` aliased as `crypto` to avoid renaming imports. Depends on: matter-labs/airbender-platform#58 ## Why ❔ Consolidate cryptographic primitives in a single upstream crate (`airbender-crypto`) instead of maintaining a local fork. The upstream crate now includes hook support for oracle-based EC field operations needed by proving mode. ## Changes - Add `crypto` workspace dependency pointing to `airbender-crypto` via git - Delete local `crypto/` directory (109 files) - Update all per-crate Cargo.toml to use workspace dependency - Update `callable_oracles` field hints: method renames (`sqrt_in_place_inner` → `sqrt_in_place`, `invert_in_place_inner` → `invert_in_place`) - Update `ecrecover`: use `recover_with_hooks` for oracle path, hookless `recover` for non-oracle path - Update import paths: `crypto::secp256k1::FieldElement` → `crypto::secp256k1::field::FieldElement` (types not re-exported at secp256k1 level in airbender-crypto) - Update `crypto::sha3::Digest` → `crypto::MiniDigest` (Digest trait re-export changed) ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## What ❔ Migrates the EVM interpreter from `ruint::aliases::U256` to the custom non-`Copy` `u256::U256` and adds oracle-backed advice for MULMOD and DIV opcodes. ### Custom U256 migration (from PR #588, #598) - Custom U256 utilities in `zk_ee` (`custom_u256_utils`) - EVM interpreter stack, opcode, and frame state migration to non-Copy U256 - Forward system tracer boundary adaptation (lazy conversion to alloy U256) - Delegation feature wiring through the proving path - `push_u64`/`push_b160` for direct small-value stack writes - Specialized PUSH1 to skip bytereverse+shift overhead - Environment opcodes (chainid, timestamp, etc.) use `push_u64`/`push_b160` ### Oracle-backed MULMOD and DIV advice - New `U256_MULMOD_ADVICE_QUERY_ID` and `U256_DIV_REM_ADVICE_QUERY_ID` oracle queries - IOOracle-based advice functions in `zk_ee::utils::u256_arithmetic_advice` that work on both RISC-V and native (no raw CSR — uses `IOOracle::raw_query`) - Value-based query format (limbs serialized directly via `UsizeSerializable`) — same handler works for both `ArithmeticQuery` and `NativeArithmeticQuery` - `NativeArithmeticQuery` extended to serve both query IDs, keeping witness streams synchronized between RISC-V simulation and native prover-input runs ### Performance optimizations - `widening_mul_assign_into` with both halves from limbs instead of `widening_mul_assign` - Direct sub+borrow for `r < d` checks instead of `Ord::cmp` (saves 1 EQ delegation) - `write_be_bytes_into` for LOG topics and storage opcode boundary conversions (avoids clone+bytereverse delegation) - Limb-by-limb `i256_cmp` avoids clone+sub delegation in SLT/SGT same-sign comparison - `UsizeDeserializable` impl for `[T; N]` arrays ## Why ❔ The proving-oriented custom U256 reduces RISC-V cycle count by routing arithmetic through the prover's bigint delegation circuit instead of software implementations. Oracle advice replaces expensive software division (especially 512÷256 for MULMOD) with a hint+verify pattern that costs fewer delegation calls. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: vibelyova <vibelyova@proton.me> Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
#646) ## What ❔ Specialize the PUSH2 opcode in the EVM interpreter, mirroring the existing PUSH1 specialization. The generic `push<const N: usize>()` path copies bytecode bytes into a `U256`, byte-reverses the full 32-byte value, and right-shifts off the unused high bytes. For a 2-byte payload that already fits in a `u64`, all of that is wasted work. The new `push2()`: - Reads up to 2 big-endian bytes from the bytecode (zero-padding missing trailing bytes, matching the generic path's right-padding semantics on truncated bytecode). - Assembles a `u64` and pushes it directly via `EvmStack::push_u64`. - Bypasses the U256 copy + bytereverse + shift. Dispatch in `interpreter.rs` swaps `self.push::<2>()` for `self.push2()`. ## Why ❔ PUSH2 was the third-largest sampled opcode cost in profiling of the `custom-u256` branch (~5.2% of opcode cycles in `block_19299001`), and the structure of the work matched the PUSH1 specialization pattern already in the tree. Removing the bytereverse + shift round-trip brings PUSH2 to parity with PUSH1 in cycles, which translates to a measurable block-level reduction in proving cost. ### Benchmark `bench_scripts/bench.sh compare`, baseline = `custom-u256` at HEAD: | Block | Base Eff | Head Eff | Δ | |-------|----------|----------|---| | `block_19299001` | 210,947,355 | 208,664,035 | **−1.08%** | | `block_22244135` | 139,404,849 | 134,713,085 | **−3.37%** | Per-opcode (block_19299001, 107,945 PUSH2 executions): - PUSH2 median cycles: 144 → 67 (**−48.5%**) - PUSH2 total cycles: −7.23M (−48.8%) - Delegations (Blake / BigInt / Keccak): unchanged - No regressions visible on other opcodes (noise only on low-count ops) Note: `block_23292836` fixture is missing locally so it's not in the comparison. ## Is this a breaking change? - [ ] Yes - [x] No No protocol-visible behavior change. Gas and native cost charging are identical (`gas_constants::VERYLOW`, `PUSH_NATIVE_COSTS[2]`). The pushed value is bit-for-bit identical to the generic path on all inputs, including the truncated-bytecode edge case where the missing low byte is zero-padded. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - Existing tests cover PUSH2 behavior (Ethereum spec fixtures + interpreter rig tests). No semantic change → no new tests needed. Verified locally: `cargo test -p evm_interpreter` (13/13), `tests/instances/evm` (14/14), `tests/instances/unit` (46/46). - [x] Documentation comments have been added / updated. - [x] Code has been formatted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What ❔ Move `evm_tester`, `evm_divergence_validator`, `eth_runner`, and `nostd_compression` from workspace `exclude` into `members`, and introduce `default-members`. Only `zksync_os` and `circuit_test_program` (RISC-V targets) remain excluded. `default-members` includes all previously-existing workspace members (core crates + test infrastructure + test instances). The three newly added tool crates (`evm-tester`, `evm_divergence_validator`, `eth_runner`) are non-default because they enable conflicting features on `forward_system` via `rig` that break other tests through workspace feature unification. They have their own dedicated CI jobs. Changes: - Relax `evm_tester` exact version pins, convert shared deps to `workspace = true` - Remove `web3` dependency from `evm_tester` (replaced with `alloy` types), eliminating vulnerable transitive deps (`idna`, `rustls-webpki`) - Convert `eth_runner` and `evm_divergence_validator` deps to workspace refs - Remove standalone `Cargo.lock` files (now using workspace lockfile) - Set `airbender-host` `default-features = false` at workspace level; `zksync_os_runner` explicitly opts into `gpu-prover` - Fix all clippy warnings in newly added crates - Add CI clippy and cargo-deny jobs for the excluded `zksync_os` RISC-V crate - Fix pre-existing clippy issues (`useless_conversion` in `mock_precompiles`, `unit_arg` in `zksync_os`) ## Why ❔ Previously excluded crates had independent dependency resolution, duplicated `Cargo.lock` files, couldn't use `[workspace.dependencies]` or `[patch]`, and weren't covered by `cargo-deny` or `clippy`. Moving them into the workspace gives unified dependency management, removes ~16k lines of duplicated lockfile, and surfaces vulnerabilities that were previously hidden. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## What ❔ Adds four cycle-marker labels in the STF that the benchmarking pipeline relies on: - `keccak_execution_environment` — wraps the EVM SHA3 opcode dispatch (incl. the `len == 0` empty-slice shortcut) - `ecrecover_execution_environment` — wraps the EE-precompile ecrecover dispatch via a new `EcRecoverEEInvocation` wrapper - `da_commitment` — wraps the per-block `write_pubdata` call (keccak-DA absorbs there; blob-DA appends + KZG fires later under the pre-existing `blob_versioned_hash` marker) - `state_commitment_update` — renamed from `verify_and_apply_batch` to reflect what the marker actually wraps (the state-tree merkle commit, distinct from DA commit and per-blob KZG) Also extracts `install_precompile_hook` from `add_precompile_ext` so the `PRECOMPILE_ADDRESSES_LOWS` sanity check stays centralized for any future custom invocation type. ## Why ❔ Split out from #645 so the STF instrumentation can be reviewed without wading through the CI workflow, joiner scripts, tracers, and docs that consume the markers. Pure observability: no state-transition behavior changes. The new markers fire only on EE-initiated invocations, so they don't double-count the bootloader's intrinsic keccak/ecrecover calls. The benchmarking pipeline (CI + bench_scripts + forward-system tracers + docs) follows in a separate PR rebased onto this branch. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What ❔ End-to-end benchmark pipeline that consumes the STF cycle markers added in #656. - `cycle_marker`: per-execution `<label>.cycles` (raw) and `<label>.effective.cycles` (raw + delegation weights) dumps; weighting uses the existing `process_block` formula (`raw + 16×Blake + 4×BigInt + 4×Keccak`). - `forward_system`: `Pair` tracer combinator + `PrecompileStatsTracer` (per-precompile gas/native, dump samples parallel to `EvmOpcodeStatsTracer`). - `bench_scripts/`: shared `benchlib.py`; `compare_*` / `join_*` scripts; `cycles_per_native_report.py` for local cycles/native ratio reports. - Test scaffolding: `tests/rig/src/chain.rs` `SeqLabelsGuard` (needed under `BlobsZKsyncOS` DA where `blob_versioned_hash` fires only in proving mode); `eth_runner` tracer composition + `BENCH_DA_SCHEME`; precompile sweep tests. - `.github/workflows/bench.yml`: full bench job — both DA schemes, `for-tests-benchmarking-pectra` proving binary, headline + collapsible PR comment, merge-base fallbacks for graceful degradation against older base commits. - `bench-fast` profile (root + `eth_runner` mirror) to speed up host-side bench builds. - `docs/benchmarking.md`: rewrite as agent-targeted reference. ## Why ❔ Split from the original #645 so reviewers can scrutinize the STF instrumentation in #656 (the small / security-relevant half) separately from this pipeline scaffolding (CI/scripts/tracers/docs/test rigging — review-skim). Once #656 lands, this PR's base auto-retargets to `draft-0.4.0`. ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What ❔ `apply_write_impl` returned `(V, V)` where the second element (`val_at_tx_start`) was ignored at all three callers (one had `#[allow(unused_variables)]`, two used `_`). Drop it. With the second return gone, `refund_for_storage_write` is moved before `addr_data.update(...)` so `val_at_tx_start` and `val_current` can stay borrowed straight from `addr_data` — eliminating the `val_at_tx_start.clone()` and the redundant `addr_data.current().value().clone()`. Body V clones: 2 → 1. ## Why ❔ Reduces wasted work in the SSTORE / SLOAD hot path. The cleanup also removes an `#[allow(unused_variables)]` smell at the caller site. Bench (`bench_scripts/bench.sh` on `block_19299001` / `block_22244135`): | Block | Eff cycles Δ | Raw cycles Δ | |---|---|---| | `block_19299001` | −0.036% (−74K) | −0.047% (−74K) | | `block_22244135` | −0.037% (−49K) | −0.046% (−49K) | Per-opcode: `SSTORE` median −3.8% (2,355 → 2,266), total −3.5% (~85K cycles across 950 SSTOREs). All Blake / BigInt / Keccak delegation counts unchanged — no behavior drift in the proven path. ## Is this a breaking change? - [ ] Yes - [x] No (Internal API — only the three in-tree callers of `apply_write_impl`.) ## Checklist - [x] PR title corresponds to the body of PR. - [x] Tests for the changes have been added / updated. (No new tests; existing `basic_system` unit suite + block replay cover the path. Pre-existing MPT test failures on `draft-0.4.0` are unrelated and reproduce on the unmodified parent branch.) - [x] Documentation comments have been added / updated. - [x] Code has been formatted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What ❔ Replaces `Bytes32`'s `Ord` impl on **the RISC-V proving target only** with a word-by-word equality scan over the underlying `inner: [usize; BYTES32_USIZE_SIZE]` (N=4 on 64-bit, 8 on RISC-V32): - Equal-prefix iterations stay in the fast path: load word, compare word, branch. - On the first differing word, resolve byte-lex order by walking the bytes of just that word — cheaper than `swap_bytes()` on RV32 without the Zbb extension (which this target does not enable). - `cmp` / `partial_cmp` are `#[inline]` since they sit on the BTreeMap descent hot path. On non-RV32 targets (forward / sequencer host) the impl falls back to the original `as_u8_array_ref().cmp(...)`. libc's `memcmp` is already SIMD-vectorized (SSE2/AVX/NEON), so the byte path beats a pure-Rust word loop on the host. The chunked helper (`cmp_word_chunked`) is still compiled on every target so the equivalence tests can validate it on the host. Affected: - `zk_ee/src/utils/bytes32.rs` ## Why ❔ From the flamegraph analysis on `draft-0.4.0`: - `impls::compare_bytes` is the **second-highest self-cost function in the binary at 6.47 %**. On no-std RISC-V the `<[u8]>::cmp` path falls back to `compiler-builtins`' generic `memcmp` (`compiler-builtins/src/mem/impls.rs:388`) — a plain byte loop with no chunking. - Almost all of that self-cost is reached through `Bytes32::cmp` (directly, or via `WarmStorageKey::cmp` → `Bytes32::cmp`) sitting inside `NodeRef::find_key_index` in HistoryMap / preimage / FlatStorageCommitment lookups. Comparing word-aligned 32-byte values byte-by-byte is wasteful when the struct is already a `[usize; N]` with `align(8)`. Forward mode doesn't need the rewrite because libc memcmp already handles it efficiently. ## Benchmark results Branch vs `origin/draft-0.4.0` (commit `59bdedfa`): | Block | Base eff | Head eff | Δ eff | Δ raw | |---|---|---|---|---| | `19299001` | 208,601,280 | 204,648,699 | **−1.89 %** | **−2.49 %** | | `22244135` | 134,741,585 | 132,504,954 | **−1.66 %** | **−2.10 %** | Blake / Bigint / Keccak delegation counts unchanged in both runs — pure raw-cycle reduction. ### Variant comparison (RV32 only — host path is unchanged) | Variant | block 19299001 Δ eff | block 22244135 Δ eff | |---|---|---| | word-cmp + `to_be()` bswap on mismatch | −1.56 % | −1.39 % | | **word-cmp + `#[inline]` + byte-fallback (this PR)** | **−1.89 %** | **−1.66 %** | | word-cmp + 2-word XOR-OR fusion | −1.68 % | −1.45 % | The 2-word XOR-OR variant regresses vs the simple loop — the extra arithmetic per executed iteration doesn't pay for the halved branch count on RV32. Picked the byte-fallback variant. ## Is this a breaking change? - [ ] Yes - [x] No Public API of `Bytes32` is unchanged. `Ord` / `PartialOrd` impls produce identical orderings to the previous implementation on every target (verified by `cmp_tests::cmp_matches_byte_lex_on_pseudorandom_pairs`, which invokes `cmp_word_chunked` directly so the helper is exercised on the host too). ## Stackability with #668 / #669 This PR targets the leaf `compare_bytes` cost; #668 / #669 target the BTreeMap lookups themselves on the pending-list paths. They hit different code regions and are expected to compose (overlap only where BTreeMap node descent invokes `Bytes32::cmp` — and even there the per-compare cost goes down). ## Checklist - [x] PR title corresponds to the body of PR. - [x] Tests for the changes have been added / updated. (Equivalence tests added: `cmp_matches_byte_lex_on_handcrafted_pairs`, `cmp_matches_byte_lex_on_pseudorandom_pairs`. Both invoke `cmp_word_chunked` directly so the chunked path is exercised on the host.) - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What ❔ Adds FRI precompile to zksync-os. FRI proofs submitted in the sidecar with FRI transactions are checked during transaction validation and the call to precompile within the same transaction reveals whether the proof is valid (under current assumptions, transactions that include invalid proofs are dropped from the block). <!-- What are the changes this PR brings about? --> <!-- Example: This PR adds a PR template to the repo. --> <!-- (For bigger PRs adding more context is appreciated) --> ## Why ❔ The goal is to add a new tx type, that would allow GW users to submit FRI proofs along the transaction in the sidecar. This would in turn, enable faster interop. <!-- Why are these changes done? What goal do they contribute to? What are the principles behind them? --> <!-- The `Why` has to be clear to non-Matter Labs entities running their own ZK Chain --> <!-- Example: PR templates ensure PR reviewers, observers, and future iterators are in context about the evolution of repos. --> ## Is this a breaking change? - [x] Yes - [ ] No ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Antonio Locascio <antonio.locascio1@gmail.com> Co-authored-by: vv-dev-ai <vv@matterlabs.dev> Co-authored-by: Claude Code <claude-code@anthropic.com> Co-authored-by: Vladislav Volosnikov <Volosnikov.apmath@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Lyova Potyomkin <lyova.potyomkin@gmail.com> Co-authored-by: vibelyova <vibelyova@proton.me> Co-authored-by: vibelyova <265594496+vibelyova@users.noreply.github.com>
## What ❔ Migates to interface v0.1.3 ## Why ❔ <!-- Why are these changes done? What goal do they contribute to? What are the principles behind them? --> <!-- The `Why` has to be clear to non-Matter Labs entities running their own ZK Chain --> <!-- Example: PR templates ensure PR reviewers, observers, and future iterators are in context about the evolution of repos. --> ## Is this a breaking change? - [ ] Yes - [x] No ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted.
## What ❔ Brings the **Fusaka (Osaka)** hardfork to `draft-0.4.0` — validated on the Ethereum execution-spec tests and benchmarked on real post-BPO mainnet blocks. **EIPs** (rebased from #589; the ~29 Pectra-groundwork commits are dropped — already on `draft-0.4.0` via #552): EIP-7939 (CLZ), 7823 (modexp input limit) + modexp repricing, 7825 (per-tx gas cap), 7934 (block RLP limit), 7918 (blob base-fee reserve), per-tx blob validation, behind a `fusaka` feature flag. **Validation** - EVM execution-spec tester now defaults to Fusaka and is **green** (0 failures). Required fixing the EIP-7623 intrinsic-native bound, cache-warmth tracking, and mock-precompile gating; the latest BPO blob schedule sits behind a compile-time `fusaka-blobs` feature. Intentional L2 divergences (beacon-chain L1 requests / withdrawals) and two replay-unsupported EIP-7934 cases are suppressed in the indexes. - Benchmarks now run **ten representative Osaka blocks** (covering EIP-7702, BLOCKHASH, blob/BPO, BLS12-381, precompiles), replacing the two Cancun fixtures. Each passes forward execution + RISC-V proving against the Ethereum reference. **`eth_runner` replay fixes** (needed to bench real Osaka blocks): process EIP-7702 (type-4) txs, supply the 256 `BLOCKHASH` ancestors, compute the blob base fee with the fork's `BLOB_BASE_FEE_UPDATE_FRACTION`, and correct prestate reconstruction for accounts created mid-block, and capture EIP-7702 delegate-target code the prestate tracer omits. The bench PR comment now reports the per-block **average** cycles, with the per-block breakdown under a spoiler. ## Why ❔ Lands the Fusaka EIPs on the current base without re-introducing already-present Pectra changes, and backs them with spec-test + real-block-replay validation so the Osaka semantics are proven correct on the RISC-V proving target. The Osaka bench fixtures keep performance tracking representative of current mainnet. ## Is this a breaking change? - [x] Yes - [ ] No ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted. --------- Co-authored-by: Antonio Locascio <antoniolocascio@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What ❔
Why ❔
Is this a breaking change?
Checklist