feat(committed): committed-state adoption enablers (required journal + L0 hooks)#48
Merged
scasplte2 merged 3 commits intoJun 15, 2026
Conversation
CommittedApp.makeL0 / CommittedState.make took journal: Option[CatalogJournal[F]] = None. The journal is load-bearing: a node that seeds (restart or download-to-join) with no journal lands in a SeededCatalog and the next combine raises BreadcrumbUnresolvable, so the metagraph stalls. Make journal a required CatalogJournal[F] (reordered before the defaulted params) with inMemory/levelDb as the explicit opt-outs, and drop the now-dead Option plumbing (flatTraverse/traverse_). This was the roadblock that parked the ottochain committed-state adapter. Also document that breadcrumb resolution is by ROOTS, not the claimed ordinal (the catalog root commits the full ordinal history); honest callers always pass a consensus-signed, ordinal-bound breadcrumb. Test updated to assert unresolvability with roots the chain never produced. Full suite green: 1111/1111. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
makeL0 produces an erased BaseDataApplicationL0Service, so a metagraph that needs onSnapshotConsensusResult (e.g. webhook dispatch + a notification-side calculated-state cache) previously had to wrap it in a ~20-method delegating service. Add an optional onConsensusResult hook — (CommittedReader, Hashed[CurrencyIncrementalSnapshot]) => F[Unit] — that the service forwards from onSnapshotConsensusResult, handing the dev the committed reader for current-state reads. Kills the wrapper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The extra-routes callback previously received only the CommittedReader, so a metagraph whose extra routes read node-context state (e.g. the on-chain snapshot via getOnChainState) could not be wired through it. Pass the L0NodeContext alongside the reader. Default extraRoutes (None) is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ottobot-ai
added a commit
to scasplte2/ottochain
that referenced
this pull request
Jun 15, 2026
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>
This was referenced Jun 15, 2026
ottobot-ai
added a commit
to scasplte2/ottochain
that referenced
this pull request
Jun 15, 2026
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>
scasplte2
pushed a commit
to scasplte2/ottochain
that referenced
this pull request
Jun 15, 2026
…ot into the currency snapshot (#164) * docs: committed-state migration plan (unify #117/#158) 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> * feat(committed): add CommittedView[CalculatedState] projection (Phase 1) 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> * feat(committed): wire makeL0 into ML0Service (Phase 1) 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> * feat(committed): total signedOrdering + bump metakit rc.3 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> * feat(committed): state-proof endpoint on the committed MPT (Phase 2) 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> * chore(deps): bump metakit to rc.4; drop source-build patch 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> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Three small, related changes that make the
committedlifecycle module actually adoptable by a downstream metagraph L0 (ottochain). All scoped tolifecycle/committed; full suite green (1111/1111).1. Require the catalog journal (the load-bearing fix)
CommittedApp.makeL0/CommittedState.maketookjournal: Option[CatalogJournal[F]] = None. The journal is load-bearing: a node that seeds (restart or download-to-join) with no journal lands in aSeededCatalog, and the nextcombineraisesBreadcrumbUnresolvable→ the metagraph stalls. Now a requiredCatalogJournal[F], withinMemory/levelDbthe explicit opt-outs. Also documents that breadcrumb resolution is by roots, not the claimed ordinal (the catalog root commits the full ordinal history).2.
onConsensusResulthook onmakeL0makeL0returns an erasedBaseDataApplicationL0Service, so a metagraph needingonSnapshotConsensusResult(webhook dispatch, a notification-side state cache) otherwise had to wrap it in a ~20-method delegating service. Added an optionalonConsensusResult: (CommittedReader, Hashed[CurrencyIncrementalSnapshot]) => F[Unit]the service forwards, handing the dev the committed reader for current-state reads.3. Pass
L0NodeContexttoextraRoutesThe extra-routes callback received only the
CommittedReader; pass theL0NodeContextalongside so extra routes can read node-context state (e.g. the on-chain snapshot). DefaultextraRoutes(None) unaffected.Downstream consumer: ottochain committed-state migration (scasplte2/ottochain#164).
🤖 Generated with Claude Code