diff --git a/.github/workflows/benchmark-pr.yml b/.github/workflows/benchmark-pr.yml index b9da23925..56fa23e5b 100644 --- a/.github/workflows/benchmark-pr.yml +++ b/.github/workflows/benchmark-pr.yml @@ -70,10 +70,12 @@ env: ELF: executor/program_artifacts/rust/ethrex.elf # The workload: a real Ethereum block. WHICH block lives in # the Makefile and nowhere else — nothing in this file names one, so a repoint - # moves this job without editing it. At the current default that is 50.78M cycles, - # 10,478 keccak calls and 116 ecsm calls: ~5.8x the work of the synthetic block with a - # ~18x different keccak:ecrecover mix. That is the whole point — a prover change - # can move the synthetic number and the real one in opposite directions. + # moves this job without editing it. At the current default and pinned ethrex rev that + # is 30,498,818 cycles, 10,659 keccak calls and 116 ecsm calls — several times the work + # of the synthetic block, at a very different keccak:ecrecover mix. That is the whole + # point: a prover change can move the synthetic number and the real one in opposite + # directions. All three figures move with the ethrex rev, so re-measure on a bump + # rather than carrying them across one. # # The path is resolved from the Makefile (`make -s print-real-block-fixture`) into # REAL_INPUT at run time. The ~1 MB .bin is gitignored and FETCHED by URL + sha256 @@ -191,11 +193,13 @@ jobs: - name: Generate ethrex bench fixtures run: | - # Generated, not committed (gitignored via executor/.gitignore). They are - # untracked, so they survive the baseline `git checkout origin/main` below — - # the SAME workload (ELF + inputs) is proven on both the PR and main sides. + # Generated, not committed (gitignored via executor/.gitignore) — except + # ethrex_bench_4.bin, which the same file re-includes and is therefore tracked. + # The gitignored ones survive the baseline `git checkout origin/main` below on + # their own; bench_4 is restored explicitly there. Either way the SAME workload + # (ELF + inputs) is proven on both the PR and main sides. # distinct = N independent genesis-funded senders -> N distinct recipients. - ( cd tooling/ethrex-fixtures && cargo build --release ) + ( cd tooling/ethrex-fixtures && cargo build --locked --release ) GEN=tooling/ethrex-fixtures/target/release/ethrex-fixtures for n in $GROWTH_STEPS; do "$GEN" "$n" "executor/tests/ethrex_bench_${n}.bin" distinct @@ -459,6 +463,11 @@ jobs: echo "real_time_spread=$TIME_SPREAD" echo "real_all_times=$ALL_TIMES" echo "real_input=$(basename "$REAL_INPUT")" + # The basename is derived from network+block, so it is a complete key for + # WHICH block but not for which bytes: the archived ProgramInput layout moves + # with the ethrex rev, so one basename can name two byte streams. The digest + # is what makes the comparison guard below able to see a fixture swap. + echo "real_input_sha=$(sha256sum "$REAL_INPUT" | cut -c1-12)" } | tee -a /tmp/metrics.txt >> "$GITHUB_OUTPUT" - name: Upload metrics artifact @@ -491,7 +500,8 @@ jobs: # grep could match two lines and write a multi-line step output. get() { grep "^$1=" "$BASELINE_FILE" | head -1 | cut -d= -f2; } for key in growth_heaps growth_slope_mb growth_r2 \ - real_time_s real_peak_mb real_time_spread real_input; do + real_time_s real_peak_mb real_time_spread real_input \ + real_input_sha; do # A baseline predating the real block simply has no real_* keys; empty # values hide the table rather than producing a bogus comparison. echo "$key=$(get "$key")" >> "$GITHUB_OUTPUT" @@ -521,11 +531,19 @@ jobs: PR_SHA=$(git rev-parse HEAD) # Checkout main and rebuild the prover (CLI) only. The workload — the gitignored - # ethrex ELF and the generated, untracked bench fixtures — is left untouched by - # the checkout, so the same inputs are proven on both the PR and main sides. + # ethrex ELF and the real-block fixture — is left untouched by the checkout, so + # the same inputs are proven on both the PR and main sides. git fetch origin main git checkout origin/main + # ...with one exception: ethrex_bench_4.bin is TRACKED (executor/.gitignore + # re-includes it), so the checkout above replaces it with main's copy. The + # generator is deterministic, so the file is clean against HEAD and the checkout + # succeeds silently. On a PR that bumps the ethrex rev those bytes are a + # different archive layout, and bench_4 is index 0 of GROWTH_PROGRAMS — the + # point would be a fabricated delta. Put the PR's copy back. + git checkout "$PR_SHA" -- executor/tests/ethrex_bench_4.bin + cargo build --release -p cli --features jemalloc-stats # --- Growth benchmarks (default parallelism, 1 sample each) --- @@ -642,6 +660,7 @@ jobs: BA_REAL_PEAK: ${{ steps.baseline-artifact.outputs.real_peak_mb }} BA_REAL_SPREAD: ${{ steps.baseline-artifact.outputs.real_time_spread }} BA_REAL_INPUT: ${{ steps.baseline-artifact.outputs.real_input }} + BA_REAL_INPUT_SHA: ${{ steps.baseline-artifact.outputs.real_input_sha }} # Baseline run outputs BR_GROWTH_HEAPS: ${{ steps.baseline-run.outputs.growth_heaps }} BR_GROWTH_SLOPE: ${{ steps.baseline-run.outputs.growth_slope_mb }} @@ -657,6 +676,7 @@ jobs: PR_REAL_PEAK: ${{ steps.pr-real.outputs.real_peak_mb }} PR_REAL_EPOCHS: ${{ steps.pr-real.outputs.real_epochs }} PR_REAL_INPUT: ${{ steps.pr-real.outputs.real_input }} + PR_REAL_INPUT_SHA: ${{ steps.pr-real.outputs.real_input_sha }} PR_REAL_RUNS: ${{ steps.pr-real.outputs.real_runs }} PR_REAL_TIME_SPREAD: ${{ steps.pr-real.outputs.real_time_spread }} PR_REAL_ALL_TIMES: ${{ steps.pr-real.outputs.real_all_times }} @@ -671,6 +691,7 @@ jobs: BASELINE_REAL_PEAK="$BA_REAL_PEAK" BASELINE_REAL_SPREAD="$BA_REAL_SPREAD" BASELINE_REAL_INPUT="$BA_REAL_INPUT" + BASELINE_REAL_INPUT_SHA="$BA_REAL_INPUT_SHA" else BASELINE_SRC="built from main" BASELINE_GROWTH_HEAPS="$BR_GROWTH_HEAPS" @@ -684,6 +705,7 @@ jobs: # Freshly proven on this runner from $REAL_INPUT, so by construction the # same block the PR side used; the cached path carries its own label. BASELINE_REAL_INPUT="$PR_REAL_INPUT" + BASELINE_REAL_INPUT_SHA="$PR_REAL_INPUT_SHA" fi echo "baseline_src=$BASELINE_SRC" >> "$GITHUB_OUTPUT" @@ -714,9 +736,20 @@ jobs: # except on a mismatch, which real_mismatch below already carries. if [ -n "$PR_REAL_TIME" ] && [ -n "$BASELINE_REAL_TIME" ]; then + # Two keys, because they catch different things: the basename catches a + # repoint to another block, the digest catches the same block re-archived at + # a different ethrex rev (a baseline older than a pin bump). A baseline + # predating the digest key has an empty one and is compared on name alone, + # which is the pre-existing behaviour rather than a new mismatch. + REAL_SKEW="" if [ -n "$BASELINE_REAL_INPUT" ] && [ "$BASELINE_REAL_INPUT" != "$PR_REAL_INPUT" ]; then - echo "::warning::Baseline real block ($BASELINE_REAL_INPUT) differs from the PR's ($PR_REAL_INPUT); not comparing." - echo "real_mismatch=$BASELINE_REAL_INPUT" >> "$GITHUB_OUTPUT" + REAL_SKEW="$BASELINE_REAL_INPUT" + elif [ -n "$BASELINE_REAL_INPUT_SHA" ] && [ "$BASELINE_REAL_INPUT_SHA" != "$PR_REAL_INPUT_SHA" ]; then + REAL_SKEW="$BASELINE_REAL_INPUT@$BASELINE_REAL_INPUT_SHA" + fi + if [ -n "$REAL_SKEW" ]; then + echo "::warning::Baseline real block ($REAL_SKEW) differs from the PR's ($PR_REAL_INPUT@$PR_REAL_INPUT_SHA); not comparing." + echo "real_mismatch=$REAL_SKEW" >> "$GITHUB_OUTPUT" else REAL_TIME_DIFF=$(awk "BEGIN { printf \"%.3f\", $PR_REAL_TIME - $BASELINE_REAL_TIME }") REAL_TIME_PCT=$(awk "BEGIN { printf \"%.1f\", (($PR_REAL_TIME - $BASELINE_REAL_TIME) * 100) / $BASELINE_REAL_TIME }") diff --git a/.github/workflows/pr_main.yaml b/.github/workflows/pr_main.yaml index 767e166de..89bff2b03 100644 --- a/.github/workflows/pr_main.yaml +++ b/.github/workflows/pr_main.yaml @@ -40,6 +40,13 @@ jobs: - name: Check ethrex fixture checksums run: make check-ethrex-fixture-checksums + # Five manifests carry the ethrex rev and they must agree: a skew is not a build + # failure, it is a fixture the guest decodes as the all-zero default. `--show` + # exits non-zero on MIXED. It reads manifests only; the matching locks are held by + # `--locked` on each workspace's own test/build step. + - name: Check the ethrex rev is consistent across manifests + run: scripts/set_ethrex_rev.sh --show + # The benchmark comment harness: verifies every steps.X.outputs.Y consumed in # benchmark-pr.yml has a producer (the orphaned-wiring class that once broke # /bench-growth silently), then renders the full comment scenario suite. @@ -153,7 +160,7 @@ jobs: - name: Run ethrex host-reference tests (detached workspace) run: | cd tooling/ethrex-tests && \ - cargo test --release -- --include-ignored --skip test_ethrex_real_block + cargo test --locked --release -- --include-ignored --skip test_ethrex_real_block test-cli: name: CLI tests diff --git a/Makefile b/Makefile index 3e4a88ecb..cf794e081 100644 --- a/Makefile +++ b/Makefile @@ -307,8 +307,12 @@ test-rust: compile-programs-rust # measured cost. ETHREX_REAL_BLOCK_NETWORK := mainnet ETHREX_REAL_BLOCK := 25368371 -ETHREX_REAL_BLOCK_FIXTURE_URL := https://github.com/yetanotherco/lambda_vm/releases/download/bench-fixtures-v1/ethrex_mainnet_25368371.bin -ETHREX_REAL_BLOCK_FIXTURE_SHA256 := 61eba49b6b254f4a05def5a47b08a21ae3eee56f0d37bcd7b3a24b0cc1e4a300 +# The asset name carries the ethrex rev because the bytes are a function of it: the +# archived ProgramInput layout moves with the pin, so one block has one fixture per rev. +# Uploading under a new name rather than replacing the old one keeps `main` — which still +# expects the pre-bump sha256 — fetching its own artifact while this branch is open. +ETHREX_REAL_BLOCK_FIXTURE_URL := https://github.com/yetanotherco/lambda_vm/releases/download/bench-fixtures-v1/ethrex_mainnet_25368371_797df554.bin +ETHREX_REAL_BLOCK_FIXTURE_SHA256 := 573004e62e3680a00d3cdbae19dc4897e2ec60d6ec0c1d05d9ef118cb8aef17f # The block's source cache, hosted in the same release. Only `regen-real-block-fixture` # reads it — the converter's TESTS use a different, upstream-pinned cache (below). ETHREX_REAL_BLOCK_CACHE_URL := https://github.com/yetanotherco/lambda_vm/releases/download/bench-fixtures-v1/cache_mainnet_25368371.json @@ -433,7 +437,7 @@ ethrex-real-block-converter-cache: $(ETHREX_CONVERTER_CACHE) # network-rejection guard, and the reproducibility digest. Runs on changes to the # converter (see .github/workflows/ethrex-block-converter.yml), not on every PR. test-ethrex-real-block-converter: $(ETHREX_CONVERTER_CACHE) - cd tooling/ethrex-block-converter && cargo test --release + cd tooling/ethrex-block-converter && cargo test --locked --release # Manual regeneration of the BENCHMARK fixture (not the converter's test block): # fetches that block's own cache and re-converts it, overwriting the fixture in @@ -459,7 +463,7 @@ test-ethrex: compile-programs-rust ethrex-real-block-fixture # otherwise fail on a clean checkout. The committed synthetic fixtures and # `no_kzg_backend_linked` still run. test-ethrex-offline: compile-programs-rust - cd tooling/ethrex-tests && cargo test --release -- --include-ignored --skip test_ethrex_real_block + cd tooling/ethrex-tests && cargo test --locked --release -- --include-ignored --skip test_ethrex_real_block test-flamegraph: cargo test -p executor --test flamegraph @@ -499,7 +503,8 @@ regen-ethrex-fixtures: cd tooling/ethrex-fixtures && \ cargo run --release -- 0 ../../executor/tests/ethrex_empty_block.bin && \ cargo run --release -- 1 ../../executor/tests/ethrex_simple_tx.bin && \ - cargo run --release -- 10 ../../executor/tests/ethrex_10_transfers.bin + cargo run --release -- 10 ../../executor/tests/ethrex_10_transfers.bin && \ + cargo run --release -- 4 ../../executor/tests/ethrex_bench_4.bin distinct $(MAKE) update-ethrex-fixture-checksums update-ethrex-fixture-checksums: @@ -530,9 +535,13 @@ test-syscalls: # exercises the implementation that actually ships; the debug run is kept because # its magnitude debug_asserts turn a contract violation into a loud panic instead # of a silently wrong value. +# `--locked` because this is the only target that builds that workspace: without it +# cargo re-resolves and REWRITES the committed lock on a manifest/lock mismatch, so +# the job passes while the lock describes a different build than the one that ran. +# That is how the ethrex rev bump left this lock a rev behind the manifest. test-ethrex-crypto: - cd crypto/ethrex-crypto && cargo test - cd crypto/ethrex-crypto && cargo test --release + cd crypto/ethrex-crypto && cargo test --locked + cd crypto/ethrex-crypto && cargo test --locked --release test: compile-programs test-syscalls test-ethrex-crypto cargo test diff --git a/bench_vs/README_ethrex.md b/bench_vs/README_ethrex.md index c1b319ac3..53be32a98 100644 --- a/bench_vs/README_ethrex.md +++ b/bench_vs/README_ethrex.md @@ -14,6 +14,11 @@ rkyv-encoded) for the ethrex commit pinned (as `rev`) in `executor/programs/rust/ethrex/Cargo.toml`. The guest reads it via `get_private_input()` and runs ethrex's `execution_program`. +Both the fixtures and those instruction counts are therefore a function of that pin: the +counts above were measured at `156cb8d6` and have not been re-measured since the +`797df554` bump, which regenerated both fixtures. Treat them as an order of magnitude, +and re-run the benchmark for real numbers. + The timing window is **single-shot end-to-end prove** (ELF load + execution + trace build + AIR construction + STARK prove); it **excludes** verification. @@ -42,6 +47,8 @@ Output (example): ethrex 1 tx 47.302s 4392951 ``` +(Example output, taken at ethrex `156cb8d6` — see the note above.) + With `--report-dir DIR` it also writes: - `DIR/ethrex_summary.md` — markdown table - `DIR/ethrex_metrics.txt` — `_time_s=` / `_cycles=` per block diff --git a/crypto/ethrex-crypto/Cargo.lock b/crypto/ethrex-crypto/Cargo.lock index fab277e4b..47fe0bbbd 100644 --- a/crypto/ethrex-crypto/Cargo.lock +++ b/crypto/ethrex-crypto/Cargo.lock @@ -79,7 +79,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -92,7 +92,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -131,7 +131,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -141,14 +141,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", - "rand 0.8.6", + "rand 0.8.7", ] [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "autocfg" @@ -162,18 +162,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "bitvec" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -183,19 +171,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-affine-constructors#78cad0378b17fc3157b83f514be192bf46edf9a1" -dependencies = [ - "digest", - "ff", - "group", - "pairing", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "byteorder" version = "1.5.0" @@ -301,14 +276,14 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "either" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" [[package]] name = "elliptic-curve" @@ -336,22 +311,22 @@ checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" [[package]] name = "enum-ordinalize" -version = "4.3.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" dependencies = [ "enum-ordinalize-derive", ] [[package]] name = "enum-ordinalize-derive" -version = "4.3.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -367,22 +342,20 @@ dependencies = [ [[package]] name = "ethrex-crypto" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", - "bls12_381", "ethereum-types", - "ff", "hex-literal", "k256", "num-bigint", "p256", "ripemd", "sha2", - "thiserror 2.0.18", + "thiserror 2.0.20", "tiny-keccak", ] @@ -392,7 +365,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "bitvec", "rand_core 0.6.4", "subtle", ] @@ -414,12 +386,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "generic-array" version = "0.14.9" @@ -542,7 +508,7 @@ dependencies = [ "getrandom 0.2.17", "getrandom 0.3.4", "lazy_static", - "rand 0.9.4", + "rand 0.9.5", "riscv", "thiserror 1.0.69", ] @@ -555,15 +521,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -571,9 +537,9 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] @@ -605,15 +571,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - [[package]] name = "paste" version = "1.0.15" @@ -650,18 +607,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -672,17 +629,11 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "rand_chacha 0.3.1", "rand_core 0.6.4", @@ -690,9 +641,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -773,7 +724,7 @@ checksum = "7d323d13972c1b104aa036bc692cd08b822c8bbf23d79a27c526095856499799" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -836,9 +787,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -846,10 +797,15 @@ dependencies = [ ] [[package]] -name = "tap" -version = "1.0.1" +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "thiserror" @@ -862,11 +818,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.20", ] [[package]] @@ -877,18 +833,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -908,9 +864,9 @@ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "uint" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +checksum = "6f9227a75a5a540a464c832ad4a4195dbdbecd8787610a56262721fde6f04f90" dependencies = [ "byteorder", "crunchy", @@ -951,33 +907,24 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -997,5 +944,5 @@ checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] diff --git a/crypto/ethrex-crypto/Cargo.toml b/crypto/ethrex-crypto/Cargo.toml index ea6c91074..54a7dfc53 100644 --- a/crypto/ethrex-crypto/Cargo.toml +++ b/crypto/ethrex-crypto/Cargo.toml @@ -16,9 +16,9 @@ license = "MIT OR Apache-2.0" [dependencies] # Defines the `Crypto` trait, `CryptoError`, and `keccak::keccak_hash`. Same rev -# + `default-features = false` as the guest's ethrex-crypto, so feature -# unification adds nothing to the guest build (no C secp256k1 / malachite / kzg). -ethrex-crypto = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-crypto", default-features = false } +# + `default-features = false` as the guest's ethrex-crypto, so this line adds +# nothing to the guest build. Note `std` is on anyway, via ethrex-trie's default. +ethrex-crypto = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-crypto", default-features = false } # Pinned to the exact 0.13.4 ethrex uses so the guest resolves a single k256 # (a version split would make `FieldElement`/`Scalar` incompatible types). # `expose-field` is required by the x-only reconstruction. diff --git a/crypto/ethrex-crypto/src/lib.rs b/crypto/ethrex-crypto/src/lib.rs index ec36b0831..d3724f92c 100644 --- a/crypto/ethrex-crypto/src/lib.rs +++ b/crypto/ethrex-crypto/src/lib.rs @@ -14,7 +14,10 @@ //! back to the pure-Rust `ProjectivePoint::lincomb`. //! //! Every other `Crypto` method inherits the trait default (vetted pure-Rust -//! crates: `ark-bn254`, `bls12_381`, `p256`, `sha2`, `ripemd`, …). +//! crates: `ark-bn254`, `p256`, `sha2`, `ripemd`, …), except two families that +//! error because no backend is linked: KZG `0x0a` (reverts) and BLS12-381 +//! `0x0b`-`0x11` (aborts). Pinned by `no_{kzg,bls}_backend_linked` in +//! `tooling/ethrex-tests`. use ethrex_crypto::keccak::keccak_hash; use ethrex_crypto::{Crypto, CryptoError}; diff --git a/executor/programs/rust/ethrex/Cargo.lock b/executor/programs/rust/ethrex/Cargo.lock index c06b622f8..63705e473 100644 --- a/executor/programs/rust/ethrex/Cargo.lock +++ b/executor/programs/rust/ethrex/Cargo.lock @@ -189,22 +189,6 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" -[[package]] -name = "bitcoin-io" -version = "0.1.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11301df0b06f22dea7bb1916403fdd88a371031e495c49b8f96931b28189e175" - -[[package]] -name = "bitcoin_hashes" -version = "0.14.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9901a56e133a1fc86eeb1113e2591f45f4682451ca893bff494d2f88918e3f" -dependencies = [ - "bitcoin-io", - "hex-conservative", -] - [[package]] name = "bitvec" version = "1.0.1" @@ -226,19 +210,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-affine-constructors#78cad0378b17fc3157b83f514be192bf46edf9a1" -dependencies = [ - "digest", - "ff", - "group", - "pairing", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "bs58" version = "0.5.1" @@ -697,8 +668,8 @@ dependencies = [ [[package]] name = "ethrex-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "crc32fast", @@ -712,6 +683,10 @@ dependencies = [ "indexmap 2.14.0", "lazy_static", "libc", + "libssz", + "libssz-derive", + "libssz-merkle", + "libssz-types", "lru", "once_cell", "rkyv", @@ -725,17 +700,16 @@ dependencies = [ [[package]] name = "ethrex-crypto" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", - "bls12_381", "ethereum-types", - "ff", "hex-literal", "k256", + "malachite", "num-bigint", "p256", "ripemd", @@ -746,8 +720,8 @@ dependencies = [ [[package]] name = "ethrex-guest-program" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -757,8 +731,6 @@ dependencies = [ "ethrex-rlp", "ethrex-vm", "hex", - "k256", - "lambda-vm-syscalls", "rkyv", "serde", "serde_with", @@ -767,8 +739,8 @@ dependencies = [ [[package]] name = "ethrex-l2-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -777,7 +749,6 @@ dependencies = [ "k256", "lambdaworks-crypto", "rkyv", - "secp256k1", "serde", "serde_with", "thiserror 2.0.18", @@ -786,14 +757,15 @@ dependencies = [ [[package]] name = "ethrex-levm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", "ethrex-common", "ethrex-crypto", "ethrex-rlp", + "libssz", "malachite", "rustc-hash", "serde", @@ -803,8 +775,8 @@ dependencies = [ [[package]] name = "ethrex-rlp" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -813,8 +785,8 @@ dependencies = [ [[package]] name = "ethrex-trie" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "anyhow", "bytes", @@ -822,18 +794,19 @@ dependencies = [ "ethereum-types", "ethrex-crypto", "ethrex-rlp", - "lazy_static", + "hashbrown 0.15.5", "rayon", "rkyv", "rustc-hash", "serde", + "spin", "thiserror 2.0.18", ] [[package]] name = "ethrex-vm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", @@ -854,7 +827,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "bitvec", "rand_core 0.6.4", "subtle", ] @@ -1017,15 +989,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex-conservative" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" -dependencies = [ - "arrayvec", -] - [[package]] name = "hex-literal" version = "0.4.1" @@ -1282,6 +1245,47 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libssz" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d498c0482bba87d2647ea4601ea76cf2b498065e3958798a88f49274f3ced5e9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "libssz-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ddfb5c969c28a4a54043e630f80c723352637bd1020f256ee3ac7a8814922b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libssz-merkle" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63c6d6d5ce5d79bba66bc98c99869eedffedf7f14f0aa0915f1a62802650bdf6" +dependencies = [ + "libssz", + "sha2", +] + +[[package]] +name = "libssz-types" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747273ab2d923e82ed147091fe0fb3e602dd2012c872cdad5efe69e27c3b4099" +dependencies = [ + "libssz", + "libssz-merkle", + "smallvec", +] + [[package]] name = "log" version = "0.4.32" @@ -1427,15 +1431,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - [[package]] name = "parity-scale-codec" version = "3.7.5" @@ -1859,26 +1854,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secp256k1" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" -dependencies = [ - "bitcoin_hashes", - "rand 0.8.6", - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" -dependencies = [ - "cc", -] - [[package]] name = "serde" version = "1.0.228" @@ -2003,6 +1978,18 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" + [[package]] name = "spki" version = "0.7.3" diff --git a/executor/programs/rust/ethrex/Cargo.toml b/executor/programs/rust/ethrex/Cargo.toml index 4922712dd..b93265450 100644 --- a/executor/programs/rust/ethrex/Cargo.toml +++ b/executor/programs/rust/ethrex/Cargo.toml @@ -18,20 +18,37 @@ lambda-vm-syscalls = { path = "../../../../syscalls" } # lambda_vm repo and injected in src/main.rs — so crypto changes stay in our repo # and don't require an ethrex PR. lambda-vm-ethrex-crypto = { path = "../../../../crypto/ethrex-crypto" } -# Pinned by immutable `rev` to a commit on the open LambdaVM-backend PR branch -# (feat/lambdavm-prover-backend) of ethrex; re-pin to the merge commit once it -# lands on ethrex `main`. The `lambdavm` feature is kept only for its dependency -# wiring (`ProgramInput`/`execution_program`/`ProgramOutput::encode` + pure-Rust -# crypto defaults); ethrex's own `LambdaVmCrypto` compiles unused — we inject our -# own. KZG is NOT linked under this feature, so the point-evaluation precompile -# (0x0a) is unsupported — see src/main.rs. -ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-guest-program", default-features = false, features = ["lambdavm"] } +# Pinned by immutable `rev` to a commit on ethrex `main`. It used to point at the +# open LambdaVM-backend PR branch (`feat/lambdavm-prover-backend`) and wait for +# that to merge; it no longer does, because the branch stopped moving 69 commits +# behind `main` while guest performance work kept landing there. Measured on the +# real benchmark block, that wait had grown to -22.9%. +# +# No `features = [...]`, deliberately — not even `lambdavm`. +# +# `ethrex-guest-program` carries one feature per zkVM and, despite the names, none +# of them selects a backend: each is only a list of optional crypto dependencies +# to activate, and none gates any method of the `Crypto` trait (its gates are +# `secp256k1`, `c-kzg`, `blst`, `std`). `lambdavm` was +# `["dep:k256", "dep:lambda-vm-syscalls", "ethrex-l2-common/secp256k1"]`, and +# since #702 moved the `Crypto` impl into this repo the syscalls it pulled are for +# ethrex's own provider, which we no longer use — while this guest already depends +# on `lambda-vm-syscalls` by path, above. +# +# What makes this guest LambdaVM is those path deps plus the +# `riscv64im-lambda-vm-elf` target, and `lambdavm` existed ONLY on the unmerged +# branch, so requiring it is what tied this guest to it. Re-pin with +# scripts/set_ethrex_rev.sh. +# +# Measured, not assumed: against the sibling feature activating the widest dependency +# set, `stress_modexp_150M` (6,373,285,966) and `stress_alt_bn128_150M` +# (22,986,061,145) are identical to the cycle, and the real benchmark block is +# 30,498,818 here vs 30,501,620 there, with a 2,928-byte smaller ELF. What the drop +# actually removes is C libsecp256k1 (`secp256k1`, `secp256k1-sys`, `bitcoin_hashes`, +# `bitcoin-io`, `hex-conservative` leave the lock); we inject our own ecrecover. +# +# 0x0a and 0x0b-0x11 are unsupported — see src/main.rs. +ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-guest-program", default-features = false } # Exact pin: must match the fixture writer (tooling/ethrex-fixtures) and the # executor test reader so the rkyv ProgramInput layout stays consistent. rkyv = { version = "=0.8.16", features = ["std", "unaligned"] } - -# `ethrex-guest-program`'s `lambdavm` feature pins `lambda-vm-syscalls` to an -# older commit. Override it with our working-tree copy so the guest links our -# current syscalls (keccak_permute + the Print-ecall no-op fix). -[patch."https://github.com/yetanotherco/lambda_vm.git"] -lambda-vm-syscalls = { path = "../../../../syscalls" } diff --git a/executor/programs/rust/ethrex/src/main.rs b/executor/programs/rust/ethrex/src/main.rs index 8154978cf..eae31effd 100644 --- a/executor/programs/rust/ethrex/src/main.rs +++ b/executor/programs/rust/ethrex/src/main.rs @@ -17,9 +17,8 @@ pub fn main() { // It accelerates trait-routed `keccak256` (via the keccak_permute precompile) // and `secp256k1_ecrecover` (via the ECSM precompile); everything else uses // ethrex's pure-Rust trait defaults. ethrex's trie/RLP keccak that goes - // through the free `keccak_hash` fn is still software, and KZG (0x0a) is - // unsupported under the `lambdavm` feature (blob txs execute; a point-eval - // precompile call reverts). + // through the free `keccak_hash` fn is still software. Unsupported, no backend + // linked: KZG 0x0a (reverts) and BLS12-381 0x0b-0x11 (aborts on the unwrap below). let crypto = Arc::new(LambdaVmEcsmCrypto); let output = execution_program(input, crypto).unwrap(); lambda_vm_syscalls::syscalls::commit(&output.encode()); diff --git a/executor/tests/README.md b/executor/tests/README.md index fdbf47bcb..7ae08e85c 100644 --- a/executor/tests/README.md +++ b/executor/tests/README.md @@ -10,14 +10,16 @@ workspace: ethrex pins rkyv `unaligned`, which must not feature-unify with the main workspace's aligned proof format). The ethrex guest, the native test reference, and the fixture generator are all -pinned to the same ethrex revision (the open LambdaVM-backend PR branch, until it -merges to `main`): +pinned to the same ethrex revision — a commit on ethrex `main`: ```text https://github.com/lambdaclass/ethrex.git -156cb8d6a3974f411d71622eecd1b249ee37ff1c +797df5540c7d35cafd69b6971a74b2a49c67d1dd ``` +Five manifests carry that pin, not one. `scripts/set_ethrex_rev.sh --show` prints +it and fails if they ever disagree. + ### Generation These blobs are generated reproducibly by the in-repo tool `tooling/ethrex-fixtures` @@ -30,27 +32,45 @@ cd tooling/ethrex-fixtures cargo run --release -- 0 ../../executor/tests/ethrex_empty_block.bin # empty block cargo run --release -- 1 ../../executor/tests/ethrex_simple_tx.bin # 1 transfer cargo run --release -- 10 ../../executor/tests/ethrex_10_transfers.bin # 10 transfers +cargo run --release -- 4 ../../executor/tests/ethrex_bench_4.bin distinct # recursion profile ``` -To regenerate after an ethrex rev bump, update the `rev` in -`tooling/ethrex-fixtures/Cargo.toml` (and the guest's), then run -`make regen-ethrex-fixtures` from the repo root. The target rebuilds the -committed fixtures and refreshes the checksums below. +`ethrex_bench_4.bin` is the odd one out: `distinct` mode, and it is read by the +recursion profile target rather than the executor tests (see the Makefile's +`recursion-profile-block-input`). It is committed like the rest, so it is +regenerated and checksummed with them — a rev bump makes every one of these +undecodable, not just the three the executor reads. + +It is also the only committed fixture nothing decodes in PR-blocking CI: the other three +go through `rkyv::from_bytes` in `tooling/ethrex-tests`, while this one's single in-repo +reader (`prover/src/tests/page_offset_forgery_poc.rs`) only reads its length. + +To regenerate after an ethrex rev bump, re-pin with +`scripts/set_ethrex_rev.sh <40-char-sha>` (all five manifests at once), regenerate the +five locks, then run `make regen-ethrex-fixtures` from the repo root. + +The checksums below are refreshed by that same run, so they catch a hand-edited `.bin` +but never one that is stale against the pinned rev. `--show` is what catches the cause. Known fixtures: ```text ethrex_empty_block.bin - sha256: d3e594f07cc74e4ddc9db9e9db220a65a2d2e578b619fc3ce06e346007b3ca43 + sha256: 8d6f6061c71c23fad1d5dee26242d631efe0bff8d7f49422c2ba4cde9d4be919 contents: stateless ethrex empty block ProgramInput (0 transactions) ethrex_simple_tx.bin - sha256: 15e3b3efa434186682537755d828ac8bbdde4be3fc7cbe34f26687b618a6c6ab + sha256: c40bce364f22758ab7fa6fe8b45ce4c305dee5add4536ef6dca0e74e410e2729 contents: stateless ethrex block with one plain ETH transfer transaction ethrex_10_transfers.bin - sha256: 38901ee4d40b99cf0aa7f642a92f0fc8db76d974bf43033a1673839020c3c28e + sha256: 4d862e8537284729ff11c7bcf91c971e562dd6bbce2a1e181ba5bf48cb6b65cf contents: stateless ethrex block with ten plain ETH transfer transactions + +ethrex_bench_4.bin + sha256: 03ed0d175622af6ef9a981d7652ba7c86630b9473f49cae17edf649724b704e1 + contents: stateless ethrex block with four plain ETH transfers, `distinct` mode + (N senders -> N recipients); read by the recursion profile target ``` ## Real-block fixtures @@ -58,7 +78,7 @@ ethrex_10_transfers.bin The blocks above are synthetic (N plain ETH transfers over a small genesis). For a representative workload — real contract execution, real trie depth, real bytecode — `make ethrex-real-block-fixture` downloads -`ethrex_mainnet_25368371.bin` (1,110,156 B) from the `bench-fixtures-v1` release +`ethrex_mainnet_25368371_797df554.bin` (1,110,183 B) from the `bench-fixtures-v1` release and verifies it against `ETHREX_REAL_BLOCK_FIXTURE_SHA256` in the Makefile before moving it into place. It is gitignored rather than committed, so the checksum lives next to the URL in the Makefile rather than in the table above (the checksum diff --git a/executor/tests/ethrex_10_transfers.bin b/executor/tests/ethrex_10_transfers.bin index 8b6c89182..201351189 100644 Binary files a/executor/tests/ethrex_10_transfers.bin and b/executor/tests/ethrex_10_transfers.bin differ diff --git a/executor/tests/ethrex_bench_4.bin b/executor/tests/ethrex_bench_4.bin index 45fe93038..23c2453ee 100644 Binary files a/executor/tests/ethrex_bench_4.bin and b/executor/tests/ethrex_bench_4.bin differ diff --git a/executor/tests/ethrex_empty_block.bin b/executor/tests/ethrex_empty_block.bin index e942b0c78..abec5263d 100644 Binary files a/executor/tests/ethrex_empty_block.bin and b/executor/tests/ethrex_empty_block.bin differ diff --git a/executor/tests/ethrex_simple_tx.bin b/executor/tests/ethrex_simple_tx.bin index 5a528b661..055f6f73c 100644 Binary files a/executor/tests/ethrex_simple_tx.bin and b/executor/tests/ethrex_simple_tx.bin differ diff --git a/scripts/set_ethrex_rev.sh b/scripts/set_ethrex_rev.sh new file mode 100755 index 000000000..5964420e7 --- /dev/null +++ b/scripts/set_ethrex_rev.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +# Re-pin every ethrex git dependency in this repo to one rev, atomically. +# +# The guest and the host-side tooling exchange ethrex types (the rkyv stateless +# input the converter writes and the guest decodes), so a rev that differs +# between them is not a version skew that fails to build -- it is a fixture the +# guest silently decodes as the all-zero default. Keeping every pin on one rev +# is what makes that impossible, which is why this rewrites all of them together +# rather than leaving them to be bumped by hand. +# +# Usage: +# scripts/set_ethrex_rev.sh <40-char-sha> re-pin everything +# scripts/set_ethrex_rev.sh --guest-only <40-char-sha> re-pin only the guest graph +# scripts/set_ethrex_rev.sh --show print the current pin(s) +# +# `--guest-only` moves the crates the guest ELF is built from and leaves the +# host-side fixture tooling where it is. That split is what lets a benchmark vary +# the guest across two revs while holding the fixture constant: the fixture is +# just bytes, its wire format does not change within a PR, and regenerating it per +# rev would instead drag the whole ethrex HOST api (which does drift) into the +# measurement. +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$REPO_ROOT" + +# Every manifest carrying an ethrex git dep. Kept explicit rather than globbed so +# a new one has to be added deliberately -- a manifest silently left behind is +# exactly the skew described above. +# The guest ELF's own graph. `crypto/ethrex-crypto` is a path dep of BOTH the +# guest and the converter, so moving it moves what the converter links too -- +# which is why a `--guest-only` run must come after the fixture already exists. +GUEST_MANIFESTS=( + executor/programs/rust/ethrex/Cargo.toml + crypto/ethrex-crypto/Cargo.toml +) + +# Host-side tooling: builds fixtures, never lands in the ELF. +TOOLING_MANIFESTS=( + tooling/ethrex-tests/Cargo.toml + tooling/ethrex-block-converter/Cargo.toml + tooling/ethrex-fixtures/Cargo.toml +) + +MANIFESTS=("${GUEST_MANIFESTS[@]}" "${TOOLING_MANIFESTS[@]}") + +current_revs() { + grep -ho 'rev = "[0-9a-f]\{40\}"' "${MANIFESTS[@]}" | sort -u | sed 's/rev = //;s/"//g' +} + +if [[ "${1:-}" == "--show" || $# -eq 0 ]]; then + # No `mapfile`: macOS ships bash 3.2, where it does not exist. + revs="$(current_revs)" + if [[ "$(printf '%s\n' "$revs" | wc -l | tr -d ' ')" == "1" ]]; then + echo "$revs" + else + # Non-zero on purpose: this is the skew the script exists to prevent, and it is + # what makes `--show` usable as a CI gate. A `--guest-only` re-pin is legitimately + # this state, so a caller doing that should ignore the status. + echo "MIXED:" >&2 + printf ' %s\n' $revs >&2 + exit 1 + fi + exit 0 +fi + +COUNTS=() +TARGETS=("${MANIFESTS[@]}") +SCOPE="all manifests" +if [[ "${1:-}" == "--guest-only" ]]; then + shift + TARGETS=("${GUEST_MANIFESTS[@]}") + SCOPE="the guest graph only" +fi + +NEW_REV="${1:-}" +if [[ ! "$NEW_REV" =~ ^[0-9a-f]{40}$ ]]; then + echo "error: expected a 40-character commit sha, got '$NEW_REV'" >&2 + exit 2 +fi + +# Only rewrite revs on ethrex deps: the same file may pin other git deps. +PATTERN='(github\.com/lambdaclass/ethrex\.git", rev = ")[0-9a-f]{40}(")' + +# Two passes so a partial rewrite is impossible. Pass 1 only counts: the pattern needs +# the git URL and `rev` on ONE physical line, so a manifest in `[dependencies.x]` table +# form matches nothing, and rewriting the others anyway would leave exactly the skew this +# script exists to prevent -- while reporting success. +for manifest in "${TARGETS[@]}"; do + [[ -f "$manifest" ]] || { echo "error: missing $manifest" >&2; exit 1; } + n="$(perl -ne "\$c++ while m{$PATTERN}g; END { print \$c + 0 }" "$manifest")" + if [[ "$n" == "0" ]]; then + echo "error: $manifest carries no ethrex rev this script can rewrite." >&2 + echo " The pattern needs the git URL and \`rev\` on one line; a \`[dependencies.x]\`" >&2 + echo " table form does not match. Nothing was written." >&2 + exit 1 + fi + COUNTS+=("$manifest ($n)") +done + +# Pass 2 rewrites, now that every target is known to match. +for manifest in "${TARGETS[@]}"; do + perl -pi -e "s{$PATTERN}{\${1}$NEW_REV\${2}}g" "$manifest" +done + +echo "re-pinned $SCOPE to $NEW_REV:" +printf ' %s\n' "${COUNTS[@]}" diff --git a/tooling/ethrex-block-converter/Cargo.lock b/tooling/ethrex-block-converter/Cargo.lock index 8ad77716b..5c216acbb 100644 --- a/tooling/ethrex-block-converter/Cargo.lock +++ b/tooling/ethrex-block-converter/Cargo.lock @@ -305,19 +305,6 @@ dependencies = [ "objc2", ] -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-affine-constructors#78cad0378b17fc3157b83f514be192bf46edf9a1" -dependencies = [ - "digest", - "ff", - "group", - "pairing", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "blst" version = "0.3.17" @@ -865,6 +852,7 @@ version = "0.1.0" dependencies = [ "ethrex-common", "ethrex-config", + "ethrex-crypto", "ethrex-guest-program", "k256", "lambda-vm-ethrex-crypto", @@ -876,18 +864,21 @@ dependencies = [ [[package]] name = "ethrex-blockchain" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "crossbeam", "ethrex-common", "ethrex-crypto", + "ethrex-guest-program", "ethrex-metrics", "ethrex-rlp", "ethrex-storage", "ethrex-trie", "ethrex-vm", + "libssz", + "libssz-merkle", "rayon", "rustc-hash", "thiserror 2.0.19", @@ -898,8 +889,8 @@ dependencies = [ [[package]] name = "ethrex-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "crc32fast", @@ -913,6 +904,10 @@ dependencies = [ "indexmap 2.14.0", "lazy_static", "libc", + "libssz", + "libssz-derive", + "libssz-merkle", + "libssz-types", "lru", "once_cell", "rkyv", @@ -926,8 +921,8 @@ dependencies = [ [[package]] name = "ethrex-config" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ethrex-common", "ethrex-p2p", @@ -938,16 +933,14 @@ dependencies = [ [[package]] name = "ethrex-crypto" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", - "bls12_381", "c-kzg", "ethereum-types", - "ff", "hex-literal", "k256", "malachite", @@ -961,8 +954,8 @@ dependencies = [ [[package]] name = "ethrex-guest-program" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -972,8 +965,6 @@ dependencies = [ "ethrex-rlp", "ethrex-vm", "hex", - "k256", - "lambda-vm-syscalls", "rkyv", "serde", "serde_with", @@ -982,8 +973,8 @@ dependencies = [ [[package]] name = "ethrex-l2-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -992,7 +983,6 @@ dependencies = [ "k256", "lambdaworks-crypto", "rkyv", - "secp256k1", "serde", "serde_with", "thiserror 2.0.19", @@ -1001,14 +991,15 @@ dependencies = [ [[package]] name = "ethrex-levm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", "ethrex-common", "ethrex-crypto", "ethrex-rlp", + "libssz", "malachite", "rustc-hash", "serde", @@ -1018,8 +1009,8 @@ dependencies = [ [[package]] name = "ethrex-metrics" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ethrex-common", "serde", @@ -1030,8 +1021,8 @@ dependencies = [ [[package]] name = "ethrex-p2p" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "aes", "aes-gcm", @@ -1072,8 +1063,8 @@ dependencies = [ [[package]] name = "ethrex-rlp" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -1082,8 +1073,8 @@ dependencies = [ [[package]] name = "ethrex-storage" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "anyhow", "bytes", @@ -1104,8 +1095,8 @@ dependencies = [ [[package]] name = "ethrex-trie" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "anyhow", "bytes", @@ -1113,18 +1104,19 @@ dependencies = [ "ethereum-types", "ethrex-crypto", "ethrex-rlp", - "lazy_static", + "hashbrown 0.15.5", "rayon", "rkyv", "rustc-hash", "serde", + "spin", "thiserror 2.0.19", ] [[package]] name = "ethrex-vm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", @@ -1157,7 +1149,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "bitvec", "rand_core 0.6.4", "subtle", ] @@ -1698,6 +1689,47 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libssz" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d498c0482bba87d2647ea4601ea76cf2b498065e3958798a88f49274f3ced5e9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "libssz-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ddfb5c969c28a4a54043e630f80c723352637bd1020f256ee3ac7a8814922b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "libssz-merkle" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63c6d6d5ce5d79bba66bc98c99869eedffedf7f14f0aa0915f1a62802650bdf6" +dependencies = [ + "libssz", + "sha2", +] + +[[package]] +name = "libssz-types" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747273ab2d923e82ed147091fe0fb3e602dd2012c872cdad5efe69e27c3b4099" +dependencies = [ + "libssz", + "libssz-merkle", + "smallvec", +] + [[package]] name = "lock_api" version = "0.4.14" @@ -1924,15 +1956,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - [[package]] name = "parity-scale-codec" version = "3.7.5" @@ -2688,6 +2711,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" + [[package]] name = "spki" version = "0.7.3" diff --git a/tooling/ethrex-block-converter/Cargo.toml b/tooling/ethrex-block-converter/Cargo.toml index f61e68a68..ba7a458b2 100644 --- a/tooling/ethrex-block-converter/Cargo.toml +++ b/tooling/ethrex-block-converter/Cargo.toml @@ -7,21 +7,27 @@ edition = "2024" [workspace] [dependencies] -# Pinned to the SAME ethrex rev as the guest (open LambdaVM-backend PR branch) -# so the generated ProgramInput rkyv layout matches what the guest deserializes. -ethrex-common = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-common", default-features = false } -ethrex-config = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-config", default-features = false } +# Pinned to the SAME ethrex rev as the guest so the generated ProgramInput rkyv +# layout matches what the guest deserializes. Re-pin all five manifests together +# with scripts/set_ethrex_rev.sh. +ethrex-common = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-common", default-features = false } +ethrex-config = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-config", default-features = false } +# Only for `NativeCrypto`, the host `Crypto` impl that `into_execution_witness` +# now takes. `ethrex_guest_program::crypto` re-exports it, but this crate's own +# guest-crypto impl is a dev-dependency, so the bin build needs its own line. +# Already in the graph via `ethrex-config` → `ethrex-p2p`, so this adds no compilation. +ethrex-crypto = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-crypto", default-features = false } # Matches the guest's own declaration (executor/programs/rust/ethrex/Cargo.toml). # # CAVEAT: this line alone does NOT reproduce the guest's precompile surface. The # `ethrex-config` dep above pulls `ethrex-p2p`, whose `default = ["c-kzg"]` # propagates to `ethrex-crypto/c-kzg` — and `default-features = false` cannot # switch it off, because ethrex's own workspace declares `ethrex-p2p` with its -# defaults on. So this graph links a working c-kzg (and malachite modexp, and -# `ark-ff/asm` BN254) that the guest does not have; verify with -# `cargo tree -e features -i ethrex-crypto`. Closing that gap means dropping -# `ethrex-config` and sourcing `ChainConfig` another way — see the README. -ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-guest-program", default-features = false, features = ["lambdavm"] } +# defaults on. So this graph links a working c-kzg that the guest does not have; +# verify with `cargo tree -e features -i ethrex-crypto`. c-kzg is the whole gap now — +# malachite modexp and `ark-ff/asm` are on both sides since ethrex-trie's `std` default. +# Closing it means dropping `ethrex-config` and sourcing `ChainConfig` another way. +ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-guest-program", default-features = false } # Exact pin: the fixture writer and the guest/executor readers must agree on the # rkyv layout. Keep this in sync with the guest @@ -54,8 +60,3 @@ lambda-vm-ethrex-crypto = { path = "../../crypto/ethrex-crypto" } # No feature delta against the rest of the graph (sha2/std is already on), so this # one can stay a dev-dependency without forcing the rebuild described above. sha2 = "0.10" - -# `ethrex-guest-program`'s `lambdavm` feature pins `lambda-vm-syscalls` to an -# older commit; override it with our working-tree copy, as the guest does. -[patch."https://github.com/yetanotherco/lambda_vm.git"] -lambda-vm-syscalls = { path = "../../syscalls" } diff --git a/tooling/ethrex-block-converter/README.md b/tooling/ethrex-block-converter/README.md index 17cf8a2f8..1d14d6c9b 100644 --- a/tooling/ethrex-block-converter/README.md +++ b/tooling/ethrex-block-converter/README.md @@ -11,16 +11,19 @@ opposite — a block that actually looks like Ethereum. Figures below are for the **current default** real block, mainnet 25368371; a repoint replaces them (see [Adopting a different block](#adopting-a-different-block)). -All are measured. +All are measured. Everything downstream of the archive layout — serialized size, cycles +and the accelerator counts — also moves with the pinned ethrex rev, so each column says +which rev it was taken at; the synthetic column has not been re-measured since the +`797df554` bump. -| | `ethrex_bench_20.bin` (synthetic) | `ethrex_mainnet_25368371.bin` (real, default) | +| | `ethrex_bench_20.bin` (synthetic, `4f658c2b`) | `ethrex_mainnet_25368371.bin` (real, default, `797df554`) | |---|---|---| | gas used | 420,000 | **2,428,684** | | transactions | 20 (all plain transfers) | 29 (real mix) | -| serialized size | 32,766 B | 1,110,156 B | -| cycles | 8,734,622 | **50,781,557** | -| keccak / ecsm calls | 411 / 80 | **10,478** / 116 | -| keccaks per ECSM call | 5.1 | **90** | +| serialized size | 32,766 B | 1,110,183 B | +| cycles | 8,734,622 | **30,498,818** | +| keccak / ecsm calls | 411 / 80 | **10,659** / 116 | +| keccaks per ECSM call | 5.1 | **92** | The last row counts keccaks per **ECSM call**, which is the ratio of the two rows above it. One ecrecover issues four ECSM ecalls — `lincomb2_with_oracle` in @@ -88,11 +91,19 @@ Artifacts live in the **[`bench-fixtures-v1`][release]** release on | asset | sha256 | read by | |---|---|---| -| `ethrex_mainnet_25368371.bin` | `61eba49b…` | every benchmark (**current default**) | +| `ethrex_mainnet_25368371_797df554.bin` | `573004e6…` | every benchmark (**current default**) | +| `ethrex_mainnet_25368371.bin` | `61eba49b…` | superseded; `main` still fetches this one | +| `ethrex_mainnet_25368371_4f658c2b.bin` | `0a301731…` | superseded (intermediate rev, unused) | | `cache_mainnet_25368371.json` | `7aa88a5f…` | `regen-real-block-fixture` | | `ethrex_mainnet_25453112.bin` | `0298663d…` | alternate candidate | | `cache_mainnet_25453112.json` | `20ffbbc1…` | alternate candidate | +> The asset name carries the ethrex rev because the bytes are a function of it: the +> archived `ProgramInput` rkyv layout moves with the pin, so one block has one +> fixture per rev. The pre-bump bytes stay hosted under the original name +> (`ethrex_mainnet_25368371.bin`, `61eba49b…`) so older `main`s — whose Makefile +> pins that sha256 — keep fetching their own artifact. + Each block has two assets: the fixture and the **cache** it was converted from (`make ethrex-real-block-cache`, ~2 MB, same verify-then-move contract). Only `regen-real-block-fixture` reads the cache. Note it is *not* the cache the @@ -130,12 +141,17 @@ cargo run --release -- Output is deterministic for a given cache file: ```text -wrote ../../executor/tests/ethrex_mainnet_25368371.bin (1110156 bytes): 1 block(s) \ +wrote ../../executor/tests/ethrex_mainnet_25368371.bin (1110183 bytes): 1 block(s) \ from mainnet starting at #25368371, 29 transaction(s), 2428684 gas ``` -Verified: regenerating from the hosted cache reproduces `61eba49b…` byte for byte, -which is what proves the hosted `.bin` and the hosted cache describe the same block. +Verified at the current ethrex rev (`797df554`): regenerating from the hosted cache +reproduces `573004e6…` byte for byte, and the result passes +`test_ethrex_real_block_native` — which is what proves the hosted cache and the fixture +the Makefile expects describe the same block. Byte count and digest are both +rev-dependent; this block has one archive per rev it has been pinned at +(1,110,156 B / `61eba49b…`, then 1,110,165 B / `0a301731…`, now this one), which is why +the release assets carry the rev in their names. The converter's `conversion_is_reproducible` test enforces the same property, but against its own pinned block rather than this one — see [Validation](#validation). @@ -345,11 +361,25 @@ repointed ~1 MB fixture cannot become committable by accident. ### Measured cost of candidate blocks Cost is a property of the block, so it changes with the repoint. All figures are -measured, never derived from gas — **cycles per gas is not constant** (20.9 for the -current default), so sizing a candidate from its gas mispredicts cost. +measured, never derived from gas — **cycles per gas is not constant** (12.6 for the +current default at `797df554`; it was 20.9 at `4f658c2b`), so sizing a candidate from its +gas mispredicts cost. **Current default — main-vintage (merge `fdb92f67`, main @ `9ccdaf2`):** +These figures were measured on the pre-bump fixture (`61eba49b…`, 1,110,156 B) and are +left as measured rather than restamped. The ethrex `4f658c2b` bump changed the fixture +bytes, so they are a baseline for a workload that no longer exists byte-for-byte. + +Counterparts at the intermediate `4f658c2b` rev, measured ABBA on `vm-benchmarks-1` at +the same epoch 2^22: **45,074,552 cycles** (−11.24%), **142.37 s** CPU prove (−10.87%), +**936.7 MB** proof (−12.22%), peak RSS flat at ~48 GB. + +At the currently pinned `797df554` only the cycle count has been re-measured — +**30,498,818 cycles**, 10,659 keccak, 116 ecsm. Prove time, proof size and the GPU column +have no counterpart at this rev yet; re-run `/bench` rather than reading the rows below +as current. + | block | gas | cycles | GPU prove (RTX 5090) | CPU prove | proof | fixture | |---|---|---|---|---|---|---| | **mainnet 25368371** | 2.43M | **50,781,557** (clang 21)
50,713,534 (clang 18) | **59.87 s** @ epoch 2^22 | **158.8 s** @ epoch 2^22 (2.65x the GPU wall) | 1.15 GB CPU / 1.12 GB GPU | 1,110,156 B, `61eba49b…` | @@ -451,11 +481,15 @@ first run after a repoint reports one-sided numbers until main republishes. ## Why the JSON and not ethrex-replay's own `.bin` -`ethrex-replay` can already emit a rkyv `ProgramInput`, but it tracks ethrex -`main`, where the type has diverged from the rev our guest pins -(`156cb8d6…`): `main` has an extra `fee_configs` field, moved the type from -`l1::` to `input::`, and uses rkyv 0.8.10 against our exact `=0.8.16`. Its -binary would not deserialize in our guest. +`ethrex-replay` can already emit a rkyv `ProgramInput`, but the type has diverged from +what our guest expects before: back when we pinned a branch off `main` (`156cb8d6…`) +`main` carried an extra `fee_configs` field and had moved the type from `l1::` to +`input::`, so replay's binary would not deserialize in our guest at all. + +We now pin `main` directly (`797df554…`), so that particular gap is closed by +construction. What has not closed: replay resolves rkyv itself from ethrex's `^0.8.10` +rather than our exact `=0.8.16`, and the next bump can reopen the type gap without +warning. The cache JSON carries only `blocks` + `witness` + `network` as plain serde, so it survives that drift. This tool re-reads it with **our** pinned ethrex types @@ -492,7 +526,7 @@ exercised via the guest's own trait dispatch. Stateless re-execution ends in a post-state-root check, so any divergence from consensus fails here. **It does not screen KZG.** Declaring `ethrex-guest-program` with -`default-features = false, features = ["lambdavm"]` is necessary but not +`default-features = false` (and no features, as the guest does) is necessary but not sufficient: the `ethrex-config` dependency (used only for `Network::get_genesis()`) pulls `ethrex-p2p`, whose `default = ["c-kzg"]` propagates down to `ethrex-crypto/c-kzg` — and `default-features = false` cannot diff --git a/tooling/ethrex-block-converter/src/main.rs b/tooling/ethrex-block-converter/src/main.rs index f96b03f24..98df955d6 100644 --- a/tooling/ethrex-block-converter/src/main.rs +++ b/tooling/ethrex-block-converter/src/main.rs @@ -5,18 +5,23 @@ //! cargo run --release -- use ethrex_common::types::Block; -use ethrex_common::types::block_execution_witness::RpcExecutionWitness; +use ethrex_common::types::block_execution_witness::{RpcExecutionWitness, decode_witness_headers}; use ethrex_config::networks::Network; +use ethrex_crypto::NativeCrypto; use ethrex_guest_program::l1::ProgramInput; use serde::Deserialize; /// The subset of `ethrex-replay`'s on-disk cache that a `ProgramInput` needs. /// /// Deliberately deserialized with *our* pinned ethrex types rather than by -/// depending on `ethrex-replay`: it tracks ethrex `main`, where `ProgramInput` -/// has diverged (extra `fee_configs` field, different module path, rkyv 0.8.10 -/// vs our `=0.8.16`), so its own `.bin` output would not deserialize in our -/// guest. This JSON is the version-tolerant interface between the two. +/// depending on `ethrex-replay`: it tracks ethrex `main`, we pin a branch off it, +/// and `ProgramInput` has diverged between the two before (it once carried an +/// extra `fee_configs` field and lived at a different module path). At the +/// currently pinned rev the type happens to match `main`'s again, but replay +/// still resolves rkyv itself from ethrex's `^0.8.10` against our exact `=0.8.16`, +/// and nothing stops the type drifting apart on the next bump. This JSON carries +/// only `blocks` + `witness` + `network` as plain serde, so it is the +/// version-tolerant interface between the two regardless. /// /// Extra fields in the file (L2 blob data, custom `chain_config`) are ignored. #[derive(Deserialize)] @@ -70,10 +75,19 @@ fn program_input_from_cache( // `into_execution_witness` rebuilds the trie structures from the flat node // list and needs the parent header, which the cache carries inside `witness`. + // Those headers are now decoded by the caller rather than inside the call, and the + // parent lookup matches on `h.number` without touching `crypto` at all. The `Crypto` + // argument is used only for keccak over the trie-node preimages, so `NativeCrypto` + // produces the same bytes as the `LambdaVmEcsmCrypto` the guest injects (whose host + // path is also software keccak) — the fixture does not depend on which one converts it. let chain_config = cache.network.get_genesis()?.config; - let witness = cache - .witness - .into_execution_witness(chain_config, summary.first_block_number)?; + let decoded_headers = decode_witness_headers(&cache.witness.headers)?; + let witness = cache.witness.into_execution_witness( + chain_config, + summary.first_block_number, + &decoded_headers, + &NativeCrypto, + )?; Ok((ProgramInput::new(cache.blocks, witness), summary)) } @@ -216,7 +230,7 @@ mod tests { .map(|b| format!("{b:02x}")) .collect(); assert_eq!( - digest, "1f7d4c4cdf9bd52472d9ebafdb4038f57a88c3c92d65c96fd86d7e323db87142", + digest, "8b3fb1294a5cd7296452d4a0422b0623c2d243e84bc8a51d3f15bc3899354553", "fixture bytes changed — regenerate it and update the README checksum", ); } diff --git a/tooling/ethrex-fixtures/Cargo.lock b/tooling/ethrex-fixtures/Cargo.lock index 8d671d94c..03e77ca4a 100644 --- a/tooling/ethrex-fixtures/Cargo.lock +++ b/tooling/ethrex-fixtures/Cargo.lock @@ -389,19 +389,6 @@ dependencies = [ "objc2", ] -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-affine-constructors#78cad0378b17fc3157b83f514be192bf46edf9a1" -dependencies = [ - "digest", - "ff", - "group", - "pairing", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "blst" version = "0.3.16" @@ -481,9 +468,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "2.1.7" +version = "2.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6648ed1e4ea8e8a1a4a2c78e1cda29a3fd500bc622899c340d8525ea9a76b24a" +checksum = "38d04308254695569fdb9bfe3bacc1c91837a670d0806605eb82d63748fbd3a6" dependencies = [ "blst", "cc", @@ -988,18 +975,21 @@ dependencies = [ [[package]] name = "ethrex-blockchain" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "crossbeam", "ethrex-common", "ethrex-crypto", + "ethrex-guest-program", "ethrex-metrics", "ethrex-rlp", "ethrex-storage", "ethrex-trie", "ethrex-vm", + "libssz", + "libssz-merkle", "rayon", "rustc-hash", "thiserror 2.0.18", @@ -1010,8 +1000,8 @@ dependencies = [ [[package]] name = "ethrex-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "crc32fast", @@ -1025,6 +1015,10 @@ dependencies = [ "indexmap 2.14.0", "lazy_static", "libc", + "libssz", + "libssz-derive", + "libssz-merkle", + "libssz-types", "lru", "once_cell", "rayon", @@ -1040,16 +1034,14 @@ dependencies = [ [[package]] name = "ethrex-crypto" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", - "bls12_381", "c-kzg", "ethereum-types", - "ff", "hex-literal", "k256", "malachite", @@ -1081,8 +1073,8 @@ dependencies = [ [[package]] name = "ethrex-guest-program" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -1100,8 +1092,8 @@ dependencies = [ [[package]] name = "ethrex-l2-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -1119,8 +1111,8 @@ dependencies = [ [[package]] name = "ethrex-l2-rpc" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "axum", "bytes", @@ -1142,6 +1134,7 @@ dependencies = [ "serde_json", "thiserror 2.0.18", "tokio", + "tokio-util", "tower-http", "tracing", "tracing-subscriber", @@ -1150,14 +1143,15 @@ dependencies = [ [[package]] name = "ethrex-levm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", "ethrex-common", "ethrex-crypto", "ethrex-rlp", + "libssz", "malachite", "rayon", "rustc-hash", @@ -1168,8 +1162,8 @@ dependencies = [ [[package]] name = "ethrex-metrics" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "axum", "ethrex-common", @@ -1184,8 +1178,8 @@ dependencies = [ [[package]] name = "ethrex-p2p" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "aes", "aes-gcm", @@ -1228,8 +1222,8 @@ dependencies = [ [[package]] name = "ethrex-rlp" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -1238,8 +1232,8 @@ dependencies = [ [[package]] name = "ethrex-rpc" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "axum", "axum-extra", @@ -1259,6 +1253,7 @@ dependencies = [ "hex-literal", "jsonwebtoken", "rand 0.8.6", + "rayon", "reqwest", "secp256k1", "serde", @@ -1277,8 +1272,8 @@ dependencies = [ [[package]] name = "ethrex-storage" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "anyhow", "bytes", @@ -1299,8 +1294,8 @@ dependencies = [ [[package]] name = "ethrex-storage-rollup" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "async-trait", "bincode", @@ -1315,8 +1310,8 @@ dependencies = [ [[package]] name = "ethrex-trie" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "anyhow", "bytes", @@ -1324,18 +1319,19 @@ dependencies = [ "ethereum-types", "ethrex-crypto", "ethrex-rlp", - "lazy_static", + "hashbrown 0.15.5", "rayon", "rkyv", "rustc-hash", "serde", + "spin", "thiserror 2.0.18", ] [[package]] name = "ethrex-vm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", @@ -1375,7 +1371,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "bitvec", "rand_core 0.6.4", "subtle", ] @@ -2225,6 +2220,47 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libssz" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d498c0482bba87d2647ea4601ea76cf2b498065e3958798a88f49274f3ced5e9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "libssz-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ddfb5c969c28a4a54043e630f80c723352637bd1020f256ee3ac7a8814922b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libssz-merkle" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63c6d6d5ce5d79bba66bc98c99869eedffedf7f14f0aa0915f1a62802650bdf6" +dependencies = [ + "libssz", + "sha2", +] + +[[package]] +name = "libssz-types" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747273ab2d923e82ed147091fe0fb3e602dd2012c872cdad5efe69e27c3b4099" +dependencies = [ + "libssz", + "libssz-merkle", + "smallvec", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2541,15 +2577,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - [[package]] name = "parity-scale-codec" version = "3.7.5" @@ -3543,6 +3570,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" + [[package]] name = "spki" version = "0.7.3" diff --git a/tooling/ethrex-fixtures/Cargo.toml b/tooling/ethrex-fixtures/Cargo.toml index 5e99f37d3..fbbde505d 100644 --- a/tooling/ethrex-fixtures/Cargo.toml +++ b/tooling/ethrex-fixtures/Cargo.toml @@ -7,13 +7,14 @@ edition = "2024" [workspace] [dependencies] -# Pinned to the SAME ethrex rev as the guest (open LambdaVM-backend PR branch) -# so the generated ProgramInput rkyv layout matches what the guest deserializes. -ethrex-blockchain = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-blockchain" } -ethrex-storage = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-storage" } -ethrex-common = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-common" } -ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-guest-program" } -ethrex-l2-rpc = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-l2-rpc" } +# Pinned to the SAME ethrex rev as the guest so the generated ProgramInput rkyv +# layout matches what the guest deserializes. Re-pin all five manifests together +# with scripts/set_ethrex_rev.sh. +ethrex-blockchain = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-blockchain" } +ethrex-storage = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-storage" } +ethrex-common = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-common" } +ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-guest-program" } +ethrex-l2-rpc = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-l2-rpc" } tokio = { version = "1", features = ["rt-multi-thread", "macros"] } # Exact pin: the fixture writer and the guest/executor readers must agree on the diff --git a/tooling/ethrex-fixtures/update_readme_checksums.py b/tooling/ethrex-fixtures/update_readme_checksums.py index 76997dbe1..f9fbee7fb 100644 --- a/tooling/ethrex-fixtures/update_readme_checksums.py +++ b/tooling/ethrex-fixtures/update_readme_checksums.py @@ -12,6 +12,10 @@ "ethrex_empty_block.bin", "ethrex_simple_tx.bin", "ethrex_10_transfers.bin", + # Committed like the three above, but generated in `distinct` mode and read by + # the recursion profile target rather than the executor tests. Omitting it left + # a committed fixture that a rev bump silently staled with nothing to catch it. + "ethrex_bench_4.bin", ) diff --git a/tooling/ethrex-tests/Cargo.lock b/tooling/ethrex-tests/Cargo.lock index 4295b4402..0a86228f1 100644 --- a/tooling/ethrex-tests/Cargo.lock +++ b/tooling/ethrex-tests/Cargo.lock @@ -247,19 +247,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-affine-constructors#78cad0378b17fc3157b83f514be192bf46edf9a1" -dependencies = [ - "digest", - "ff", - "group", - "pairing", - "rand_core", - "subtle", -] - [[package]] name = "bs58" version = "0.5.1" @@ -706,8 +693,8 @@ dependencies = [ [[package]] name = "ethrex-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "crc32fast", @@ -721,6 +708,10 @@ dependencies = [ "indexmap 2.14.0", "lazy_static", "libc", + "libssz", + "libssz-derive", + "libssz-merkle", + "libssz-types", "lru", "once_cell", "rayon", @@ -736,15 +727,13 @@ dependencies = [ [[package]] name = "ethrex-crypto" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", - "bls12_381", "ethereum-types", - "ff", "hex-literal", "k256", "malachite", @@ -759,8 +748,8 @@ dependencies = [ [[package]] name = "ethrex-guest-program" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -778,8 +767,8 @@ dependencies = [ [[package]] name = "ethrex-l2-common" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -797,14 +786,15 @@ dependencies = [ [[package]] name = "ethrex-levm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", "ethrex-common", "ethrex-crypto", "ethrex-rlp", + "libssz", "malachite", "rayon", "rustc-hash", @@ -815,8 +805,8 @@ dependencies = [ [[package]] name = "ethrex-rlp" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "ethereum-types", @@ -834,8 +824,8 @@ dependencies = [ [[package]] name = "ethrex-trie" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "anyhow", "bytes", @@ -843,18 +833,19 @@ dependencies = [ "ethereum-types", "ethrex-crypto", "ethrex-rlp", - "lazy_static", + "hashbrown 0.15.5", "rayon", "rkyv", "rustc-hash", "serde", + "spin", "thiserror 2.0.18", ] [[package]] name = "ethrex-vm" -version = "13.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c" +version = "23.0.0" +source = "git+https://github.com/lambdaclass/ethrex.git?rev=797df5540c7d35cafd69b6971a74b2a49c67d1dd#797df5540c7d35cafd69b6971a74b2a49c67d1dd" dependencies = [ "bytes", "derive_more", @@ -886,7 +877,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "bitvec", "rand_core", "subtle", ] @@ -1290,6 +1280,47 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libssz" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d498c0482bba87d2647ea4601ea76cf2b498065e3958798a88f49274f3ced5e9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "libssz-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ddfb5c969c28a4a54043e630f80c723352637bd1020f256ee3ac7a8814922b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libssz-merkle" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63c6d6d5ce5d79bba66bc98c99869eedffedf7f14f0aa0915f1a62802650bdf6" +dependencies = [ + "libssz", + "sha2", +] + +[[package]] +name = "libssz-types" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747273ab2d923e82ed147091fe0fb3e602dd2012c872cdad5efe69e27c3b4099" +dependencies = [ + "libssz", + "libssz-merkle", + "smallvec", +] + [[package]] name = "log" version = "0.4.33" @@ -1435,15 +1466,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - [[package]] name = "parity-scale-codec" version = "3.7.5" @@ -1952,6 +1974,18 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" + [[package]] name = "spki" version = "0.7.3" diff --git a/tooling/ethrex-tests/Cargo.toml b/tooling/ethrex-tests/Cargo.toml index f4774278d..f7daff1d4 100644 --- a/tooling/ethrex-tests/Cargo.toml +++ b/tooling/ethrex-tests/Cargo.toml @@ -10,9 +10,10 @@ edition = "2024" [dev-dependencies] executor = { path = "../../executor" } -# Pinned to the SAME ethrex rev as the guest (open LambdaVM-backend PR branch) -# so the native reference reads the same ProgramInput rkyv layout. -ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "156cb8d6a3974f411d71622eecd1b249ee37ff1c", package = "ethrex-guest-program" } +# Pinned to the SAME ethrex rev as the guest so the native reference reads the same +# ProgramInput rkyv layout. Re-pin all five manifests together with +# scripts/set_ethrex_rev.sh. +ethrex-guest-program = { git = "https://github.com/lambdaclass/ethrex.git", rev = "797df5540c7d35cafd69b6971a74b2a49c67d1dd", package = "ethrex-guest-program" } # Exact pin: the fixture writer and the guest/executor readers must agree on the # rkyv layout. Keep this in sync with tooling/ethrex-fixtures and # executor/programs/rust/ethrex/Cargo.toml. diff --git a/tooling/ethrex-tests/tests/ethrex.rs b/tooling/ethrex-tests/tests/ethrex.rs index 6374f2f43..4fa53971c 100644 --- a/tooling/ethrex-tests/tests/ethrex.rs +++ b/tooling/ethrex-tests/tests/ethrex.rs @@ -127,11 +127,13 @@ fn test_ethrex_real_block_native() { /// backend too (invalid G1 encoding), and both paths surface as /// `CryptoError::Other`, so the variant can't tell them apart. The string comes /// from `ethrex-crypto`'s `KzgError::Unimplemented`; if upstream rewords it this -/// test goes red, which is the safe direction. +/// test goes red, which is the safe direction — and it has: the 4f658c2b rev bump +/// dropped `openvm-kzg` from the sentence, so the expected text moved with it. /// /// Worth knowing why this can regress: `ethrex-crypto`'s own default feature set -/// is `["std", "kzg-rs", "secp256k1"]`, so any future dependency pulling it in -/// with defaults on restores a backend and silently removes the screen. +/// is `["std", "kzg-rs", "secp256k1", "aws-lc-rs", "blst"]`, so any future +/// dependency pulling it in with defaults on restores a backend and silently +/// removes the screen. #[test] fn no_kzg_backend_linked() { use ethrex_guest_program::crypto::{Crypto, NativeCrypto}; @@ -141,12 +143,31 @@ fn no_kzg_backend_linked() { Err(err) => format!("{err:?}"), }; assert!( - message.contains("One of features c-kzg, openvm-kzg or kzg-rs should be active"), + message.contains("One of features c-kzg or kzg-rs should be active"), "a KZG backend is linked into ethrex-tests, so test_ethrex_real_block_native no \ longer screens precompile 0x0a: {message}" ); } +/// Same screen for EIP-2537 (0x0b-0x11), which the 797df554 bump moved behind the +/// native-only `blst` feature. Unlike the KZG gap these do NOT revert: levm maps +/// `CryptoError::Unsupported` to `InternalError`, which aborts the run. Goes red if a +/// dependency restores a backend, or if upstream rewords the message. +#[test] +fn no_bls_backend_linked() { + use ethrex_guest_program::crypto::{Crypto, NativeCrypto}; + let result = NativeCrypto.bls12_381_g1_add(([0u8; 48], [0u8; 48]), ([0u8; 48], [0u8; 48])); + let message = match result { + Ok(_) => "bls12_381_g1_add accepted zero input".to_string(), + Err(err) => format!("{err:?}"), + }; + assert!( + message.contains("requires the `blst` feature"), + "a BLS12-381 backend is linked into ethrex-tests, so the native reference no \ + longer matches the guest on 0x0b-0x11: {message}" + ); +} + /// The same real block through the guest ELF, checking the VM's committed /// output matches the native reference. Split from the native gate above /// because this one needs the ethrex ELF and is far heavier than the synthetic