Summary
spel init (in init_project, spel-cli/src/init.rs) generates two separate guest-related crates in every scaffolded project, only one of which is actually used:
-
methods/guest/ — excluded from the cargo workspace, containing the real #[lez_program] guest binary (methods/guest/src/bin/{snake_name}.rs). This is what the generated Makefile's build target actually compiles, correctly using the deterministic, Docker-pinned strategy:
|
cargo risczero build --manifest-path methods/guest/Cargo.toml \ |
|
2> >(grep -Ev "Falling back to slow ImageID|No such file or directory \(os error 2\)" >&2) |
cargo risczero build --manifest-path methods/guest/Cargo.toml
-
methods/ — a separate workspace member, whose build.rs uses the non-deterministic path instead:
|
"methods/build.rs", |
|
r#"fn main() { |
|
risc0_build::embed_methods(); |
|
} |
|
"#, |
|
); |
|
|
write_file(
root,
"methods/build.rs",
r#"fn main() {
risc0_build::embed_methods();
}
"#,
);
Why this is a problem
lssa explicitly documents why risc0_build::embed_methods() should not be used for real deployed programs — it produces a non-deterministic guest build (or requires Docker, which defeats the point):
https://github.com/logos-blockchain/lssa/blob/47eba256479f6f785acbd138834340703cd03401/lez/programs/README.md#L17-L22
Why not just risc0_build::embed_methods() ?
Because this will either provide non-deterministic guest build or requires Docker.
And forcing to use Docker to build the project is not an option for us especially because we also build Docker images for our services, which would mean we would have to call docker from docker (and this is not really feasible).
risc0_build::embed_methods() works well when you don't need deterministic build or Docker is not a problem. This is the case for our tests and we use it there.
The generated methods/ crate (with its embed_methods()-based build.rs) appears to be dead scaffolding left over from an earlier template design:
- It is a cargo workspace member (
members = [..., "methods", ...]), so cargo build --workspace compiles it and runs its build.rs on every build.
- Nothing else generated by
init_project depends on the {snake_name}-methods package or imports from it — no dependency edge from {snake_name}_ffi, examples, or the CLI crate.
- Its
methods/src/lib.rs just does include!(concat!(env!("OUT_DIR"), "/methods.rs")), but that generated file/binary is never referenced anywhere else in the project (the real binary path used by spel.toml, the Makefile, and wallet deploy-program is methods/guest/target/.../docker/{snake_name}.bin).
So today every spel init project ends up with an orphaned crate that (a) does nothing useful, (b) still calls the explicitly-discouraged embed_methods(), and (c) could confuse someone reading the generated project into thinking it's part of the real build/deploy path.
Suggestion
Remove the dead methods/ crate generation from init_project — i.e. the methods/Cargo.toml, methods/build.rs, and methods/src/lib.rs writes (spel-cli/src/init.rs around lines 654–692), the "methods/src" entry in the scaffolded directory list, and the "methods" entry in the workspace members list — keeping only the methods/guest/ layout that's actually built and deployed.
Summary
spel init(ininit_project,spel-cli/src/init.rs) generates two separate guest-related crates in every scaffolded project, only one of which is actually used:methods/guest/— excluded from the cargo workspace, containing the real#[lez_program]guest binary (methods/guest/src/bin/{snake_name}.rs). This is what the generatedMakefile'sbuildtarget actually compiles, correctly using the deterministic, Docker-pinned strategy:spel/spel-cli/src/init.rs
Lines 393 to 394 in 1ef0500
methods/— a separate workspace member, whosebuild.rsuses the non-deterministic path instead:spel/spel-cli/src/init.rs
Lines 677 to 683 in 1ef0500
Why this is a problem
lssaexplicitly documents whyrisc0_build::embed_methods()should not be used for real deployed programs — it produces a non-deterministic guest build (or requires Docker, which defeats the point):https://github.com/logos-blockchain/lssa/blob/47eba256479f6f785acbd138834340703cd03401/lez/programs/README.md#L17-L22
The generated
methods/crate (with itsembed_methods()-basedbuild.rs) appears to be dead scaffolding left over from an earlier template design:members = [..., "methods", ...]), socargo build --workspacecompiles it and runs itsbuild.rson every build.init_projectdepends on the{snake_name}-methodspackage or imports from it — no dependency edge from{snake_name}_ffi,examples, or the CLI crate.methods/src/lib.rsjust doesinclude!(concat!(env!("OUT_DIR"), "/methods.rs")), but that generated file/binary is never referenced anywhere else in the project (the real binary path used byspel.toml, theMakefile, andwallet deploy-programismethods/guest/target/.../docker/{snake_name}.bin).So today every
spel initproject ends up with an orphaned crate that (a) does nothing useful, (b) still calls the explicitly-discouragedembed_methods(), and (c) could confuse someone reading the generated project into thinking it's part of the real build/deploy path.Suggestion
Remove the dead
methods/crate generation frominit_project— i.e. themethods/Cargo.toml,methods/build.rs, andmethods/src/lib.rswrites (spel-cli/src/init.rsaround lines 654–692), the"methods/src"entry in the scaffolded directory list, and the"methods"entry in the workspacememberslist — keeping only themethods/guest/layout that's actually built and deployed.