3737// / (factory) path; the -1 activation-height default is a deliberate
3838// / fail-closed sentinel for hand-built Params only.
3939// / STILL DEFERRED (scoped later, NOT a P0 fence):
40- // / * The header-STORAGE / chain-connection path — a proof that passes the
41- // / gate is verified but NOT yet persisted (see add_auxpow_header()).
4240// / * Live cross-check of the pinned constants vs a running .140 namecoind,
4341// / deferred to the PE item4 soak.
42+ // / (The header-STORAGE / connect / LevelDB-persist path is WIRED -- see
43+ // / connect_locked() + persist_entry_locked(); the prior "not yet persisted"
44+ // / note was retired once P1e/P1f landed.)
4445// / ==========================================================================
4546
4647#include " block.hpp"
@@ -940,10 +941,11 @@ inline uint32_t get_next_work_required(
940941
941942// ─── HeaderChain ─────────────────────────────────────────────────────────────
942943
943- // / Header-only chain skeleton for embedded NMC. Mirrors the public surface of
944- // / btc::coin::HeaderChain. P0: the validation internals (difficulty checks,
945- // / AuxPow checks, LevelDB persistence) are intentionally NOT implemented — the
946- // / methods below are structural skeletons so call sites compile.
944+ // / Header-only chain for embedded NMC. Mirrors the public surface of
945+ // / btc::coin::HeaderChain. The validation internals are WIRED: AuxPow gate
946+ // / (P1d), in-memory connect / cumulative-work / fork-choice (P1e) and LevelDB
947+ // / persistence (P1f). The only deferred leg is the live-node constant
948+ // / cross-check (PE item4 soak); see the STATUS banner above.
947949class HeaderChain {
948950public:
949951 explicit HeaderChain (const NMCChainParams& params, const std::string& db_path = " " )
@@ -958,9 +960,9 @@ class HeaderChain {
958960 HeaderChain (const HeaderChain&) = delete ;
959961 HeaderChain& operator =(const HeaderChain&) = delete ;
960962
961- // / Initialize the chain.
962- // / P0-DEFER: no LevelDB open, no persisted-state load, no checkpoint seed.
963- // / Returns true (structural success) so wiring smoke-tests pass .
963+ // / Initialize the chain. Opens LevelDB at m_db_path (when set) and reloads
964+ // / persisted state via load_from_db(); degrades to in-memory on open
965+ // / failure (mirror of btc). Returns true .
964966 bool init () {
965967 LOG_INFO << " [EMB-NMC] HeaderChain::init() db_path="
966968 << (m_db_path.empty () ? " (in-memory)" : m_db_path);
@@ -983,7 +985,7 @@ class HeaderChain {
983985 return true ;
984986 }
985987
986- // / Current chain tip (best header). P0: empty until add path is built .
988+ // / Current chain tip (best header); std::nullopt on an empty chain .
987989 std::optional<IndexEntry> tip () const {
988990 std::lock_guard<std::mutex> lock (m_mutex);
989991 if (m_tip.IsNull ()) return std::nullopt ;
@@ -1059,9 +1061,6 @@ class HeaderChain {
10591061 return locator;
10601062 }
10611063
1062- // / Add a single plain header.
1063- // / P0-DEFER: NO difficulty validation, NO PoW check, NO connection check,
1064- // / NO persistence. Structural skeleton only — returns false.
10651064 // / Add a single plain (non-merge-mined) header.
10661065 // / P1e storage leg: in-memory connect path. On an empty chain the header
10671066 // / seeds the chain root (height 0, checkpoint anchor); otherwise it must
@@ -1138,11 +1137,20 @@ class HeaderChain {
11381137 return connect_locked (header, auxpow);
11391138 }
11401139
1141- // / Add a batch of plain headers. P0-DEFER: returns 0 (none accepted).
1140+ // / Add a batch of plain (non-merge-mined) headers, as delivered by a
1141+ // / getheaders response during SPV header-sync. Each header is run through
1142+ // / the same connect path as add_header() under a single lock. Headers are
1143+ // / expected in ascending (parent-before-child) order; out-of-order or
1144+ // / gapped entries simply fail to connect and are skipped without aborting
1145+ // / the batch. Returns the number of headers newly connected.
11421146 int add_headers (const std::vector<BlockHeaderType>& headers) {
1143- (void )headers;
1144- // P0-DEFER: batch header path not implemented.
1145- return 0 ;
1147+ std::lock_guard<std::mutex> lock (m_mutex);
1148+ int accepted = 0 ;
1149+ for (const auto & h : headers) {
1150+ if (connect_locked (h, std::nullopt ))
1151+ ++accepted;
1152+ }
1153+ return accepted;
11461154 }
11471155
11481156 // / P1 PC: look up a header by absolute height by walking the tip's ancestry
0 commit comments