Outcome
A replaceable C++20 persistence adapter durably commits every successful kernel block and reopens to the identical validated state and state root after clean shutdown, process interruption, or recoverable transaction failure. Versioned snapshots and an admitted-transaction journal support deterministic replay and recovery.
Acceptance evidence
- Record a storage ADR comparing SQLite, LMDB, RocksDB, and a custom journal. Pin the selected source version, SHA-256, license, durability settings, update path, and removal path before implementation.
- Define the versioned storage schema, snapshot/export contract, startup validation, commit ordering, corruption behavior, and migration-refusal rules. Storage bytes are operational compatibility data, not consensus state.
- Persist canonical genesis bytes, immutable chain parameters, current height and state root, materialized accounts and fee pool, ordered admitted 200-byte transactions, exact kernel receipt bytes, application headers, and block IDs.
- Keep admission failures out of the canonical journal. Retaining admitted transaction bytes must preserve all consensus-visible replay behavior.
- Apply blocks to an independent ledger fork, commit all persistent changes in one durable database transaction, then publish the fork with a non-throwing ownership transfer.
- On storage failure before commit, preserve both live and durable pre-block state. On an ambiguous or post-commit failure, fail closed and reopen before processing another height.
- On startup, reject unknown schemas, wrong genesis or chain ID, non-contiguous heights, duplicate ordinals, invalid state invariants, root/header/receipt mismatches, and corrupt snapshots or journal entries.
- Restore the latest verified snapshot and deterministically replay subsequent journal entries, comparing every kernel-produced root, receipt, header, and block ID.
- Test creation/reopen, empty and all-unadmitted blocks, execution failures, long seeded sequences, repeated restart, snapshot export/import, replay from genesis, single-writer locking, semantic corruption, truncated history, and injected failures around every commit phase.
- Run the frozen ledger vectors through commit/reopen/replay and pass all four
tools/verify.sh presets, including ASan/UBSan.
- Document the public persistence boundary and update
docs/project/current-state.md with exact evidence.
Scope
Persistent local ledger state only. Exclude ABCI, CometBFT, networking, RPC, multi-validator operation, pruning/state sync, production backup policy, and protocol-state changes.
Dependencies and gates
PR #10 / issue #8 must be merged first. Any discovered kernel-visible semantic change invokes the protocol-change gate before implementation. The CometBFT adapter depends on this issue.
Outcome
A replaceable C++20 persistence adapter durably commits every successful kernel block and reopens to the identical validated state and state root after clean shutdown, process interruption, or recoverable transaction failure. Versioned snapshots and an admitted-transaction journal support deterministic replay and recovery.
Acceptance evidence
tools/verify.shpresets, including ASan/UBSan.docs/project/current-state.mdwith exact evidence.Scope
Persistent local ledger state only. Exclude ABCI, CometBFT, networking, RPC, multi-validator operation, pruning/state sync, production backup policy, and protocol-state changes.
Dependencies and gates
PR #10 / issue #8 must be merged first. Any discovered kernel-visible semantic change invokes the protocol-change gate before implementation. The CometBFT adapter depends on this issue.