dgb(test): lock CoinNode submit/seam contract (#82 RPC-fallback half) - #163
Merged
Conversation
This was referenced Jun 18, 2026
frstrtr
force-pushed
the
dgb/coin-node-submit-seam-test
branch
from
June 18, 2026 19:51
f9f0510 to
9ee16c9
Compare
frstrtr
added a commit
that referenced
this pull request
Jun 18, 2026
Add coin/block_broadcast.hpp -- broadcast_won_block(), the DGB dual-path won-block dispatcher the run-loop wires tracker().m_on_block_found to. Fires BOTH sinks per the broadcaster-gate rule: embedded P2P relay (PRIMARY, supplied as a sink fn until NodeP2P/EmbeddedDaemon lands) AND external digibyted submitblock via the CoinNode seam (FALLBACK, fired ALWAYS, ignore_failure=true so a duplicate after a P2P accept never masks the win). landed_first records the race winner; with neither sink live the call is a safe no-op (any()=false, no throw, null seam never dereferenced). 1:1 contract mirror of bch broadcast_won_block (90a3553); decoupled via std::function P2P sink + ICoinNode* so it is build-verified now. DGB-Scrypt standalone parent -- no merged-coinbase leg in the default build. Complements the #163 RPC-fallback seam half. dgb_block_broadcast_test: 5-case dispatch contract (no-sink no-op, p2p-only, rpc-only, dual-path always-fires-fallback, fallback-no-ack-does-not-mask-p2p) over a fake ICoinNode -- 5/5 PASS, build EXIT=0. Registered in test/CMakeLists.txt AND both build.yml --target allowlists (#143 NOT_BUILT trap avoided). p2pool-merged-v36 surface: NONE (block dispatch only). Per-coin isolation: src/impl/dgb/coin/ only.
This was referenced Jun 19, 2026
frstrtr
force-pushed
the
dgb/coin-node-submit-seam-test
branch
from
June 19, 2026 07:52
9ee16c9 to
1d3cf93
Compare
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
Add coin/block_broadcast.hpp -- broadcast_won_block(), the DGB dual-path won-block dispatcher the run-loop wires tracker().m_on_block_found to. Fires BOTH sinks per the broadcaster-gate rule: embedded P2P relay (PRIMARY, supplied as a sink fn until NodeP2P/EmbeddedDaemon lands) AND external digibyted submitblock via the CoinNode seam (FALLBACK, fired ALWAYS, ignore_failure=true so a duplicate after a P2P accept never masks the win). landed_first records the race winner; with neither sink live the call is a safe no-op (any()=false, no throw, null seam never dereferenced). 1:1 contract mirror of bch broadcast_won_block (90a3553); decoupled via std::function P2P sink + ICoinNode* so it is build-verified now. DGB-Scrypt standalone parent -- no merged-coinbase leg in the default build. Complements the #163 RPC-fallback seam half. dgb_block_broadcast_test: 5-case dispatch contract (no-sink no-op, p2p-only, rpc-only, dual-path always-fires-fallback, fallback-no-ack-does-not-mask-p2p) over a fake ICoinNode -- 5/5 PASS, build EXIT=0. Registered in test/CMakeLists.txt AND both build.yml --target allowlists (#143 NOT_BUILT trap avoided). p2pool-merged-v36 surface: NONE (block dispatch only). Per-coin isolation: src/impl/dgb/coin/ only.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
…(--run) Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a boost::asio::io_context plus an explicit graceful shutdown driven from signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract. This is the lifecycle every node subsystem (sharechain peer dgb::Node, embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch handler hangs off. Standing the spine up first keeps the next increments (node/Config construction over LevelDB, P2P listen, Stratum, and the m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable rather than landing a large unverified port in one step. --selftest / bare invocation unchanged (live ShareTracker::score() path). External digibyted RPC fallback posture preserved. Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK (block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
…(--run) Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a boost::asio::io_context plus an explicit graceful shutdown driven from signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract. This is the lifecycle every node subsystem (sharechain peer dgb::Node, embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch handler hangs off. Standing the spine up first keeps the next increments (node/Config construction over LevelDB, P2P listen, Stratum, and the m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable rather than landing a large unverified port in one step. --selftest / bare invocation unchanged (live ShareTracker::score() path). External digibyted RPC fallback posture preserved. Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK (block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
…RPC arm wired Stacks on the run-loop (#182 spine + node-construct) and the DGBWorkSource 4a skeleton (#186): closes the SEAM both left for "stand the Stratum work source up + bind the won-block broadcaster." --run now constructs the miner-facing path on the run-loop io_context: - c2pool::dgb::HeaderChain + dgb::coin::Mempool (MVP-unwired this slice — the 4a work source returns default work; mining_submit low-diff-rejects via the 0.0 compute_share_difficulty sentinel BEFORE the broadcaster, so no garbage block is ever emitted) - dgb::coin::CoinNode(nullptr,nullptr) + a SubmitBlockFn bridging block_bytes -> hex -> submit_block_hex (rpc.cpp:387, REAL not a stub): the submitblock-RPC arm of the #82 dual-path broadcaster. has_rpc()==false => returns false LOUDLY (the #163 seam guard: no silent drop). - dgb::stratum::DGBWorkSource + core::StratumServer, gated on a new --stratum [HOST:]PORT flag (mirrors main_btc.cpp). Acceptor lifecycle is wired into the signal_set handler: stratum stop() runs BEFORE ioc.stop() so live miner sessions close cleanly. CMake: link c2pool-dgb against dgb_stratum. Single-coin (no bitcoin_family / src/core touch); core::StratumServer consumed, not modified. No -DAUX_DOGE. Remaining for the #82 closer (NEXT slice): the embedded P2P-relay arm (m_on_block_found -> reconstruct_won_block -> broadcast_won_block) needs the reconstructor stack (#163/#166/#167/#177), HELD off master. Two-arm independent broadcast evidence captured once both arms are live. Build EXIT=0; --run --stratum 127.0.0.1:5022 smoke: StratumServer started, sharechain peer on 5024, SIGINT -> ordered graceful shutdown (stratum stop then clean exit), EXIT=0.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
…(--run) Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a boost::asio::io_context plus an explicit graceful shutdown driven from signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract. This is the lifecycle every node subsystem (sharechain peer dgb::Node, embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch handler hangs off. Standing the spine up first keeps the next increments (node/Config construction over LevelDB, P2P listen, Stratum, and the m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable rather than landing a large unverified port in one step. --selftest / bare invocation unchanged (live ShareTracker::score() path). External digibyted RPC fallback posture preserved. Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK (block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
Pin the embedded-primary / external-digibyted-RPC-fallback contract of dgb::coin::CoinNode (core::coin::ICoinNode) that the won-block dispatch relies on: web_server submits a solved block via m_coin_node->submit_block_hex(), which forwards to NodeRPC::submitblock (the external-daemon fallback that MUST persist alongside embedded). Three invariants, mirroring impl/bch/test/coin_node_seam_test.cpp: 1. no source -> empty WorkView, no throw 2. embedded, no rpc -> WorkView sourced from embedded 3. no rpc sink -> submit_block_hex == false (!m_rpc guard, no crash) The live submitblock call + m_on_block_found tracker callback are wired by the DGB run-loop standup (main_dgb.cpp is selftest-only today); that is the remaining #82 slice and is out of scope here (rpc=nullptr). Registered in test/CMakeLists.txt AND both build.yml --target allowlists (avoids the #143 NOT_BUILT-sentinel trap). 3/3 PASS, build EXIT=0.
frstrtr
force-pushed
the
dgb/coin-node-submit-seam-test
branch
from
June 19, 2026 08:05
1d3cf93 to
e83f872
Compare
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
Add coin/block_broadcast.hpp -- broadcast_won_block(), the DGB dual-path won-block dispatcher the run-loop wires tracker().m_on_block_found to. Fires BOTH sinks per the broadcaster-gate rule: embedded P2P relay (PRIMARY, supplied as a sink fn until NodeP2P/EmbeddedDaemon lands) AND external digibyted submitblock via the CoinNode seam (FALLBACK, fired ALWAYS, ignore_failure=true so a duplicate after a P2P accept never masks the win). landed_first records the race winner; with neither sink live the call is a safe no-op (any()=false, no throw, null seam never dereferenced). 1:1 contract mirror of bch broadcast_won_block (90a3553); decoupled via std::function P2P sink + ICoinNode* so it is build-verified now. DGB-Scrypt standalone parent -- no merged-coinbase leg in the default build. Complements the #163 RPC-fallback seam half. dgb_block_broadcast_test: 5-case dispatch contract (no-sink no-op, p2p-only, rpc-only, dual-path always-fires-fallback, fallback-no-ack-does-not-mask-p2p) over a fake ICoinNode -- 5/5 PASS, build EXIT=0. Registered in test/CMakeLists.txt AND both build.yml --target allowlists (#143 NOT_BUILT trap avoided). p2pool-merged-v36 surface: NONE (block dispatch only). Per-coin isolation: src/impl/dgb/coin/ only.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
Add coin/block_broadcast.hpp -- broadcast_won_block(), the DGB dual-path won-block dispatcher the run-loop wires tracker().m_on_block_found to. Fires BOTH sinks per the broadcaster-gate rule: embedded P2P relay (PRIMARY, supplied as a sink fn until NodeP2P/EmbeddedDaemon lands) AND external digibyted submitblock via the CoinNode seam (FALLBACK, fired ALWAYS, ignore_failure=true so a duplicate after a P2P accept never masks the win). landed_first records the race winner; with neither sink live the call is a safe no-op (any()=false, no throw, null seam never dereferenced). 1:1 contract mirror of bch broadcast_won_block (90a3553); decoupled via std::function P2P sink + ICoinNode* so it is build-verified now. DGB-Scrypt standalone parent -- no merged-coinbase leg in the default build. Complements the #163 RPC-fallback seam half. dgb_block_broadcast_test: 5-case dispatch contract (no-sink no-op, p2p-only, rpc-only, dual-path always-fires-fallback, fallback-no-ack-does-not-mask-p2p) over a fake ICoinNode -- 5/5 PASS, build EXIT=0. Registered in test/CMakeLists.txt AND both build.yml --target allowlists (#143 NOT_BUILT trap avoided). p2pool-merged-v36 surface: NONE (block dispatch only). Per-coin isolation: src/impl/dgb/coin/ only.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
Add coin/block_broadcast.hpp -- broadcast_won_block(), the DGB dual-path won-block dispatcher the run-loop wires tracker().m_on_block_found to. Fires BOTH sinks per the broadcaster-gate rule: embedded P2P relay (PRIMARY, supplied as a sink fn until NodeP2P/EmbeddedDaemon lands) AND external digibyted submitblock via the CoinNode seam (FALLBACK, fired ALWAYS, ignore_failure=true so a duplicate after a P2P accept never masks the win). landed_first records the race winner; with neither sink live the call is a safe no-op (any()=false, no throw, null seam never dereferenced). 1:1 contract mirror of bch broadcast_won_block (90a3553); decoupled via std::function P2P sink + ICoinNode* so it is build-verified now. DGB-Scrypt standalone parent -- no merged-coinbase leg in the default build. Complements the #163 RPC-fallback seam half. dgb_block_broadcast_test: 5-case dispatch contract (no-sink no-op, p2p-only, rpc-only, dual-path always-fires-fallback, fallback-no-ack-does-not-mask-p2p) over a fake ICoinNode -- 5/5 PASS, build EXIT=0. Registered in test/CMakeLists.txt AND both build.yml --target allowlists (#143 NOT_BUILT trap avoided). p2pool-merged-v36 surface: NONE (block dispatch only). Per-coin isolation: src/impl/dgb/coin/ only.
This was referenced Jun 19, 2026
Closed
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
…(--run) Stand up the run-loop spine in main_dgb.cpp behind a new --run flag: a boost::asio::io_context plus an explicit graceful shutdown driven from signal_set(SIGINT, SIGTERM), mirroring main_btc.cpp s teardown contract. This is the lifecycle every node subsystem (sharechain peer dgb::Node, embedded digibyted P2P, Stratum acceptor) and the #82 won-block dispatch handler hangs off. Standing the spine up first keeps the next increments (node/Config construction over LevelDB, P2P listen, Stratum, and the m_on_block_found -> reconstruct_won_block -> broadcast_won_block binding landed across #163/#166/#167/#173/#174/#176/#177/#179) build-verifiable rather than landing a large unverified port in one step. --selftest / bare invocation unchanged (live ShareTracker::score() path). External digibyted RPC fallback posture preserved. Build: c2pool-dgb links EXIT=0 (-DCOIN_DGB=ON). Smoke: --selftest OK (block_period=75s SSOT); --run spine up, SIGINT -> clean shutdown exit 0.
frstrtr
added a commit
that referenced
this pull request
Jun 19, 2026
…RPC arm wired Stacks on the run-loop (#182 spine + node-construct) and the DGBWorkSource 4a skeleton (#186): closes the SEAM both left for "stand the Stratum work source up + bind the won-block broadcaster." --run now constructs the miner-facing path on the run-loop io_context: - c2pool::dgb::HeaderChain + dgb::coin::Mempool (MVP-unwired this slice — the 4a work source returns default work; mining_submit low-diff-rejects via the 0.0 compute_share_difficulty sentinel BEFORE the broadcaster, so no garbage block is ever emitted) - dgb::coin::CoinNode(nullptr,nullptr) + a SubmitBlockFn bridging block_bytes -> hex -> submit_block_hex (rpc.cpp:387, REAL not a stub): the submitblock-RPC arm of the #82 dual-path broadcaster. has_rpc()==false => returns false LOUDLY (the #163 seam guard: no silent drop). - dgb::stratum::DGBWorkSource + core::StratumServer, gated on a new --stratum [HOST:]PORT flag (mirrors main_btc.cpp). Acceptor lifecycle is wired into the signal_set handler: stratum stop() runs BEFORE ioc.stop() so live miner sessions close cleanly. CMake: link c2pool-dgb against dgb_stratum. Single-coin (no bitcoin_family / src/core touch); core::StratumServer consumed, not modified. No -DAUX_DOGE. Remaining for the #82 closer (NEXT slice): the embedded P2P-relay arm (m_on_block_found -> reconstruct_won_block -> broadcast_won_block) needs the reconstructor stack (#163/#166/#167/#177), HELD off master. Two-arm independent broadcast evidence captured once both arms are live. Build EXIT=0; --run --stratum 127.0.0.1:5022 smoke: StratumServer started, sharechain peer on 5024, SIGINT -> ordered graceful shutdown (stratum stop then clean exit), EXIT=0.
This was referenced Jun 20, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase B / #82 broadcaster-gate — locks the proven half of the won-block submit path with a regression guard.
What
Test-only slice mirroring
impl/bch/test/coin_node_seam_test.cpp. Pins the embedded-primary / external-digibyted-RPC-fallback contract ofdgb::coin::CoinNode(core::coin::ICoinNode) that the won-block dispatch depends on:m_coin_node->submit_block_hex()→NodeRPC::submitblock(external-daemon fallback, MUST persist alongside embedded).Three invariants (gtest, 3/3 PASS, build EXIT=0):
submit_block_hex == false(the!m_rpcguard — no throw, no null-deref crash)#82 status (root-cause, surfaced to integrator)
submit_block_hexis already real (rpc.cpp:387 → submitblock) and the generic sinkweb_server.cpp → CoinNode::submit_block_hexis intact. The remaining gap is not a stub:main_dgb.cppis selftest-only and never stands up the run-loop, som_on_block_foundis never wired and the won-block dispatcher never runs. That closes with the DGB run-loop standup slice (NodeBridge + web_server + tracker callbacks) — out of scope here (rpc=nullptr in every case).CI hygiene
Registered in
test/CMakeLists.txtAND both build.yml--targetallowlists (avoids the #143 NOT_BUILT-sentinel trap).HOLD merge — integrator merges on operator approval.