Skip to content

dash(S8): reception-wire leg 4 -- mn_list_update -> on_mn_list_update (closes the 4-leg wire) - #694

Merged
frstrtr merged 1 commit into
masterfrom
dash/s8-reception-wire-mnlist-leg
Jul 13, 2026
Merged

dash(S8): reception-wire leg 4 -- mn_list_update -> on_mn_list_update (closes the 4-leg wire)#694
frstrtr merged 1 commit into
masterfrom
dash/s8-reception-wire-mnlist-leg

Conversation

@frstrtr

@frstrtr frstrtr commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Stacks on #693 (legs 1+3). Closes the dash reception wire: adds the mnlistdiff RESYNC leg.

What

  • node_interface.hpp: +Event<MnListUpdate> mn_list_update on dash::interfaces::Node; MnListUpdate carries the projected DMN set as vector<pair<uint256, coin::MNState>> (exactly on_mn_list_update()s signature). Pulls mn_state_machine.hpp for MNState (dash-coin scoped, no cross-coin reach).
  • mn_list_ingest.hpp (new): wire_mn_list_ingest() subscribes CoinStateMaintainer::on_mn_list_update to the event; teardown via returned EventDisposable, same lifetime contract as legs 1-3.
  • test_dash_node_reception_wire.cpp: +3 KAT.

Why

Legs 1-3 wired new_tx / new_tip / block_connected. on_mn_list_update had no source event on the interface at all (called out in leg 1s scope note). This is the authoritative bulk masternode-set resync -- distinct from leg 3 folding per-block deltas incrementally between snapshots. An empty snapshot is a set-gap -> demote to the retained dashd getblocktemplate fallback.

Scope / safety

  • SAFE-ADDITIVE, single-coin: src/impl/dash/coin/ + test/ only. No bitcoin_family / src/core / other-coin trees. Per-coin isolation intact.
  • Dashd RPC fallback retained (never removed).
  • No CMakeLists/build.yml change: existing test_dash_node_reception_wire exe (already allowlisted) picks up the header + cases.

Verification (Linux x86_64, from build/)

  • ctest -R ^DashReceptionWire -> 11/11 passed (8 prior legs + 3 leg-4).
  • Object-lib + exe trap swept: --target dash, test_dash_node_interface, c2pool-dash all build clean (interface change compiles at every node_interface.hpp consumer).

… CoinStateMaintainer::on_mn_list_update

Closes the 4-leg dash reception wire. Legs 1-3 wired the mempool-relay
(new_tx), tip-advance (new_tip) and block-connect (block_connected) events
into CoinStateMaintainer; this adds the mnlistdiff RESYNC leg. Every full
masternode-set snapshot dashd delivers routes to on_mn_list_update(), which
REPLACES the DMN set the embedded coinbase pays wholesale (authoritative bulk
feed) -- distinct from leg 3 folding per-block deltas incrementally between
snapshots. An empty snapshot is a set-gap: it demotes the node-held bundle to
the retained dashd getblocktemplate fallback rather than backing a template
with a phantom payee.

Interface-shape addition (purely additive, dash interface only, single-coin):
dash::interfaces::Node gains Event<MnListUpdate> mn_list_update, where
MnListUpdate carries the projected set as vector<pair<uint256, coin::MNState>>
-- exactly on_mn_list_update()s signature. node_interface.hpp now pulls
mn_state_machine.hpp (dash-coin scoped, no cross-coin reach) for MNState,
matching the codec weight it already takes from block.hpp/transaction.hpp.

src/impl/dash/coin/mn_list_ingest.hpp: wire_mn_list_ingest() subscribes
on_mn_list_update to the event; teardown via the returned EventDisposable,
same lifetime contract as the other three legs.

KAT: test_dash_node_reception_wire gains 3 cases proving the leg end-to-end
off the real Event (no direct poke) -- a snapshot seeds the DMN set and arms
the embedded bundle with a tip present; an empty snapshot demotes to dashd;
dispose stops ingest. Suite 11/11 green. Dashd RPC fallback retained.
@frstrtr
frstrtr changed the base branch from dash/s8-reception-wire-block-connect-leg to master July 13, 2026 19:39
@frstrtr frstrtr closed this Jul 13, 2026
@frstrtr frstrtr reopened this Jul 13, 2026
@frstrtr
frstrtr merged commit ab249df into master Jul 13, 2026
38 of 40 checks passed
@frstrtr
frstrtr deleted the dash/s8-reception-wire-mnlist-leg branch July 13, 2026 20:41
frstrtr added a commit that referenced this pull request Jul 13, 2026
…work() template source + assemble_work_job_targets()

The embedded get_work chain was fully wired but had NO production consumer:
NodeCoinState::select_work() (embedded template when the 4-leg reception wire
(#693/#694) has populated the node bundle, else the retained dashd
getblocktemplate fallback) and assemble_work_job_targets() (per-miner job-target
arithmetic) each existed and were unit-tested, but nothing fused them into a
single miner-facing entry. Only the test suites ever called select_work().

Add dash::stratum::get_work() (src/impl/dash/stratum/get_work.hpp): the first
non-test caller of the embedded arm. It sources the base block template off the
node-held NodeCoinState -- NO direct dashd poll on the hot path when the bundle
is populated -- and assembles the job targets over whichever template arm ran.
dashd_fallback stays REQUIRED and is invoked ONLY on a set-gap (unpopulated /
invalidated bundle): the always-reachable safety + [GBT-XCHECK] cross-check arm,
never removed.

test_dash_get_work (4/4) pins the fused contract, seeding mirrored exactly from
test_dash_node_embedded_wire (no fabricated oracle values):
  * set-gap routes DashdFallback (invoked once) and still assembles targets;
  * populated routes Embedded WITHOUT invoking the fallback, byte-equal to a
    direct build_embedded_workdata() over the node's own held state;
  * job targets are identical across both template sources;
  * on_invalidate (reorg) demotes back to the fallback.

Registered in both build.yml --target allowlists. STRICTLY single-coin
(src/impl/dash/ + test only), SAFE-ADDITIVE.
frstrtr added a commit that referenced this pull request Jul 14, 2026
…work() template source + assemble_work_job_targets()

The embedded get_work chain was fully wired but had NO production consumer:
NodeCoinState::select_work() (embedded template when the 4-leg reception wire
(#693/#694) has populated the node bundle, else the retained dashd
getblocktemplate fallback) and assemble_work_job_targets() (per-miner job-target
arithmetic) each existed and were unit-tested, but nothing fused them into a
single miner-facing entry. Only the test suites ever called select_work().

Add dash::stratum::get_work() (src/impl/dash/stratum/get_work.hpp): the first
non-test caller of the embedded arm. It sources the base block template off the
node-held NodeCoinState -- NO direct dashd poll on the hot path when the bundle
is populated -- and assembles the job targets over whichever template arm ran.
dashd_fallback stays REQUIRED and is invoked ONLY on a set-gap (unpopulated /
invalidated bundle): the always-reachable safety + [GBT-XCHECK] cross-check arm,
never removed.

test_dash_get_work (4/4) pins the fused contract, seeding mirrored exactly from
test_dash_node_embedded_wire (no fabricated oracle values):
  * set-gap routes DashdFallback (invoked once) and still assembles targets;
  * populated routes Embedded WITHOUT invoking the fallback, byte-equal to a
    direct build_embedded_workdata() over the node's own held state;
  * job targets are identical across both template sources;
  * on_invalidate (reorg) demotes back to the fallback.

Registered in both build.yml --target allowlists. STRICTLY single-coin
(src/impl/dash/ + test only), SAFE-ADDITIVE.
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