feat(compiler): add codegen identity for config- and feature-dependent bytecode - #177
feat(compiler): add codegen identity for config- and feature-dependent bytecode#177dmitry123 wants to merge 1 commit into
Conversation
|
Warning Review limit reached
Next review available in: 55 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Criterion results (vs baseline)Heads-up: runner perf is noisy; treat deltas as a smoke check. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Closes FLU-1107.
Problem
The same wasm input compiles to different rwasm bytecode depending on how the compiling binary was built, and the serialized module records none of it:
impl_fpu_opcode!(src/isa/mod.rs) substitutesTrap(IllegalOpcode)for every float instruction at compile time when thefpufeature is off, so anfpubuild and a default build emit different modules (and different hashes) for one contract.CompilationConfigflags —code_snippets, the fuel flags,max_allowed_memory_pages, the router/linker — decide which functions are emitted and where fuel charges land, shifting every downstream instruction offset.0xEF 0x52 0x01) versions the wire format, not the compiler configuration, so nothing identifies the build that produced the bytes.Changes
CompilationConfig::codegen_identity()(src/compiler/codegen_identity.rs) — a keccak-256 fingerprint over every input that affects emitted bytecode: the codegen-relevant config fields plus the compile-time feature set of the compiling binary. Compilers agreeing on the value compile any given wasm input to identical bytes; disagreeing ones may not. Hosts that address modules by hash can pin this next to the bytecode and reject foreign modules with a clean error instead of executing them under different semantics.Preimage details: every variable-length element is length-prefixed so distinct configs cannot collide; import-linker entries are hashed in sorted name order because the linker is backed by a hash map with unstable iteration order; state-router entries are hashed in declaration order because that order is part of the emitted routing code.
CODEGEN_FEATURE_FPU/codegen_feature_set()expose the feature bitmask; features that only change the host-side surface (std,serde,wasmtime, …) are deliberately excluded since they do not affect the bytes.fpudocumentation (per the Linear comment) — floating point is not officially supported; the feature exists only for the e2e suite and the fuzzer. Documented atimpl_fpu_opcode!, at the executor's dispatch split (src/vm/executor.rs), and in theCargo.tomlfeature list, each noting that the feature changes emitted bytecode rather than just runtime behaviour.docs/module-format.md— new "Codegen determinism" section listing every input that affects emitted bytecode and explaining that the header version identifies the format, not the configuration.Not included
Embedding the identity in the module header and checking it in
verify_module(suggestion 1 of the issue) would require aRWASM_VERSION_V2bump and would change the bytes — and therefore the hash — of every module ever compiled. That is a consensus-level decision, so this PR delivers the identity as a host-checkable value and leaves the format untouched. Worth a follow-up decision.Also note the runtime never sees a
CompilationConfig(RwasmInstance::newtakes only store/engine/module), so a load-time check has to be driven by the host comparing identities either way.Testing
cargo test --lib(80 passed) andcargo test --lib --features fpu;cargo clippy --all-targets --all-featuresclean;cargo check --no-default-featuresclean.New tests cover: stability across equal configs; a changed identity for each codegen-relevant flag; independence from import-linker insertion order; sensitivity to state-router ordering; and a pinned digest of the default config per feature set, which both locks the preimage layout against silent drift and demonstrates that an
fpubuild and a default build carry different identities.