Skip to content

spel init scaffolds a dead methods/ crate that still uses discouraged embed_methods() #265

Description

@fryorcraken

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:

  1. 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:

    spel/spel-cli/src/init.rs

    Lines 393 to 394 in 1ef0500

    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
    
  2. methods/ — a separate workspace member, whose build.rs uses the non-deterministic path instead:

    spel/spel-cli/src/init.rs

    Lines 677 to 683 in 1ef0500

    "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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions