Skip to content

⚠ BREAKING: move ledger-v9 to Compact 0.34 and typed mint recipients - #67

Merged
acedward merged 1 commit into
ledger-v9from
00028-kernel-compact-034-toolchain
Sep 4, 2026
Merged

⚠ BREAKING: move ledger-v9 to Compact 0.34 and typed mint recipients#67
acedward merged 1 commit into
ledger-v9from
00028-kernel-compact-034-toolchain

Conversation

@acedward

@acedward acedward commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

⚠ BREAKING compatibility boundary

This PR targets ledger-v9, never main.

Dependency-order warning: DRAFT PR #65 remains DRAFT / DO NOT MERGE until ledger v9 is the standard. This PR does not edit, merge, or change #65.

Two breaking boundaries ship together:

  1. Compact-generated code now requires @midnight-ntwrk/compact-runtime exactly 0.19.0. Loading it under 0.18.0-rc.1 fails with Version mismatch.
  2. mint_shielded and mint_unshielded change in place to accept explicit typed recipients and reject zero amounts. Their ZKIR/verifier keys move, so callers and deployments must migrate together.

Toolchain

Component Version
compactc 0.34.0
Compact language 0.26.0
compact-runtime 0.19.0

infra/compact-version.txt is the single compiler-version authority. Both download routes authenticate the selected archive before unzip:

Linux asset SHA-256
compactc_v0.34.0_aarch64-unknown-linux-musl.zip d3e292c4f48e257dcd6b3d3e3e4743d7d8ea0729f48953eab91a366d44cd026d
compactc_v0.34.0_x86_64-unknown-linux-musl.zip 775ccddf5a71399835329bbf7471ba5a8c54fcc825d372c75e19ba7042069584

The root/workspace pins and root override collapse the lockfile to one @midnight-ntwrk/compact-runtime@0.19.0 locator. CI now performs a real full Compact build/key generation and exact artifact inventory check; a separate exact-source linux/amd64 kernel-image job builds and inspects the image.

Generated src/managed/ remains gitignored and uncommitted. Local builds, CI, and the kernel image regenerate it.

Recipient semantics

  • mint_shielded(domainSep, amount, nonce, Either<ZswapCoinPublicKey, ContractAddress>)
  • mint_unshielded(domainSep, amount, Either<ContractAddress, UserAddress>)
  • Shielded user calls pass left(ownCoinPublicKey) explicitly; unshielded user calls pass the decoded ledger user address.
  • Both Either arms are present as 32-byte structures; the inactive arm is a valid fresh zero value.
  • Both circuits reject amount == 0 with mint amount must be positive.
  • A contract-owned shielded output must be claimed by the recipient contract's receive circuit in the same transaction segment. Without that receive, pinned ledger-v9 1.0.0-rc.3's WASM carries exact semantic a contract-owned coin output was left unclaimed, and live submission rejects with exact public surface 1010: Invalid Transaction: Custom error: 218. The coin is not stranded.

Every direct and indirect kernel caller was migrated. The exhaustive AST gate covers 45 relevant call expressions with no stale arity/shape: seven direct shielded, five direct unshielded, 24 shielded helpers, and nine unshielded helpers. The narrower production inventory is nine generated-circuit calls across five source files.

Final ZKIR/key comparison

The base Compact source at 4af1025 has SHA-256 6fde5f8e2cfc5d5559f1468f3997f72810aec3093c6a87a54036b9175dadd3f0; the final recipient-typed source has SHA-256 3cf4cb51a5bc6ad9ac02adf828254caeee68c5b861d31d7319106289ee0d2546.

The 0.33 baseline and final 0.34 output were each generated twice and were internally byte-identical. An intermediate compile of the unchanged source under 0.34 was all SAME, isolating the shipping drift to the recipient-source change.

Relative artifact 0.33 bytes 0.33 SHA-256 Final 0.34 bytes Final 0.34 SHA-256 Result
keys/incrementNoun.prover 76,645 cc812f6b7cd2e10734fc7093ba5d59ba0a3c79f74a01ceffae1aeae024b2d36d 76,645 cc812f6b7cd2e10734fc7093ba5d59ba0a3c79f74a01ceffae1aeae024b2d36d SAME
keys/incrementNoun.verifier 1,351 76d622c599cbf1cc68fd9f698a41f71d3be45ec2fc18c28c01269c6105306e62 1,351 76d622c599cbf1cc68fd9f698a41f71d3be45ec2fc18c28c01269c6105306e62 SAME
keys/mint_shielded.prover 5,214,494 5e9d656c1c39a68992ee170a39296b82a9ffbc6dae731c59b7433dd7e68a070a 5,215,614 27f5fee2454c64ed76f8ca77fe4b773fc68e3509542880f8f4caae5bf62bc5a2 CHANGE
keys/mint_shielded.verifier 2,119 88669abef686f746a8f1e37224e326898388008ab4cfa54aa0a9e57042596537 2,119 568987e35fc11d205d8c8c08858a85833e535f13b6b0c77b3a95f5c1f9eb4839 CHANGE
keys/mint_unshielded.prover 2,820,616 7d6301b0a6147238a434984983af6476bc0f1362ec68274d440901333735686b 2,821,420 f556576d54a7bc17b48be78c6daa8e7a6a60eb1df9bcab69f97c7e5fb076e2f1 CHANGE
keys/mint_unshielded.verifier 2,119 a1f7a4aea726d5b59a143b0ffb92d1bb65198b9046fdfae00a547ddd910d3be8 2,119 04f25d78fc43f59e2ccf0cf95df8176b9c6b53be96d588808457e433037582e8 CHANGE
zkir/incrementNoun.bzkir 117 33465f34039cfaf9a81229bd202182254f653e42faa9e5ad1915af2ed9fa0e68 117 33465f34039cfaf9a81229bd202182254f653e42faa9e5ad1915af2ed9fa0e68 SAME
zkir/mint_shielded.bzkir 470 2778d50b9221d19eb06834ba6fffa17f3a43a02a0c4c6396de7ae878ad25a0c7 670 574f94bc0574e726a54dc9ae1dff5372d0f73d872fac05d396f3a6b996f569d1 CHANGE
zkir/mint_unshielded.bzkir 471 0edbeaecb343c9e5395a843c9efa1873918e476625f74c0b021ce5ef95250ef5 826 26ade2bd308a3b728432d01f1877e6f383667794c224bc3ff6419a9d4298d12e CHANGE

Verdict: both mint verifier keys moved; every ledger-v9 OfferFiles contract instance must redeploy. incrementNoun remains unchanged.

Downstream checklist (FR-012; follow-up work, not changed here)

  • midnight-2-offers/images/offerfiles-kernel: repin this kernel commit and regenerate the OfferFiles manifest/key material.
  • midnight-2-offers/images/aa-contracts: repin AA and runner/package.json to compact-runtime 0.19.0; update runner/aa-console.ts so its OfferFiles faucet call adds left(ownCoinPublicKey).
  • midnight-2-offers/images/zswap-da/ledger-v9.patch: update the runtime pin and patched browserContract.ts faucet call; regenerate src/contract/manifest.json and patched key hashes. Upstream effectstream/templates/zswap-da is still ledger-v8/kernel main, so the change stays in this v9 patch until that template migrates.
  • Check images/offerfiles-kernel/entrypoint-register-tokens.sh (artifact names only) and compose/offerfiles.yml (comment only); neither currently contains a mint call.
  • Re-run AA project 00029 T-M1's one-transaction mint-into-Manager measurement with contract mint + receive composed together.
  • Kernel main and midnight-1-offers remain ledger-v8/1.x and unchanged; they keep the old API and require no redeploy from this branch.

Verification receipts

  • Pinned source: d8d4ec8a747999bf7a0d30a36489dd398ffd4db5, one non-merge commit over exact origin/ledger-v9 4af102536f02f137b696a4734bd8c936eddf3672; 544670d ancestry preserved.
  • Determinism/artifacts: two identical final 17-file generations; exact compiler/language/runtime, contract/index.js guard, three named .bzkir, and six named keys passed.
  • Runtime/focused tests: runtime invariant passed; independent audit focused suite 55 passed / 0 failed / 642 assertions.
  • Type/docs: root typecheck reported zero diagnostics across 30 backend, 115 solver/consumer, and 11 price-feed roots; docs tsc -b and Vite production build passed against real generated declarations (6,053 modules).
  • Unit selection in pinned oven/bun:1.3.11: 1,594 passed / 1 environment-only failure / 17,124 assertions / 113 files. The only failure is the physical-image secret scanner's beforeAll because the Bun-only container has no Docker CLI. Successful PR ledger-v9 #65 Bun 1.3.3 baseline is 1,593/0; this candidate adds eight focused tests, so remote expectation is 1,601/0. Remote CI is the final proof.
  • Final live e2e: 62 passed / 0 failed, including both requested mint colours/deltas, pinned rc.3 WASM semantic + exact live code 218, both zero-amount rejections, lifecycle/API/Celestia/batcher/multi-token/unshielded flows, and terminal ROOT_UNKNOWN/non-ingestion.
  • Local arm64 kernel image: sha256:004e4e787d6e2f93f0003b8a0f5bd2d7a4315287048a6705998a98674f83689d, arm64/linux. In-image source/runtime/metadata/inventory and all nine hashes passed.
  • Independent audit: PASS WITH FINDINGS, zero blockers. Its sole NIT was an organizer receipt count typo (eight vs nine production direct calls), resolved in P4.3 without changing source or test inputs.

Disclosed limitations

  • check:pgtypes twice hung without output on this host; pgtyped inputs are unchanged. No pass is claimed.
  • Docker Desktop could not resolve the exact Dockerfile frontend metadata or uncached amd64 base locally. The arm64 build used a candidate-only copy differing solely by removal of the syntax directive; all instructions/source and in-image gates were identical. The committed exact-source amd64 CI job is the required remote proof and is not claimed green yet.
  • Deployment Compose config renders successfully, but the startup smoke is FAILED / not a partial success because of two unchanged, unrelated base-line blockers: indexer 4.4.0-rc.3 requires cache_max_nodes, then the kernel waits indefinitely for healthy pglite. They are recorded as organizer issues 00030 and 00031 and intentionally remain outside this Compact PR.
  • All project Docker containers/networks/volumes/tags, generated output, caches, temporary test copies, local environment files, and fixed-port listeners were torn down. Three explicitly unrelated pre-existing effectstream-00028-midnight-tip-query:* image tags were preserved.

Audit and rollout

Independent audit result: PASS WITH FINDINGS, zero blockers. The sole NIT is resolved. Remote checks, including exact-source amd64 and exact Bun unit proof, are monitored in P4.5; this PR must not be merged until required checks are green and the owner is ready for the ledger-v9 rollout.

Again: DRAFT PR #65 remains DRAFT / DO NOT MERGE. This PR does not change it.

@acedward
acedward merged commit 358aaca into ledger-v9 Sep 4, 2026
7 checks passed
acedward added a commit that referenced this pull request Sep 4, 2026
… registration

Carries the 00029 fixes onto the ledger-v9 line: blank/whitespace optional env
now selects the package default (price-feed and batcher config), the mint
script registers TESTTOKENA/B/U through POST /v1/known-tokens, and Compose plus
both launchers use the linear contract -> healthy kernel -> mint/register ->
compatibility -> wallet consumers startup.

No textual conflicts. Eight files were touched on both sides and auto-merged;
each was inspected line by line:

  packages/contracts-midnight/mint-test-tokens.ts -- v9's typed mint recipients
    (shieldedUserRecipient / unshieldedUserRecipient, PR #67) are preserved and
    the inline /api/known-tokens loop is replaced by main's
    registerMintedTokenNames seam. The two edits sit in disjoint regions.
  start.dev.ts -- v9's infra/compact.sh version probe (PR #67) and main's
    sync-api-health waiter, ENABLE_TOKEN_REGISTRY and mint ordering coexist.
  deploy/compose.yml -- v9's api/v4 indexer endpoints, the PORT-only proof
    server with its healthcheck disabled and the service_started conditions are
    untouched; the mint-test-tokens one-shot and its
    service_completed_successfully edges are added on top.
  deploy/images/kernel/Dockerfile -- comment updates plus the new
    entrypoint-mint-test-tokens.sh COPY; v9's checksum-pinned compactc build
    stage is unchanged.
  README.md, deploy/README.md, deploy/.env.example and
  deploy/scripts/provision-solver-fees.ts -- documentation only.

No dependency pin moves: bun.lock is untouched by this merge and still resolves
@midnightntwrk/ledger-v9 1.0.0-rc.3 and @midnight-ntwrk/compact-runtime 0.19.0
exactly once each, with zero ledger-v8 entries. compactc stays at 0.34.0.
@acedward acedward mentioned this pull request Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant