Skip to content

Streaming daemon: Slice 1 · Layer 2 — Storage primitives #810

Description

@chowbao

Part of #808 (epic) · Builds on: #809 · Reference implementation: #806

Slice 1 · Layer 2 of 4 — Storage primitives. Produces and freezes a single chunk's cold artifacts from a ledger source. Still no long-running daemon — these are the building blocks Layer 3 drives.

Context

A chunk is the atomic unit of ingestion/freezing (10k ledgers). This layer adds the per-chunk hot RocksDB and the processChunk primitive that materializes a chunk's cold .pack from whatever source is cheapest. The merged ledger stores compose into one multi-CF hot DB so a ledger commits as one atomic synced WriteBatch.

Scope

  • Per-chunk hot DB lifecycle (pkg/stores/hotchunk)
    • one RocksDB per chunk holding the ledgers column family (events/txhash CFs are added in later slices)
    • openHotDBForChunk:
      • ready → open existing
      • transient | absent → wipe + recreate (dirent + grandparent fsync)
      • fatal on a ready key whose dir is missing (hot-volume loss — no auto-heal)
    • discardHotDBForChunk: transient bracket → rmdir → delete key
    • a read-only view for freezing; the transient / ready state machine
  • processChunk
    • single-pass materialization of a chunk's requested cold artifacts (here: ledgers → .pack) through the one-write protocol
    • per-kind idempotency (skip if already "frozen")
  • backfillSource — picks a chunk's ledger source in a fixed preference order:
    • ready + complete hot DB
    • frozen local .pack (when ledgers not requested)
    • bulk backend — with the loss-vs-staleness rule + a bounded waitForBackendCoverage (fatal on timeout) for backend-only chunks above a lagging tip
  • Ledger cold-ingest wiring (ingest/driver, ingest/service) — drive the ledger ingester into the hot DB / cold .pack

Acceptance

  • Atomicity: a ledger is fully present or fully absent; create/discard idempotent across mid-op crashes.
  • Hot-volume loss: ready-but-missing-dir fatals with a curated recovery instruction; the read handle closes before any same-tick discard.
  • Determinism: re-materialization overwrites at the canonical path and is byte-identical; widening re-derives a covered chunk from local .pack with no download; the backend-lag wait fires only for genuinely backend-only chunks.
  • Green stacked on Layer 1 (build / vet / -short).

Design references

Dependencies

Out of scope

  • the resolver/executor, ingestion loop, lifecycle tick → Layer 3
  • events CFs / tx-hash CF + .bin → Slices 2 & 3

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions