feat(committed): committed-state migration — verifiable calc-state root into the currency snapshot#164
Merged
Merged
Conversation
Plan of record for adopting metakit committed-state (Approach B) as hashCalculatedState, salvaging #117's field-level proof endpoint on top. Records the key reframe: tessellation already roots calculatedStateProof into the signed currency snapshot + global proof, so a structured root needs no framework change. The prior roadblock was the journal=Option stall (seeded cell -> BreadcrumbUnresolvable), not the rooting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First slice of the committed-state migration: project the FULL calculated state (all 4 fields) into metakit's committed dictionary so the two-tier committed root commits to it, ready to become the currency snapshot's calculatedStateProof. Keys are lowercase slash-namespaced CommitKeys: fiber/<uuid>, script/<uuid>, registry/<name>, reverse/<uuid>. Key derivation is TOTAL (entries has no error channel; a non-total key would halt combine): UUIDs always fit a 64-char segment, and an over-long registry name (render up to 253) falls back to registry/h/<sha256>. CommittedViewSuite covers the registry readable/hashed-overflow keys, namespacing, totality, determinism, and empty genesis. Refs docs/proposals/committed-state-migration.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ML0Service now assembles the data application via CommittedApp.makeL0, so the snapshot's calculatedStateProof becomes the two-tier committed root (MPT state-dict + SMT epoch catalog) — a verifiable calculated-state root in the signed currency snapshot, no tessellation change required. - ML0Service: makeL0 with orderedCombiner (total-order sort + latestLogs reset before folding) and rejectionNotifyingValidator (per-update rejection webhooks); the new onConsensusResult hook refreshes the notification-side checkpoint cache + dispatches the snapshot webhook (replaces the hand-rolled onSnapshotConsensusResult); extraRoutes keeps the existing ML0Routes handlers. - Main: acquire a LevelDB CatalogJournal Resource (required — without it a seeded/restarted node stalls). - DL1: makeL0 commits CommittedOnChain[OnChain]; the validator's on-chain cache and the /onchain route decode the wrapper and read .inner, so the fiber sequence checks and the client-facing shape are unchanged. - Mock fixture serializes the same CommittedOnChain shape. Depends on metakit Constellation-Labs/metakit#48 (required journal + onConsensusResult + extraRoutes context). sharedData 358/358 green; full build compiles. e2e validation pending. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adopt #158's total signing order: OttochainMessage.signedOrdering now tiebreaks on the proof signatures, completing the partial message order to a TOTAL one (pure — no Hasher). The combiner drops the per-combiner content-digest tiebreak and just sorts by signedOrdering, so every node folds the identical sequence (greenfield — no coordination needed). Bump the metakit pin to 1.8.0-rc.3 (committed-state changes: required journal + onConsensusResult/extraRoutes hooks + genesis-combine fix). Until rc.3 lands on Central the metakit-from-source action builds the v1.8.0-rc.3 tag; the tessellation rc.10 jar fallback is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-homes #117's field-level state proof onto the real committed root. GET /v1/state-machines/:id/state-proof[?field=] and GET /v1/scripts/:id/state-proof[?field=] return a Merkle-Patricia inclusion proof for the fiber/script record (committed at fiber/<id> / script/<id>) against the MPT root whose combined hash IS the snapshot's calculatedStateProof. A client verifies the proof against the consensus-signed root, then reads any field off the proven record — #117's two-level field->fiberRoot->metagraphRoot collapses to one level, anchored to a real consensus root instead of an off-chain one. ?field= also surfaces the named stateData field of the proven record. StateProofHandler delegates to CommittedReader.committed.proveKey (no hand-rolled tries); wired via makeL0 extraRoutes (now passed the reader). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
metakit 1.8.0-rc.4 is published to Maven Central with all the committed-state changes (required journal, onConsensusResult / extraRoutes hooks, and the genesis-combine fix) — verified in the published jar. So the temporary metakit-from-source action is no longer needed: removed it and its callers (ci.yml x2, e2e.yml), and e2e.yml now resolves the tessellation-sdk version straight from the Central metakit POM again. The tessellation rc.10 hypergraph-jar fallback is untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3c15649 to
8f2fe6b
Compare
scasplte2
approved these changes
Jun 15, 2026
This was referenced Jun 15, 2026
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.
Draft / WIP. Unifies and supersedes #117 (hand-rolled state roots) and #158 (committed-state adapter) into one workstream. Plan of record:
docs/proposals/committed-state-migration.md.The reframe
Tessellation already roots
hashCalculatedStateinto the signed currency snapshot (DataApplicationPart.calculatedStateProof) and transitively into the global GL0 proof. So the groundwork is just making that hash a verifiable tree root — exactly what metakitCommittedApp.makeL0produces — with no tessellation change. (Promoting it to a typedOption[MerkleRoot]field onDataApplicationPartis an optional later phase.)What's here so far
CommittedView[CalculatedState]— projects all 4 fields (stateMachines/scripts/registry/reverseNames) into lowercase slash-namespaced CommitKeys. Registry keying is total (registry/<name>, with aregistry/h/<sha256>fallback for names that overflow a 64-char segment).CommittedViewSuitegreen.Depends on
metakit Constellation-Labs/metakit#48 (
fix(committed): require CatalogJournal) — the required-journal fix that removes the seed→BreadcrumbUnresolvablestall that parked #158. Held un-tagged for now; ottochain builds it from source until merged.Still to come (this PR)
makeL0into the post-feat(l0): fee/gas estimation (metakit rc.2) + split ML0 routes into handlers #163ML0Service(combine/validate/hash/routes owned by metakit;withConsensusHooksforonSnapshotConsensusResult; totalsignedOrdering; DL1 readers unwrapCommittedOnChain.inner).state-proofendpoint on the committed MPT.🤖 Generated with Claude Code