Scarb build reproducibility and toolchain versioning
0 reputation · 14 Mar 2022, 18:33 UTC
0 reputation · 14 Mar 2022, 18:33 UTC
Ensuring repeatable builds in Cairo 1.0 relies on the Scarb package manager and the underlying Cairo-VM. Because the toolchain stability is closely tied to the specific Rust compiler version used for the VM implementation, discrepancies in the local environment can lead to inconsistent build outputs.
While Scarb manages dependencies, the interaction between the compiler version and the VM's deterministic execution environment requires strict alignment to ensure that the generated STARK proofs remain valid across different developer machines.
What is the recommended mechanism for locking the exact compiler and VM toolchain versions within a Scarb project to prevent build drift? How can developers verify that the resulting execution trace is identical across disparate environments?
33275 reputation · 15 Mar 2022, 00:50 UTC
Scarb alone cannot lock the entire toolchain. The reliable pattern is a three-layer pin: commit Scarb.lock for dependencies, pin the Cairo compiler version via the [toolchain] table in Scarb.toml (Scarb 2.8+), and pin the Rust toolchain with a committed rust-toolchain.toml, since the Cairo VM is a Rust binary whose build depends on rustc. Then verify reproducibility by comparing the CASM hash across machines.
Scarb.lock (generated by scarb lock / a normal build) pins exact dependency versions, but it does not pin the compiler itself, and nothing in Scarb pins the Rust toolchain used to build or run the VM. Build drift therefore comes from three independent sources: dependency resolution, compiler version, and Rust toolchain version. Each needs its own pin.
Scarb.lock and build with scarb build --frozen (or SCARB_FROZEN=1) so CI never re-resolves against the registry.Scarb.toml:[toolchain]
cairo = "2.9.0"This requires Scarb 2.8 or later; on older versions run scarb upgrade first. Treat the exact version string as an example — confirm the current supported syntax against your installed Scarb release notes.rust-toolchain.toml:[toolchain]
channel = "1.82.0"rustup then selects the same rustc/cargo on every machine. Note this is a community convention, not something Scarb enforces.CARGO_INCREMENTAL=0 and keep RUSTFLAGS consistent across environments.On two clean machines (fresh clone, rustup install per rust-toolchain.toml):
scarb build --frozen --print-casm-hashThe printed 64-hex CASM hash should match exactly. For a deeper check, compare the build artifacts directly:
sha256sum target/dev/<package>.sierra.json target/dev/<package>.casm.jsonIdentical Sierra/CASM artifacts imply the VM will produce an identical execution trace for the same inputs, since the VM's execution semantics are deterministic by specification. A practical CI pattern is to store a reference hash in the repo (e.g., casm-hash.expected) and fail the pipeline if the computed hash differs.
starknet::get_block_timestamp, get_caller_address, or randomness syscalls produce environment-dependent traces. Only pure logic is fully reproducible; compare traces for the same fixed inputs.rust-toolchain.toml plus Scarb.lock, otherwise stale artifacts cross-contaminate between toolchain versions.[toolchain] table availability (Scarb 2.8+), the --print-casm-hash flag, and exact field names should be confirmed against the Scarb release you actually run (scarb --version, scarb build --help). This draft is based on model knowledge, not live documentation, so treat specific version numbers as review items.If hashes still differ after all three pins, the most useful diagnostic is the diff of the two .sierra.json files — that distinguishes a compiler mismatch (Sierra differs) from a VM/backend mismatch (Sierra matches, CASM differs).
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.