Skip to content

Commit c8c440d

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 7974e45 commit c8c440d

17 files changed

Lines changed: 1868 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: 46 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,12 @@ 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+
compile-programs: compile-programs-asm compile-programs-rust compile-bench compile-recursion-elfs
145+
146+
compile-recursion-elfs: prepare-sysroot $(RECURSION_ARTIFACTS)
147+
148+
$(RECURSION_ARTIFACTS_DIR):
149+
mkdir -p $@
137150

138151

139152
$(RUST_ARTIFACTS_DIR):
@@ -142,13 +155,19 @@ $(RUST_ARTIFACTS_DIR):
142155
$(BENCH_ARTIFACTS_DIR):
143156
mkdir -p $@
144157

158+
# The guest .elf rules depend on FORCE so their recipe always runs: cargo already
159+
# tracks the full dependency graph, so we let it decide what to rebuild (a fast
160+
# no-op when nothing changed) rather than re-encode that in Make prereqs.
161+
.PHONY: FORCE
162+
FORCE:
163+
145164
# Compile rust (64-bit)
146165
# Order-only `| prepare-sysroot` so a direct `make .../foo.elf` provisions the sysroot
147166
# first (the aggregate compile-programs-rust/compile-bench targets already do, but a
148167
# bare pattern-rule invocation like `make -B .../ethrex.elf` would otherwise skip it
149168
# and fail to compile guest C dependencies). Order-only because prepare-sysroot is
150169
# .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)
170+
$(RUST_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(RUST_ARTIFACTS_DIR)
152171
cd $(RUST_PROGRAMS_DIR)/$* && \
153172
CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \
154173
CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \
@@ -160,7 +179,7 @@ $(RUST_ARTIFACTS_DIR)/%.elf: $(RUST_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot
160179
cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$* $@
161180

162181
# Compile rust benches (64-bit)
163-
$(BENCH_ARTIFACTS_DIR)/%.elf: $(BENCH_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot $(BENCH_ARTIFACTS_DIR)
182+
$(BENCH_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(BENCH_ARTIFACTS_DIR)
164183
cd $(BENCH_PROGRAMS_DIR)/$* && \
165184
CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \
166185
CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \
@@ -171,6 +190,22 @@ $(BENCH_ARTIFACTS_DIR)/%.elf: $(BENCH_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysro
171190
-Z json-target-spec
172191
cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$* $@
173192

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

@@ -183,7 +218,10 @@ clean-bench:
183218
clean-shared:
184219
-rm -rf $(SHARED_TARGET_DIR)
185220

186-
clean: clean-asm clean-rust clean-bench clean-shared
221+
clean-recursion-elfs:
222+
-rm -rf $(RECURSION_ARTIFACTS_DIR)
223+
224+
clean: clean-asm clean-rust clean-bench clean-shared clean-recursion-elfs
187225

188226
test-executor: compile-programs
189227
cargo test -p executor
@@ -225,8 +263,9 @@ test-fast:
225263
test-prover:
226264
cargo test -p lambda-vm-prover
227265

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

232271
# 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)