Skip to content

Commit 90a942f

Browse files
committed
feat: enable recursion
- Introduces smoke test with verification of empty program - Implements `__getrandom_v03_custom` to avoid panics when accessing hashmaps - Updated test to expect deterministic output by inspecting the current output
1 parent f9db93e commit 90a942f

17 files changed

Lines changed: 1878 additions & 24 deletions

File tree

Cargo.lock

Lines changed: 118 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.PHONY: deps deps-linux deps-macos compile-programs-asm compile-programs-rust compile-bench \
2-
compile-programs clean-asm clean-rust clean-bench clean-shared clean test test-asm \
2+
compile-programs compile-recursion-elfs clean-asm clean-rust clean-bench clean-shared \
3+
clean-recursion-elfs clean test test-asm \
34
test-rust test-executor test-flamegraph flamegraph-prover \
45
test-fast test-prover test-prover-all test-disk-spill test-math-cuda test-cuda-integration \
56
bench-math-cuda bench-prover bench-prover-cuda build check clippy fmt lint regen-ethrex-fixtures \
@@ -46,6 +47,13 @@ BENCH_PROGRAM_DIRS := $(dir $(wildcard $(BENCH_PROGRAMS_DIR)/*/Cargo.toml))
4647
BENCH_PROGRAMS := $(notdir $(basename $(BENCH_PROGRAM_DIRS:%/=%)))
4748
BENCH_ARTIFACTS := $(addprefix $(BENCH_ARTIFACTS_DIR)/, $(addsuffix .elf, $(BENCH_PROGRAMS)))
4849

50+
# Recursion smoke-test guests, in bench_vs/lambda/ (shared with bench_vs/run.sh)
51+
# rather than executor/programs/. The recursion guest is the in-VM STARK verifier.
52+
RECURSION_GUESTS_DIR=./bench_vs/lambda
53+
RECURSION_ARTIFACTS_DIR=./executor/program_artifacts/recursion
54+
RECURSION_GUESTS := empty fibonacci recursion
55+
RECURSION_ARTIFACTS := $(addprefix $(RECURSION_ARTIFACTS_DIR)/, $(addsuffix .elf, $(RECURSION_GUESTS)))
56+
4957
# Override with: make ... SYSROOT_DIR=$HOME/.lambda-vm-sysroot
5058
# to install the sysroot in a user-writable location and avoid sudo.
5159
SYSROOT_DIR ?= /opt/lambda-vm-sysroot
@@ -133,7 +141,14 @@ compile-programs-rust: prepare-sysroot $(RUST_ARTIFACTS)
133141

134142
compile-bench: prepare-sysroot $(BENCH_ARTIFACTS)
135143

136-
compile-programs: compile-programs-asm compile-programs-rust compile-bench
144+
# NOTE: recursion ELFs are temporarily unused by the main tests due to long running time.
145+
# We compile them anyway to ensure they keep building until their tests are fast enough to run on the CI.
146+
compile-programs: compile-programs-asm compile-programs-rust compile-bench compile-recursion-elfs
147+
148+
compile-recursion-elfs: prepare-sysroot $(RECURSION_ARTIFACTS)
149+
150+
$(RECURSION_ARTIFACTS_DIR):
151+
mkdir -p $@
137152

138153

139154
$(RUST_ARTIFACTS_DIR):
@@ -142,13 +157,19 @@ $(RUST_ARTIFACTS_DIR):
142157
$(BENCH_ARTIFACTS_DIR):
143158
mkdir -p $@
144159

160+
# The guest .elf rules depend on FORCE so their recipe always runs: cargo already
161+
# tracks the full dependency graph, so we let it decide what to rebuild (a fast
162+
# no-op when nothing changed) rather than re-encode that in Make prereqs.
163+
.PHONY: FORCE
164+
FORCE:
165+
145166
# Compile rust (64-bit)
146167
# Order-only `| prepare-sysroot` so a direct `make .../foo.elf` provisions the sysroot
147168
# first (the aggregate compile-programs-rust/compile-bench targets already do, but a
148169
# bare pattern-rule invocation like `make -B .../ethrex.elf` would otherwise skip it
149170
# and fail to compile guest C dependencies). Order-only because prepare-sysroot is
150171
# .PHONY — a normal prereq would force a rebuild every time; its recipe is idempotent.
151-
$(RUST_ARTIFACTS_DIR)/%.elf: $(RUST_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot $(RUST_ARTIFACTS_DIR)
172+
$(RUST_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(RUST_ARTIFACTS_DIR)
152173
cd $(RUST_PROGRAMS_DIR)/$* && \
153174
CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \
154175
CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \
@@ -160,7 +181,7 @@ $(RUST_ARTIFACTS_DIR)/%.elf: $(RUST_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot
160181
cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$* $@
161182

162183
# Compile rust benches (64-bit)
163-
$(BENCH_ARTIFACTS_DIR)/%.elf: $(BENCH_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot $(BENCH_ARTIFACTS_DIR)
184+
$(BENCH_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(BENCH_ARTIFACTS_DIR)
164185
cd $(BENCH_PROGRAMS_DIR)/$* && \
165186
CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \
166187
CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \
@@ -171,6 +192,22 @@ $(BENCH_ARTIFACTS_DIR)/%.elf: $(BENCH_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysro
171192
-Z json-target-spec
172193
cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$* $@
173194

195+
# Recursion-suite guests: same standard guest flags as compile-bench (std-inclusive
196+
# build-std works for both the no_std inner guests and the std recursion verifier).
197+
# The crate's binary is <name>-bench; copy it to <name>.elf so prover tests read
198+
# prebuilt artifacts like every other program (see
199+
# prover/src/tests/recursion_smoke_test.rs), instead of shelling out.
200+
$(RECURSION_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(RECURSION_ARTIFACTS_DIR)
201+
cd $(RECURSION_GUESTS_DIR)/$* && \
202+
CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \
203+
CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \
204+
rustup run nightly-2026-02-01 cargo build --release \
205+
--target $(RV64_TARGET_SPEC) \
206+
-Z build-std=core,alloc,std,compiler_builtins,panic_abort \
207+
-Z build-std-features=compiler-builtins-mem \
208+
-Z json-target-spec
209+
cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$*-bench $@
210+
174211
clean-asm:
175212
-rm -rf $(ASM_ARTIFACTS_DIR)
176213

@@ -183,7 +220,10 @@ clean-bench:
183220
clean-shared:
184221
-rm -rf $(SHARED_TARGET_DIR)
185222

186-
clean: clean-asm clean-rust clean-bench clean-shared
223+
clean-recursion-elfs:
224+
-rm -rf $(RECURSION_ARTIFACTS_DIR)
225+
226+
clean: clean-asm clean-rust clean-bench clean-shared clean-recursion-elfs
187227

188228
test-executor: compile-programs
189229
cargo test -p executor
@@ -225,8 +265,9 @@ test-fast:
225265
test-prover:
226266
cargo test -p lambda-vm-prover
227267

228-
# Prover tests including slow ones
229-
test-prover-all:
268+
# Prover tests including slow ones. The recursion smoke tests (#[ignore]d) read
269+
# prebuilt guest ELFs from executor/program_artifacts/recursion/, so build them first.
270+
test-prover-all: compile-recursion-elfs
230271
cargo test -p lambda-vm-prover -- --include-ignored
231272

232273
# Prover tests with debug-checks (shows bus balance report)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[target.riscv64im-lambda-vm-elf]
2+
rustflags = [
3+
"-C", "link-arg=-e",
4+
"-C", "link-arg=main",
5+
"-C", "passes=lower-atomic"
6+
]

bench_vs/lambda/empty/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bench_vs/lambda/empty/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[workspace]
2+
3+
[package]
4+
name = "empty-bench"
5+
version = "0.1.0"
6+
edition = "2024"
7+
8+
[dependencies]

bench_vs/lambda/empty/src/main.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
use core::arch::asm;
5+
use core::panic::PanicInfo;
6+
7+
const SYSCALL_HALT: u64 = 93;
8+
9+
#[panic_handler]
10+
fn panic(_info: &PanicInfo) -> ! {
11+
loop {}
12+
}
13+
14+
fn halt() -> ! {
15+
unsafe {
16+
asm!(
17+
"ecall",
18+
in("a0") 0u64,
19+
in("a7") SYSCALL_HALT,
20+
options(noreturn),
21+
);
22+
}
23+
}
24+
25+
#[unsafe(no_mangle)]
26+
pub fn main() -> ! {
27+
halt()
28+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[target.riscv64im-lambda-vm-elf]
2+
rustflags = [
3+
"-C", "link-arg=-e",
4+
"-C", "link-arg=main",
5+
"--cfg", "getrandom_backend=\"custom\"",
6+
"-C", "passes=lower-atomic"
7+
]

0 commit comments

Comments
 (0)