feat(compiler): M7 5+-param HashMap-order port — @contract full byte parity - #175
Conversation
📝 WalkthroughWalkthroughContract templates with more than 4 parameters are no longer rejected during compilation. A new ChangesParameter iteration-order parity
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant compile_contract
participant param_order
Caller->>compile_contract: compile_contract(template)
compile_contract->>compile_contract: check params.len()
alt params.len() <= 4
compile_contract->>compile_contract: enumerate() for placeholder indices
else params.len() >= 5
compile_contract->>param_order: iteration_order_2_12(names)
param_order-->>compile_contract: permutation of indices
end
compile_contract-->>Caller: compiled contract with ConstantPlaceholder indices
Related PRs: None identified. Suggested labels: compiler, correctness, tests Suggested reviewers: None identified. Poem: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
|
@coderabbitai review |
✅ Action performedReview finished.
|
efab482 to
3d5f5af
Compare
422dd24 to
e79d82d
Compare
3d5f5af to
82727a4
Compare
Ports the exact ordering Scala's immutable HashMap (`HashTrieMap`) yields for a set of `@contract` param names, the source of `ConstantPlaceholder` indices for ≥5-param templates: JVM `String.hashCode` + `scala.collection.Hashing.improve` + the 5-bit-sliced trie walk (ascending buckets, sub-tries in place). Pinned to Scala 2.12 to match the `ct` oracle and ergo-appkit; the 2.13 CHAMP order is kept (test-only) as the documented alternative. Both reproduce the recon's bit-validated p5/p8 vectors exactly. Not yet wired into assembly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BUh2DBnAPqThdYFZW5D8wx
…lates Replaces the ≥5-param `TooManyParamsForOrdering` reject with real placeholder- index assignment via the Scala 2.12 `HashTrieMap` iteration order (param_order::iteration_order_2_12); ≤4-param path (declaration order) untouched. `constTypes`/`constValues`/`parameters` stay declaration-ordered — only the body's `ConstantPlaceholder` substitution follows the map order. Error variant removed. Adds oracle-captured 5/6/8-param vectors (five/six/eight_hashorder) whose name sets order differently under HashTrieMap than declaration AND alphabetical, plus the pre-existing five_params — all four ≥5-param templates now compile BYTE-IDENTICAL to the `ct` oracle (sigma-state 6.0.2, Scala 2.12.21, JVM 17). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BUh2DBnAPqThdYFZW5D8wx
82727a4 to
2fa0c8d
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
ergo-compiler/src/lib.rs (1)
1241-1241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winKeep
param_ordercrate-private unless it is a supported API.This exposes the Scala hash-order port as public crate surface. If only
compile_contractneeds it, prefer crate visibility to avoid downstream semver coupling.Proposed change
-pub mod param_order; +pub(crate) mod param_order;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ergo-compiler/src/lib.rs` at line 1241, The `param_order` module is being exposed as public API even though it appears to be an internal implementation detail. Change the visibility on `param_order` in `lib.rs` to crate-private unless `compile_contract` or another supported public API truly needs it, and keep any internal references working through the crate-visible module rather than exporting it to downstream users.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@ergo-compiler/src/lib.rs`:
- Line 1241: The `param_order` module is being exposed as public API even though
it appears to be an internal implementation detail. Change the visibility on
`param_order` in `lib.rs` to crate-private unless `compile_contract` or another
supported public API truly needs it, and keep any internal references working
through the crate-visible module rather than exporting it to downstream users.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6ee34aa0-1c0c-440b-b4a6-786261c44dbe
⛔ Files ignored due to path filters (4)
test-vectors/ergoscript/contract/contract_seed.jsonis excluded by!test-vectors/**test-vectors/ergoscript/contract/sources/eight_hashorder.esis excluded by!test-vectors/**test-vectors/ergoscript/contract/sources/five_hashorder.esis excluded by!test-vectors/**test-vectors/ergoscript/contract/sources/six_hashorder.esis excluded by!test-vectors/**
📒 Files selected for processing (4)
ergo-compiler/src/contract_template.rsergo-compiler/src/lib.rsergo-compiler/src/param_order.rsergo-compiler/tests/contract_template_parity.rs
Bump workspace version to 0.5.2 and promote the changelog: the complete v1 product API (#168-#185, #188), shadow validation as a production mode (#193-#195), the operator observability wave (#187, #190, #192, #194), two live accept-invalid consensus fixes (#176, #179), ErgoScript compiler byte-parity completion (#165-#167, #175), and the #160-#163 sync/recovery fixes. Full workspace gate run on the merge result. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BUh2DBnAPqThdYFZW5D8wx
What this is
Closes M7's one deferral:
@contracttemplates with ≥5 named parameters now compile byte-identically to Scala instead of returningTooManyParamsForOrdering. This was deferred because Scala assigns each param's bodyConstantPlaceholderindex by JVM HashMap iteration order (not declaration order) once the param map exceeds 4 entries and upgrades fromMap1..Map4to a hashHashTrieMap.The port (
ergo-compiler/src/param_order.rs)iteration_order_2_12: JVMString.hashCode(i32-wrapping31*h+cover UTF-16) → Scala'sHashing.improvebit-mix → the 2.12HashTrieMap5-bit-slice trie walk (ascending buckets, sub-tries recursed in place, collisions bottoming out to insertion order). Reproduces the recon's bit-validated p5/p8 vectors exactly.Scala version pinned: 2.12 (2.12.21) — confirmed empirically by running the
ctoracle through scala-cli (it printedCompiling project (Scala 2.12.21, JVM 17)), matching the oracle's//> using scala 2.12pragma and ergo-appkit. The 2.13 CHAMP order is kept test-only as the documented alternative.Correctness discipline
five_params+ three new discriminating captures (five_hashorder,six_hashorder,eight_hashorder) whose HashTrieMap order differs from BOTH declaration and alphabetical (the 8-param one includes two real root-bucket hash collisions). All captured fresh from thectverb (sigma-state 6.0.2 / Scala 2.12.21) — never self-oracled.constTypes/constValues/parameters/constantIndexstay declaration-ordered for ALL arities; ONLY the body'sConstantPlaceholdersubstitution follows the map order.TooManyParamsForOrderinggone; grep-confirmed no stale refs).Test plan
7 new
param_orderunit tests (hashCode known-vectors, improve, the p5/p8 worked orders, collision→insertion-order) + the byte-exactcontract_template_paritygate over the new ≥5-param vectors.🤖 Generated with Claude Code
https://claude.ai/code/session_01BUh2DBnAPqThdYFZW5D8wx
Summary by CodeRabbit
New Features
Bug Fixes
Tests