build(guest): remap the absolute paths out of the guest ELF, and pin its sha256 - #993
Open
MauroToscano wants to merge 2 commits into
Open
MauroToscano wants to merge 2 commits into
MauroToscano wants to merge 2 commits into
Conversation
…its sha256 A guest ELF is a program constant. Its Merkle roots, its genesis page set and its cycle count are read off it and pinned elsewhere, and a recursion guest is on its way to embedding one of those roots at compile time. All of that assumes the ELF is a function of the sources. It was not. Nothing remapped paths, so the build baked in the absolute paths of the machine that produced it — the workspace directory, the cargo registry checkout, the rustup toolchain that supplies the build-std sources, the sysroot. Measured before this change: 147 `/Users/…` strings in `ethrex.elf`, including the toolchain root, which carries the HOST TRIPLE. Two checkouts of one commit produced different bytes; two machines differed by kilobytes. Three builds of "the same" post-#894 sources came out at 3,948,520 / 3,948,504 / 3,952,608 bytes with three different digests, and nothing in the tree could say which was right or that anything was wrong. The failure mode is the quiet one. A constant derived in one worktree is not a claim about another's guest, and a toolchain bump moves every such constant with no source change, no code change and no test that fails until a verifier rejects a valid proof. `scripts/guest_rustflags.py` appends `--remap-path-prefix` for the four real prefixes, longest-first so the most specific wins. It reads each guest's OWN flags out of its `.cargo/config.toml` rather than this repo carrying one list: `CARGO_ENCODED_RUSTFLAGS` REPLACES the config's rustflags rather than extending them, and the guests' flag sets are not uniform — four different combinations of `link-arg=-e main`, `getrandom_backend` and `passes=lower-atomic` across 45 crates — so a blanket value would silently drop flags that decide whether a guest links or randomises correctly. The config stays the single source of truth. `make check-ethrex-guest-elf` is the assertion that makes it stick, and `assert_sha256` is deliberately not `ensure_verified`: there is nowhere to refetch a built artifact from, so the only useful behaviours are pass and a loud, specific failure naming both digests. Measured after: `ethrex.elf` is 3,948,944 bytes, sha256 `3d34a312…`, with ZERO `/Users/maurofab` strings. ⚠ This moves the ELF for everyone, so every ELF-derived constant needs re-deriving with it. Not merged on any campaign branch; the timing is Mauro's.
Two differently named checkouts of this commit still produce different ELFs — 3,948,944 against 3,950,136 bytes — with zero embedded paths in either. The residue is cargo's `-C metadata` disambiguator, derived from a package's absolute source path and passed to rustc before any remapping can apply. The boundary is exact, measured across the two builds: the guest crate and `lambda-vm-ethrex-crypto`, both PATH packages, get different disambiguators; `ethrex-trie` (git) and `core` (build-std) are identical. Closing it needs a canonical build path, which is a bigger decision than a flag. So the sha256 pin is provisional: a property of this commit built in a directory of a particular name, not of the commit. Said at the constant, so nobody wires it into `test` or `lint` and gets a failure that looks like drift. What the change does fix is the half that crosses machines: the home directory, the registry location, the sysroot and the rustup toolchain path — the last of which carries the host triple — no longer appear. That was the 4 KB between a Linux box and a macOS laptop building the same sources.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two commits on
chore/guest-elf-remap:build(guest):scripts/guest_rustflags.pyappends--remap-path-prefixfor the four real prefixes (workspace, cargo registry, rustup toolchain, sysroot), longest-first, reading each guest's own flags out of its.cargo/config.tomlbecauseCARGO_ENCODED_RUSTFLAGSreplaces the config's rustflags rather than extending them and the 45 guests carry four different flag sets.make check-ethrex-guest-elfasserts the built ethrex guest's sha256 and prints both digests on a miss.docs(guest): records, measured, what the remapping does not fix.Why
A guest ELF is a program constant: its Merkle roots, genesis page set and cycle count are read off it and pinned elsewhere. Before this change the build baked in the absolute paths of the machine that produced it (147
/Users/…strings inethrex.elf, including the rustup toolchain root, which carries the host triple), so two checkouts of one commit produced different bytes and two machines differed by kilobytes, with nothing in the tree able to say which was right.What it fixes and what it does not
Fixed: every path rustc controls. A build now has zero host paths in the ELF, so the home directory, the registry location, the sysroot and the toolchain path no longer leak in; that was the difference between a Linux box and a macOS laptop building the same sources.
Not fixed, and measured: two differently named checkouts of one commit still give two ELFs (3,948,944 vs 3,950,136 bytes). The residue is cargo's
-C metadatadisambiguator for path dependencies (the guest crate andlambda-vm-ethrex-crypto), derived from the absolute source path before any flag reaches rustc; git and registry dependencies and build-std are identical across the two builds. Closing it needs a canonical build path (a container or a fixed mount), which is a separate decision.The sha256 pin is therefore provisional, a property of this commit built in a directory of a particular name. It is wired into nothing that
make testormake lintruns, so it cannot produce a failure that looks like drift.Checks
Both commits are signed.
make lintandmake fmtare unaffected (no Rust source changes). The Makefile targets are opt-in.