Skip to content

feat(dbtool): add moho state and export-entries commands - #5

Open
vladb-ai wants to merge 4 commits into
mainfrom
feat/dbtool-moho
Open

feat(dbtool): add moho state and export-entries commands#5
vladb-ai wants to merge 4 commits into
mainfrom
feat/dbtool-moho

Conversation

@vladb-ai

@vladb-ai vladb-ai commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Replicated from alpenlabs#171

Description

Extends dbtool with a moho domain so the runner's Moho data can be inspected and maintained offline, the same way the existing asm domain covers the storage DB. Previously there was no offline tooling for any Moho state.

Two resources, in two databases (each command opens the one it needs):

  • moho state — per-block MohoState snapshots, in the proof DB. get <commitment> · latest · list · put <commitment> --file F · delete <commitment> · prune (--before|--after) <h>.
  • moho export-entries — the per-container export-entry MMR the RPC rebuilds inclusion proofs from, in the storage DB. get · find · height · count · range · proof · append · prune --from.

Everything goes through the existing synchronous surface of strata-asm-moho-storage, so dbtool stays fully synchronous. Records render as their cheap public fields plus a lossless ssz_hex blob, and mutating verbs stay behind the --write gate — consistent with the asm commands.

The one storage-crate change is additive: SledMohoStateDb gains list, delete, and prune_after (the worker only reads/appends/prunes-from-below), mirroring asm-storage's SledAsmStateDb. SledExportEntriesDb already exposed everything needed.

This also corrects the README's earlier "planned" section, which put export-entries in the proof DB — it actually lives in the storage DB alongside the ASM manifests.

The remaining proof-DB resources (proof asm/moho/mapping/status/prune) are a separate PR (alpenlabs#172).

Type of Change

  • New feature/Enhancement (non-breaking change which adds functionality or enhances an existing one)
  • Documentation update
  • New or updated tests

Notes to Reviewers

The moho state and moho export-entries resources deliberately target different --db directories; the dispatcher picks the opener per resource (see main.rs / cmd::moho_target).

Verified end-to-end against a real sled DB through the built binary: the --write gate, appendcount/get/find/height/range/proof, and prune --from all behave, plus the empty-DB read paths and the prune-arg validation.

A functional test (fn_asm_dbtool_moho_test.py) drives the prover env until a Moho proof lands, then exercises moho state against the real proof DB (list/latest/get round-trips, missing lookup, --write gate, delete on a snapshot) and moho export-entries against the storage DB (negative paths — ASM has no assignment-fulfillment tooling to drive a real export entry).

Checklist

  • I have performed a self-review of my code.
  • I have commented my code where necessary.
  • I have updated the documentation if needed.
  • My changes do not introduce new warnings.
  • I have added tests that prove my changes are effective or that my feature works.
  • New and existing tests pass with my changes.

prajwolrg and others added 4 commits July 2, 2026 10:50
The Moho worker only ever reads, appends, and prunes-from-below, so the
sled state store exposed just those. Offline tooling (dbtool) needs to
enumerate, remove individual snapshots, and roll the store back to a
known-good height, so add the read-only `list`, the single-key `delete`,
and `prune_after` — mirroring `asm-storage`'s `SledAsmStateDb`.
dbtool only covered the storage DB's `asm` domain. Add a `moho` domain so
the runner's Moho data can be inspected and maintained offline too.

The two resources live in different databases, so each opens the one it
needs: `moho state` (per-block MohoState snapshots) in the proof DB, and
`moho export-entries` (the per-container export-entry MMR the RPC rebuilds
inclusion proofs from) in the storage DB — a split the README's earlier
"planned" section got wrong. Both go through the existing sync surface of
`strata-asm-moho-storage`, keeping dbtool fully synchronous.

Records render as their cheap public fields plus a lossless `ssz_hex`
blob, and mutating verbs stay behind the `--write` gate, matching the
`asm` commands.
Drives the prover env until a Moho proof lands (implying the Moho worker
persisted its state), stops the runner, then exercises `moho state`
against the proof DB — list/latest/get round-trips, a missing lookup, the
--write gate, and a delete on a snapshot — and `moho export-entries`
against the storage DB. No export entry can be driven from the harness
(ASM lacks assignment-fulfillment tooling), so export-entries gets
negative-path coverage, matching the existing RPC test.
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

🔒 AI Security Review

Reviewed the full diff (bin/dbtool moho commands, SledMohoStateDb::{prune_after,delete,list}, and the new functional test).

No exploitable vulnerabilities found.

Context that shapes the risk here:

  • dbtool is an offline operator CLI, not a network-facing service. It requires direct filesystem access to a sled DB directory, and the runner must already be stopped (sled takes an exclusive lock) before any command can run — so the caller is already a trusted local operator, not a remote/untrusted party.
  • All mutating verbs (put, delete, prune, append) are gated by ensure_write/--write (bin/dbtool/src/utils.rs), consistent with the existing asm commands.
  • Input handling is careful and panic-averse on the new code paths:
    • parse_hash32/parse_commitment (bin/dbtool/src/utils.rs) reject malformed hex/length via Result, no unwrap/expect on attacker-shaped input.
    • read_hashes (bin/dbtool/src/cmd/export_entries.rs:339) validates the input file length is a multiple of 32 before chunks_exact(32), so the subsequent try_into().expect(...) is safe by construction.
    • SledMohoStateDb::prune_after (crates/extensions/moho/storage/src/sled/moho_state.rs:589) uses checked_add on the u32 height, avoiding overflow at u32::MAX.
    • container: u8 in ExportEntriesVerb is used directly as a namespace prefix byte; there's no fixed-size array indexing, so no out-of-bounds concern from an arbitrary container id.
  • moho export-entries proof <container> <index> --at <n> exposes StoredMmr::generate_proof_at_size to raw CLI arguments, but this mirrors the pre-existing, already-shipped asm manifest-mmr proof <index> --at <n> pattern (crates/storage/src/sled/manifest_mmr.rs:119) — not a new exposure introduced by this PR, and the call is Result-returning, not unsafe.
  • The Python functional test (functional-tests/tests/dbtool/fn_asm_dbtool_moho_test.py) invokes dbtool via subprocess.run with an argument list (no shell=True), so there's no command-injection concern there.

Nothing in this diff introduces injection, auth/access-control gaps, unsafe deserialization, crypto misuse, or memory-safety issues.

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.

2 participants