Skip to content
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c927a54
feat(misc): Added details on GP VK anchoring and update management
Filter94 Jul 13, 2026
b76a825
fix(misc): Fixed review comment
Filter94 Jul 13, 2026
8562c21
fix(misc): Fixed review comment
Filter94 Jul 13, 2026
b70b4ee
fix(misc): Split the verifiable proof and the GP output proof
Filter94 Jul 14, 2026
d972658
fix(misc): Fixed merge conflict
Filter94 Jul 14, 2026
89e4614
feat(riscv-guest): WIP extended guest program
Filter94 Jul 16, 2026
0843aea
Merge branch 'main' of github.com:LFDT-Lineth/lineth-monorepo into fe…
Filter94 Jul 16, 2026
8ec2bc7
feat(riscv-guest): WIP implementation of the l2-execution extended gu…
Filter94 Jul 16, 2026
89e7b09
chore(riscv-guest): Removed the vanilla guest runner, the tests, refo…
Filter94 Jul 16, 2026
1e0e077
chore(riscv-guest): Reverting the output reformat change
Filter94 Jul 16, 2026
230c1bf
fix(riscv-guest): Reference tests update, some fixes
Filter94 Jul 29, 2026
08a5358
Merge branch 'main' of github.com:LFDT-Lineth/lineth-monorepo into fe…
Filter94 Jul 29, 2026
3589a99
fix(riscv-guest): Hopefully fixed the tests
Filter94 Jul 29, 2026
8aaf4cd
fix(riscv-guest): Fixed some tests setup on CI
Filter94 Jul 29, 2026
77e32d9
Merge branch 'main' of github.com:LFDT-Lineth/lineth-monorepo into fe…
Filter94 Jul 29, 2026
e360c64
fix(riscv-guest): Memory management
Filter94 Jul 29, 2026
68f5dae
fix(ci): Removed unused opcode variable
Filter94 Jul 29, 2026
8441b52
Merge branch 'main' of github.com:LFDT-Lineth/lineth-monorepo into fe…
Filter94 Jul 31, 2026
8e5376c
fix(riscv-guest): Fixed merge conflict. Enabled precompiles software …
Filter94 Jul 31, 2026
5f32609
fix(riscv-guest): Fixed merge conflict. Enabled precompiles software …
Filter94 Jul 31, 2026
f2ffefd
chore(riscv-guest): Fixed merge conflict
Filter94 Aug 10, 2026
5f232ae
fix(misc): Fixed lineth rename
Filter94 Aug 10, 2026
a7f31cc
Merge branch 'main' of github.com:LFDT-Lineth/lineth-monorepo into fe…
Filter94 Aug 12, 2026
6201e56
refactor(riscv-guest): make l2-execution base PR implementation-only
Filter94 Aug 13, 2026
fcdd878
fix(riscv-guest): make install-native-crypto-deps portable
Filter94 Aug 13, 2026
a71fc5a
fix(ci): validate the RISC-V guest-program workflows on stacked PRs, …
Filter94 Aug 18, 2026
2def433
fix(riscv-guest): Fixed merge conflict
Filter94 Aug 18, 2026
5352e60
fix(misc): Fixed the rollup spec tests
Filter94 Aug 18, 2026
a9d5d8b
fix(riscv-guest): Remove the go script for vanilla GP input generatio…
Filter94 Aug 19, 2026
bc78c85
Merge branch 'main' of github.com:LFDT-Lineth/lineth-monorepo into fe…
Filter94 Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/actions/setup-arithmetization-riscv/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ runs:
echo "${HOME}/.local/bin" >> "${GITHUB_PATH}"
echo "${HOME}/.local/share/mise/shims" >> "${GITHUB_PATH}"

# blst + mcl are not packaged for Ubuntu; `install-native-crypto-deps` (riscv-guests/Makefile)
# builds them from the pinned tags once and installs into /usr/local — the SAME command a
# developer runs locally, and the same one .github/actions/setup-riscv-guests calls, so there
# is one recipe to keep in sync instead of two. The l2-execution guest's native host tools
# (l2-execution-wrap, l2-execution-runner) link them via the default `zig build` step this job
# also runs, even though the benchmark itself only consumes the freestanding riscv64 ELF.
- name: Cache blst + mcl builds
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
/usr/local/lib/libblst.a
/usr/local/lib/libmcl.so
/usr/local/include/blst.h
/usr/local/include/blst_aux.h
/usr/local/include/mcl
key: crypto-libs-blst-e7f90de551e8df682f3cc99067d204d8b90d27ad-mcl-0499298adcfad3bbcebf77f17700ebbe97166060

- name: Install native crypto deps (blst, mcl)
shell: bash
run: make -C riscv-guests install-native-crypto-deps

- name: Install riscv64-unknown-elf toolchain
# Install the riscv64-unknown-elf toolchain
# Use the xpack-dev-tools/riscv-none-elf-gcc-xpack for riscv64-none-elf-gcc
Expand Down
50 changes: 11 additions & 39 deletions .github/actions/setup-riscv-guests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,51 +20,23 @@ runs:
version: ${{ steps.zigversion.outputs.version }}
dependency-hash-paths: riscv-guests/*/build.zig.zon

- name: Install apt crypto dependencies
shell: bash
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends libsecp256k1-dev libssl-dev build-essential git

# blst + mcl are not packaged for Ubuntu; build once from pinned tags and cache the artifacts.
# Bump the two SHAs here AND in the cache key together.
# blst + mcl are not packaged for Ubuntu; `install-native-crypto-deps` builds them from the
# pinned tags once and installs into /usr/local — the SAME command a developer runs locally.
# Cache /usr/local's result directly so a hit skips straight to a no-op inside that target.
- name: Cache blst + mcl builds
id: crypto-cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.crypto-libs
path: |
/usr/local/lib/libblst.a
/usr/local/lib/libmcl.so
/usr/local/include/blst.h
/usr/local/include/blst_aux.h
/usr/local/include/mcl
key: crypto-libs-blst-e7f90de551e8df682f3cc99067d204d8b90d27ad-mcl-0499298adcfad3bbcebf77f17700ebbe97166060

- name: Build blst and mcl from source
if: steps.crypto-cache.outputs.cache-hit != 'true'
shell: bash
run: |
BLST_SHA=e7f90de551e8df682f3cc99067d204d8b90d27ad # v0.3.16
MCL_SHA=0499298adcfad3bbcebf77f17700ebbe97166060 # v3.06
STAGE="$HOME/.crypto-libs"
mkdir -p "$STAGE/lib" "$STAGE/include"

git clone https://github.com/supranational/blst.git "$HOME/blst-src"
git -C "$HOME/blst-src" checkout --detach "$BLST_SHA"
(cd "$HOME/blst-src" && ./build.sh)
cp "$HOME/blst-src/libblst.a" "$STAGE/lib/"
cp "$HOME/blst-src/bindings/blst.h" "$HOME/blst-src/bindings/blst_aux.h" "$STAGE/include/"

git clone https://github.com/herumi/mcl.git "$HOME/mcl-src"
git -C "$HOME/mcl-src" checkout --detach "$MCL_SHA"
make -C "$HOME/mcl-src" -j"$(nproc)"
cp "$HOME/mcl-src/lib/libmcl.so" "$STAGE/lib/"
cp -r "$HOME/mcl-src/include/mcl" "$STAGE/include/"

- name: Install blst and mcl into /usr/local
- name: Install native crypto deps (blst, mcl)
shell: bash
run: |
sudo cp "$HOME/.crypto-libs/lib/libblst.a" /usr/local/lib/
sudo cp "$HOME/.crypto-libs/lib/libmcl.so" /usr/local/lib/
sudo rm -f /usr/local/lib/libmcl.a
sudo cp "$HOME/.crypto-libs/include/blst.h" "$HOME/.crypto-libs/include/blst_aux.h" /usr/local/include/
sudo cp -r "$HOME/.crypto-libs/include/mcl" /usr/local/include/
sudo ldconfig
run: make -C riscv-guests install-native-crypto-deps

# Zig package fetches (zesu, zesu-zkvm, EF zkevm fixtures) land in each guest's zig-pkg/.
- name: Cache Zig package fetches
Expand Down
13 changes: 6 additions & 7 deletions .github/workflows/riscv-guests-host-tests.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Host-machine CI for the RISC-V guest programs (riscv-guests/):
# - host-tests: `make test` — the top-level orchestrator fans the native unit tests out to every
# guest in GUESTS (single-fixture smoke test, delegated-accel integration test, …).
# - spec-tests: `make spec-test` in l2-execution — the FULL EF execution-spec-tests zkevm
# stateless suite (~2,880 fixture files / ~16.8k blocks) run through the guest on the host.
# This is deliberately NOT orchestrated: the EF suite only exists for the EVM-execution guest.
# - reference-tests: `make reference-test` in l2-execution — the dummy-wrap-vs-fixture-truth
# reference-test guard (extended_vanilla_runner.zig), over the Amsterdam EF corpus.
# Both run the guest logic natively (no RISC-V, no ZKC); running the guest through the ZKC
# interpreter is covered separately, by its own dedicated workflow.
name: riscv-guests host tests
Expand Down Expand Up @@ -53,8 +52,8 @@ jobs:
working-directory: riscv-guests
timeout-minutes: 20

spec-tests:
name: l2-execution EF spec tests (host)
reference-tests:
name: l2-execution extended-guest reference-test guards (host)
runs-on: gha-lfdt-lineth-ss-ubuntu-24-amd64-large
steps:
- name: Checkout repository
Expand All @@ -65,8 +64,8 @@ jobs:
- name: Setup Environment
uses: ./.github/actions/setup-riscv-guests

- name: Run full EF zkevm stateless fixture suite
run: make spec-test
- name: Run extended-guest reference-test guards
run: make reference-test
working-directory: riscv-guests/l2-execution
timeout-minutes: 30

2 changes: 1 addition & 1 deletion .husky/commit-msg
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ALLOWED_SCOPES=\
'coordinator prover prover-ray verifier-ray postman tx-exclusion-api '\
'linea-besu contracts sdk-core sdk-ethers sdk-viem '\
'tracer sequencer state-recovery jvm-libs blob-libs '\
'e2e ci docker deps misc maru'
'e2e ci docker deps misc maru riscv-guest'

# Match overall structure: <type>(<scope-group>)!?: <subject>
HEADER_RE="^(${ALLOWED_TYPES})\\(([^)]+)\\)!?: .+"
Expand Down
1 change: 1 addition & 0 deletions riscv-guests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ zig-out/
zig-pkg/
.cache/
*.objdump
*/.cache/
57 changes: 56 additions & 1 deletion riscv-guests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ZIG ?= zig
# Mirrors the CI `zig fmt --check` invocation (riscv-guests-host-tests.yml) and scales with GUESTS.
FMT_PATHS := build_common/build.zig $(foreach g,$(GUESTS),$(g)/build.zig $(g)/src $(g)/test)

.PHONY: compile test fetch clean fmt fmt-check help
.PHONY: compile test fetch clean fmt fmt-check help install-native-crypto-deps

# Each common target fans out to every guest's own Makefile.
compile test fetch clean:
Expand All @@ -27,6 +27,60 @@ compile test fetch clean:
$(MAKE) -C $$g $@ ZIG="$(ZIG)" || exit $$?; \
done

# Native crypto libs (blst, mcl) that zesu's native host backend links — needed to build/run any
# guest's native host tools (unit tests, the wrap/runner CLIs), never for the freestanding riscv64
# guest ELF itself. Not packaged for Ubuntu, so built from pinned upstream tags; idempotent (skips
# already-installed libs), so this is the SAME command whether run in CI or on a dev machine —
# CI's job is only to cache the result, not to own a separate copy of this recipe. Bump the two SHAs
# below when updating (keep in sync with any CI cache key that also names them).
BLST_SHA := e7f90de551e8df682f3cc99067d204d8b90d27ad
MCL_SHA := 0499298adcfad3bbcebf77f17700ebbe97166060

install-native-crypto-deps:
@set -eu; \
uname_s=$$(uname -s); \
if [ "$$uname_s" = "Darwin" ]; then \
command -v brew >/dev/null 2>&1 || { echo "Homebrew not found: https://brew.sh"; exit 1; }; \
brew install secp256k1 openssl || true; \
prefix=/opt/homebrew; \
sudo=""; \
else \
Comment thread
Copilot marked this conversation as resolved.
sudo apt-get update -qq; \
sudo apt-get install -y --no-install-recommends libsecp256k1-dev libssl-dev build-essential git; \
prefix=/usr/local; \
sudo="sudo"; \
fi; \
Comment thread
Filter94 marked this conversation as resolved.
Outdated
if [ -f "$$prefix/lib/libblst.a" ]; then \
echo "blst already installed at $$prefix/lib/libblst.a"; \
else \
echo "Building blst from source ($(BLST_SHA))..."; \
rm -rf /tmp/blst-src; \
git clone https://github.com/supranational/blst.git /tmp/blst-src; \
git -C /tmp/blst-src checkout --detach $(BLST_SHA); \
(cd /tmp/blst-src && ./build.sh); \
$$sudo mkdir -p "$$prefix/lib" "$$prefix/include"; \
$$sudo cp /tmp/blst-src/libblst.a "$$prefix/lib/"; \
$$sudo cp /tmp/blst-src/bindings/blst.h /tmp/blst-src/bindings/blst_aux.h "$$prefix/include/"; \
fi; \
if [ -f "$$prefix/lib/libmcl.so" ] || [ -f "$$prefix/lib/libmcl.dylib" ]; then \
echo "mcl already installed under $$prefix/lib"; \
else \
echo "Building mcl from source ($(MCL_SHA))..."; \
rm -rf /tmp/mcl-src; \
git clone https://github.com/herumi/mcl.git /tmp/mcl-src; \
git -C /tmp/mcl-src checkout --detach $(MCL_SHA); \
$(MAKE) -C /tmp/mcl-src; \
$$sudo mkdir -p "$$prefix/lib" "$$prefix/include"; \
if [ "$$uname_s" = "Darwin" ]; then \
$$sudo cp /tmp/mcl-src/lib/libmcl.dylib "$$prefix/lib/" 2>/dev/null || $$sudo cp /tmp/mcl-src/lib/libmcl.a "$$prefix/lib/"; \
else \
$$sudo rm -f "$$prefix/lib/libmcl.a"; \
$$sudo cp /tmp/mcl-src/lib/libmcl.so "$$prefix/lib/"; \
$$sudo ldconfig; \
fi; \
$$sudo cp -r /tmp/mcl-src/include/mcl "$$prefix/include/"; \
fi

# Formatting spans build_common + all guests, so it lives here (not fanned out). `fmt` rewrites in
# place; `fmt-check` only verifies — the same gate CI runs.
fmt:
Expand All @@ -44,4 +98,5 @@ help:
@echo " make clean # remove each guest's zig-out/ and .zig-cache/"
@echo " make fmt # format build_common + all guest sources in place (zig fmt)"
@echo " make fmt-check # verify formatting without writing (the CI gate)"
@echo " make install-native-crypto-deps # install blst/mcl for native host-tool builds"
@echo ""
22 changes: 11 additions & 11 deletions riscv-guests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ riscv-guests/
l2-execution/ Vanilla EVM execution guest: build.zig + build.zig.zon + Makefile + src/ + test/
```

Within a guest, `src/` holds **only the production code that ships in the rv64im object/ELF**; host-only code (unit tests, the spec-test harness, fixture parsing) lives in `test/`, and committed sample/test data in `test/testdata/`. The split mirrors what `build.zig` builds: the object + `elf` step compile `src/`; `zig build test` / `spec-tests` compile `test/`. (Automated tests pull their EF fixtures from the lazy `execution_spec_tests_zkevm` dependency, not from committed data — `test/testdata/` is just the manual ZkC-run samples.)
Within a guest, `src/` holds **only the production code that ships in the rv64im object/ELF**; host-only code (unit tests, the reference-test harness, fixture parsing) lives in `test/`, and committed sample/test data in `test/testdata/`. The split mirrors what `build.zig` builds: the object + `elf` step compile `src/`; `zig build test` / `extended-vanilla` compile `test/`. (Automated tests pull their EF fixtures from the lazy `execution_spec_tests_zkevm` dependency, not from committed data — `test/testdata/` is just the manual ZkC-run samples.)

**Add a guest:** create `riscv-guests/<name>/` (its own `build.zig`, `build.zig.zon`, `Makefile`, `src/` for production code + `test/` for host tests, depending on `../build_common`) and append `<name>` to `GUESTS` in the top-level `Makefile`. Future guests (Rollup, Aggregation) slot in this way — each with its own dependencies and compile/lint sequence.

Expand Down Expand Up @@ -63,18 +63,18 @@ make -C l2-execution compile ZIG=/path/to/zig IN_ORIGIN=0x08800000 # override

`make -C l2-execution compile` builds the guest as a **statically-linked rv64im ELF** under `<guest>/zig-out/bin/` — the [zkvm-standards](https://github.com/eth-act/zkvm-standards/blob/main/standards/riscv-target/target.md) artifact ("Object Format: ELF, statically linked"). `make test` runs the native Zig unit tests (see [Native test dependencies](#native-test-dependencies)).

### Spec tests (l2-execution only — full EF zkevm fixture suite)
### Reference tests (l2-execution only — full EF zkevm fixture suite)

The EF stateless-fixture suite is specific to the EVM-execution guest, so `spec-test` is an **l2-execution target**, not an orchestrated one (a rollup/aggregation guest has no equivalent). `make test` is the fast single-fixture smoke test; the full suite:
l2-execution is the Rollup's extended guest, not a vanilla EVM-execution guest — the EF stateless-fixture suite is used as a reference test: it asserts the dummy-wrapped extended guest (`runL2Execution`) agrees with the fixture's own expected validity verdict on block validity (the reference-test corpus is the source of truth — no second, independently re-run implementation needed), so `reference-test` is an **l2-execution target**, not an orchestrated one (a rollup/aggregation guest has no equivalent). `make test` is the fast single-fixture smoke test; the full suite:

```bash
make -C l2-execution spec-test ZIG=/path/to/zig
make -C l2-execution spec-test ZIG=/path/to/zig SPEC_ARGS="--fork Amsterdam"
make -C l2-execution spec-test ZIG=/path/to/zig SPEC_ARGS="--match bal_self_transfer"
make -C l2-execution spec-test ZIG=/path/to/zig SPEC_ARGS="--report-only"
make -C l2-execution reference-test ZIG=/path/to/zig
make -C l2-execution reference-test ZIG=/path/to/zig REFERENCE_ARGS="--fork Amsterdam"
make -C l2-execution reference-test ZIG=/path/to/zig REFERENCE_ARGS="--match bal_self_transfer"
make -C l2-execution reference-test ZIG=/path/to/zig REFERENCE_ARGS="--report-only"
```

The runner walks the `blockchain_tests/` tree from the lazy `execution_spec_tests_zkevm` dependency and runs every block through the guest, failing if any output differs from the fixture's expected `statelessOutputBytes`. The corpus walking/reporting is reusable ([`spec_runner.zig`](l2-execution/test/spec_runner.zig)); a future extended-execution guest supplies its own input **adapter** ([`evm_spec_runner.zig`](l2-execution/test/evm_spec_runner.zig) is the vanilla one).
The runner walks the `blockchain_tests/` tree from the lazy `execution_spec_tests_zkevm` dependency and, for every block, wraps it into a dummy-filled extended input and checks the extended guest's validity verdict against the fixture's own expected `successful_validation` result — see [`extended_vanilla_runner.zig`](l2-execution/test/extended_vanilla_runner.zig). The corpus walking/reporting is reusable ([`spec_runner.zig`](l2-execution/test/spec_runner.zig)); `extended_vanilla_runner.zig` supplies the only adapter that plugs into it today.

## Continuous Integration

Expand All @@ -83,9 +83,9 @@ Two workflows guard the guests.
[`riscv-guests-host-tests.yml`](../.github/workflows/riscv-guests-host-tests.yml) runs on every PR touching `riscv-guests/**`, with two parallel host-machine jobs:

- **Guest unit tests** — `zig fmt --check` plus the orchestrated `make test` (every guest in `GUESTS`).
- **l2-execution EF spec tests** — the full fixture suite via `make spec-test` (fail-hard; ~2,900 files / ~23k blocks, minutes on a warm cache).
- **l2-execution extended-guest reference-test guards** — the full EF fixture suite via `make reference-test` (fail-hard; ~2,900 files / ~23k blocks, minutes on a warm cache).

[`riscv-guests-zkc-interpreter-run.yml`](../.github/workflows/riscv-guests-zkc-interpreter-run.yml) runs the complementary guest **under zkc**: it builds the l2-execution guest with the prover-accelerated keccak op (`KECCAK_ACCEL=true`) and executes it on the committed sample input via `make -C l2-execution exec ZKC_EXEC_FLAGS="--quiet --gogen --fast"` (the ELF → JSON → `zkc` path described below). Execution uses zkc's **generated-Go backend in fast mode** (`--gogen --fast`) rather than the tree-walking interpreter, because tracing is not implemented yet — a far lighter path (tens of MB, seconds). It triggers on `riscv-guests/**` **and** the interpreter program + tooling it depends on under `arithmetization/` (the `main.zkc` program, the zkc stdlib, the keccak wrapper, and `elf_to_json_gen`), and tracks the `zkc` `main` branch by default (override with the `zkc-ref` workflow input). This is a *runnability* gate — output-correctness over the full corpus is the host spec-test suite's job above.
[`riscv-guests-zkc-interpreter-run.yml`](../.github/workflows/riscv-guests-zkc-interpreter-run.yml) runs the complementary guest **under zkc**: it builds the l2-execution guest with the prover-accelerated keccak op (`KECCAK_ACCEL=true`) and executes it on the committed sample input via `make -C l2-execution exec ZKC_EXEC_FLAGS="--quiet --gogen --fast"` (the ELF → JSON → `zkc` path described below). Execution uses zkc's **generated-Go backend in fast mode** (`--gogen --fast`) rather than the tree-walking interpreter, because tracing is not implemented yet — a far lighter path (tens of MB, seconds). It triggers on `riscv-guests/**` **and** the interpreter program + tooling it depends on under `arithmetization/` (the `main.zkc` program, the zkc stdlib, the keccak wrapper, and `elf_to_json_gen`), and tracks the `zkc` `main` branch by default (override with the `zkc-ref` workflow input). This is a *runnability* gate — output-correctness over the full corpus is the host reference-test suite's job above.

The host-tests setup lives in [`.github/actions/setup-riscv-guests`](../.github/actions/setup-riscv-guests/action.yml): it installs the Zig pinned in `.zigversion` (via community mirrors — ziglang.org prunes dev builds), the apt crypto packages, and blst/mcl built from pinned upstream sources into `/usr/local`, with the builds and Zig package fetches cached. The interpreter-run workflow reuses that same action for the guest build (the freestanding ELF links none of the crypto) and adds Go plus a `zkc` install.

Expand All @@ -104,5 +104,5 @@ These need `zkc` and `go` on `PATH`. The interpreter loads a finished ELF — `e

Each guest folder is a complete package: its own dependencies (`build.zig.zon`), compile/test logic (`build.zig`), lifecycle (`Makefile`), production source (`src/`) and host-only test code (`test/`). Shared build helpers are factored into `build_common/`; the toolchain pin (`.zigversion`) is shared at this level.

- `l2-execution/`: vanilla EVM execution guest. See `l2-execution/README.md`.
- `l2-execution/`: the Rollup's extended l2-execution guest. See `l2-execution/README.md`.
```
Loading
Loading