Skip to content

nmc(P1f): HeaderChain LevelDB persistence (h/tip/height) + 6 KATs (52->58) - #201

Merged
frstrtr merged 1 commit into
masterfrom
nmc/p1f-leveldb-persist
Jun 19, 2026
Merged

nmc(P1f): HeaderChain LevelDB persistence (h/tip/height) + 6 KATs (52->58)#201
frstrtr merged 1 commit into
masterfrom
nmc/p1f-leveldb-persist

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 19, 2026

Copy link
Copy Markdown
Owner

P1f LevelDB persistence leg (NMC embedded merge-mined chain)

Stacks on the P1f get_locator slice conceptually but is independent — touches
disjoint regions of header_chain.hpp, so it bases cleanly on master (does not
require #200/get_locator to land first).

What it does

  • Write path: every accepted header is persisted on the connect_locked
    success path under "h"+block_hash(32) → serialized IndexEntryDiskV1, plus
    "tip"(32B) and "height"(4B BE) pointers, in one commit_sync() batch.
    Rejected (idempotent / orphan / activation-gate) headers write nothing.
  • Read path: init() opens the store (when db_path given) and
    load_from_db() rebuilds m_index from the "h" prefix, then restores
    m_tip / m_tip_height / m_best_work from the tip entry.
  • Degrades gracefully: empty db_path or open failure → pure in-memory, no crash.

Mirror-of-btc with a documented divergence

Adapted from btc::coin::HeaderChain persistence. No "i" height-index key:
NMC keeps a full-residency m_index (not btc's bounded LRU + separate height
index), so the "i" schema has no consumer here. The "height" key collision
with the "h" prefix scan is handled by a size()==33 guard (covered by a KAT).

P1f-DEFER

AuxPow blobs are not serialized yet — only a has_auxpow presence flag. A
reloaded merge-mined header keeps its HEADER_VALID_CHAIN status; its auxpow
comes back nullopt. The blob lands behind this same flag in the next sub-leg
(nmc::coin::AuxPow has no serialization yet; not hand-rolled here per the fence).

Tests / fence

+6 KATs (NmcP1fPersist): disk-format round-trips (incl. status + aux-flag) and
real LevelDBStore reopen round-trips under a temp dir. Suite 52 → 58 green,
nmc_auxpow_merkle_test EXIT=0 locally. NMC-tree only (two files:
coin/header_chain.hpp, test/auxpow_merkle_test.cpp); rides the allowlisted
test target — no build.yml / CI change. GPG-signed, attribution-clean.

…->64)

Rebased onto master (771f586) post-#200/get_locator. Persists every accepted entry under "h"+block_hash (IndexEntryDiskV1), plus tip/height pointers, in one synced WriteBatch; init() restores m_index/m_tip/m_tip_height/m_best_work via load_from_db(). NMC has no height-index (full-residency m_index), so no "i" key. Auxpow blob deferred (presence flag only). Coexists with get_locator: 6 persist KATs + 6 locator KATs = 58->64 green.
@frstrtr
frstrtr force-pushed the nmc/p1f-leveldb-persist branch from 197d91d to 19c00f8 Compare June 19, 2026 11:03
@frstrtr
frstrtr merged commit 67b309f into master Jun 19, 2026
19 checks passed
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.

1 participant