Skip to content

Commit a20c558

Browse files
authored
dash(S8): reception-wire legs 1+3 (#693)
dash(S8): reception-wire legs 1+3 -- new_tx/block_connected -> CoinStateMaintainer (rebased on master)
2 parents d37e776 + f76a948 commit a20c558

6 files changed

Lines changed: 286 additions & 2 deletions

File tree

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ jobs:
102102
core_test sharechain_test share_test btc_share_test \
103103
test_threading test_weights \
104104
test_header_chain test_mempool test_template_builder \
105-
test_doge_chain test_compact_blocks test_dash_x11_kat test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly test_dash_difficulty_parity test_dash_auto_ratchet test_dash_min_protocol_gate test_dash_work_source test_dash_node_coin_state test_dash_coin_state_maintainer test_dash_node_embedded_wire \
105+
test_doge_chain test_compact_blocks test_dash_x11_kat test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly test_dash_difficulty_parity test_dash_auto_ratchet test_dash_min_protocol_gate test_dash_work_source test_dash_node_coin_state test_dash_coin_state_maintainer test_dash_node_embedded_wire test_dash_node_reception_wire \
106106
test_multiaddress_pplns test_pplns_stress \
107107
test_hash_link test_decay_pplns \
108108
test_pplns_consensus \
@@ -252,7 +252,7 @@ jobs:
252252
test_threading test_weights \
253253
test_header_chain test_mempool test_template_builder \
254254
test_doge_chain test_compact_blocks test_dash_x11_kat \
255-
test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly test_dash_difficulty_parity test_dash_auto_ratchet test_dash_min_protocol_gate test_dash_work_source test_dash_node_coin_state test_dash_coin_state_maintainer test_dash_node_embedded_wire \
255+
test_dash_header_chain test_dash_block_replay test_dash_conformance test_dash_subsidy test_dash_mempool test_dash_simplifiedmns test_dash_quorum test_dash_quorum_root test_dash_mn_state test_dash_embedded_gbt test_dash_smldiff test_dash_p2p_messages test_dash_p2p_connection test_dash_p2p_node test_dash_node_interface test_dash_config test_dash_broadcaster test_dash_broadcaster_full test_dash_share_hash_link test_dash_block_relay test_dash_rpc_request test_dash_rpc_conf test_dash_block_producer test_dash_embedded_relay_e2e test_dash_block_relay_plan test_dash_version_activation_latch test_dash_block_relay_binding test_dash_block_relay_dual_arm test_dash_coinbase_parity test_dash_donation_combined test_dash_g3_assembled test_dash_work_target test_dash_work_job_targets test_dash_stratum_binding test_dash_job_notify_roundtrip test_dash_cb_payee test_dash_stratum_notify_roundtrip test_dash_poolnode_messages test_dash_peer test_dash_share_tracker test_dash_node test_dash_share_messages test_dash_stratum_extranonce_split test_dash_stratum_submit_reassembly test_dash_difficulty_parity test_dash_auto_ratchet test_dash_min_protocol_gate test_dash_work_source test_dash_node_coin_state test_dash_coin_state_maintainer test_dash_node_embedded_wire test_dash_node_reception_wire \
256256
test_hash_link test_decay_pplns \
257257
test_pplns_consensus \
258258
test_v36_script_sorting test_v36_cross_impl_refhash \
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// SPDX-License-Identifier: AGPL-3.0-or-later
2+
#pragma once
3+
// ===========================================================================
4+
// dash reception wire (leg 3 of 4) -- interfaces::Node::block_connected ->
5+
// maintainer.
6+
//
7+
// #672..#685 landed the node-held embedded coin-state bundle + its async
8+
// CoinStateMaintainer; leg 1 (wire_mempool_ingest) subscribed the mempool-relay
9+
// event and leg 2 (wire_tip_ingest) the header/think TIP-ADVANCE event. This
10+
// leg subscribes the BLOCK-CONNECT event: every connected block is routed to
11+
// CoinStateMaintainer::on_block_connected(), which folds the block's DIP3
12+
// special txs into the DMN set incrementally (MnStateMachine::apply_block),
13+
// keeping the masternode set the embedded coinbase pays current BETWEEN full
14+
// mnlistdiff snapshots. A block that empties the set (all collateral spent)
15+
// clears MN-readiness and demotes the bundle to the retained dashd getblock-
16+
// template fallback rather than backing a template with a phantom payee.
17+
//
18+
// PAYLOAD: a bare full_block carries the block body but NOT its height, and
19+
// apply_block needs the connected height (DIP3 special-tx chain position). So
20+
// this leg subscribes block_connected, which pairs (block, height) -- the
21+
// interface-shape addition this leg makes, mirroring leg 2's TipAdvance, kept to
22+
// the dash interface only (single-coin, purely additive). on_mn_list_update
23+
// remains the authoritative bulk resync (leg 4, mnlistdiff source event).
24+
//
25+
// LIFETIME: the handler captures maint by reference, so maint (and the
26+
// NodeCoinState it drives) MUST outlive node. The returned EventDisposable lets
27+
// a caller tear the subscription down explicitly; it does NOT auto-dispose on
28+
// drop -- identical contract to wire_mempool_ingest / wire_tip_ingest.
29+
//
30+
// SCC: pulls node_interface.hpp (transaction/block codec via BlockConnected),
31+
// so include this header ONLY from a TU that already links the full dash codec
32+
// (main_dash + this leg KAT), never a guard-weight TU.
33+
// ===========================================================================
34+
#include <memory>
35+
36+
#include <core/events.hpp>
37+
38+
#include "node_interface.hpp" // dash::interfaces::Node (block_connected feed) + BlockConnected
39+
#include "coin_state_maintainer.hpp" // dash::coin::CoinStateMaintainer::on_block_connected
40+
41+
namespace c2pool::dash
42+
{
43+
44+
// Subscribe maint to node.block_connected: every connected block folds its DIP3
45+
// special txs into the DMN set via on_block_connected(block, height). The
46+
// maintainer refreshes MN-readiness from the post-apply set size -- a block that
47+
// empties the set demotes the node-held bundle to the dashd fallback; otherwise
48+
// it republishes with the freshened MN set. Returns the subscription handle so
49+
// the caller controls teardown.
50+
inline std::shared_ptr<EventDisposable>
51+
wire_block_connect_ingest(::dash::interfaces::Node& node,
52+
::dash::coin::CoinStateMaintainer& maint)
53+
{
54+
return node.block_connected.subscribe(
55+
[&maint](const ::dash::interfaces::BlockConnected& bc)
56+
{
57+
maint.on_block_connected(bc.block, bc.height);
58+
});
59+
}
60+
61+
} // namespace c2pool::dash
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// SPDX-License-Identifier: AGPL-3.0-or-later
2+
#pragma once
3+
// ===========================================================================
4+
// dash reception wire (leg 1 of 4) -- interfaces::Node::new_tx -> maintainer.
5+
//
6+
// #672..#685 landed the node-held embedded coin-state bundle plus its async
7+
// CoinStateMaintainer, and proved that DRIVING the maintainer's on_*() methods
8+
// flips select_work() to the embedded arm. But nothing in a LIVE NodeImpl ever
9+
// subscribed the coin interface's reception events to that maintainer, so in a
10+
// running node the arm could never flip on its own -- the maintainer sat idle.
11+
// This is the first of the four reception legs
12+
// (on_mempool_tx / on_block_connected / on_new_tip / on_mn_list_update): the
13+
// mempool-relay leg, wired exactly as the dgb sibling (wire_mempool_ingest)
14+
// but routed through the maintainer's on_mempool_tx() so the readiness /
15+
// republish bookkeeping stays in one place.
16+
//
17+
// PAYLOAD-COMPLETE TODAY: interfaces::Node::new_tx carries a whole
18+
// coin::Transaction, and on_mempool_tx() never gates publication (an empty
19+
// mempool still yields a valid coinbase-only template), so this leg needs no
20+
// chain context. The other three legs are NOT wired here: on_block_connected
21+
// needs the connected block's HEIGHT (full_block carries none -- see bch's
22+
// block_connector deriving it from the chain tip), on_new_tip needs
23+
// bits/mtp/address-version params a bare best_block_hash does not carry, and
24+
// on_mn_list_update has no source event on interfaces::Node at all. Those are
25+
// their own slices; opening them touches the interface shape and is a design
26+
// decision surfaced to the integrator, not guessed here.
27+
//
28+
// LIFETIME: the handler captures `maint` by reference, so `maint` (and the
29+
// NodeCoinState it drives) MUST outlive `node`. The returned EventDisposable
30+
// lets a caller tear the subscription down explicitly; EventDisposable does
31+
// NOT auto-dispose on destruction, so if the handle is dropped the
32+
// subscription persists for the node's life.
33+
//
34+
// SCC (#143 / #22 / #39): pulls transaction.hpp (the tx serialization codec),
35+
// so include this header ONLY from a TU that already links the full dash codec
36+
// (main_dash + this leg's KAT), never a guard-weight TU -- identical to the
37+
// dgb mempool_ingest / embedded_tx_select btclibs-SCC trap.
38+
// ===========================================================================
39+
#include <memory>
40+
41+
#include <core/events.hpp>
42+
43+
#include "node_interface.hpp" // dash::interfaces::Node (new_tx feed)
44+
#include "coin_state_maintainer.hpp" // dash::coin::CoinStateMaintainer::on_mempool_tx
45+
#include "transaction.hpp" // dash::coin::Transaction -> MutableTransaction
46+
47+
namespace c2pool::dash
48+
{
49+
50+
// Subscribe `maint` to `node.new_tx`: every relayed tx is folded into the
51+
// maintainer's mempool via on_mempool_tx (fee_known=false until a UTXO view
52+
// feeds it, matching the embedded shaper's conservative default -- a P2P-fed
53+
// mempool cannot desync coinbasevalue versus a daemon's GBT). The mempool leg
54+
// never gates publication, so a rejected tx (bad utxo ref / already-in) is a
55+
// no-op here, not a demotion. Returns the subscription handle so the caller
56+
// controls teardown.
57+
inline std::shared_ptr<EventDisposable>
58+
wire_mempool_ingest(::dash::interfaces::Node& node,
59+
::dash::coin::CoinStateMaintainer& maint)
60+
{
61+
return node.new_tx.subscribe(
62+
[&maint](const ::dash::coin::Transaction& tx)
63+
{
64+
maint.on_mempool_tx(::dash::coin::MutableTransaction(tx));
65+
});
66+
}
67+
68+
} // namespace c2pool::dash

src/impl/dash/coin/node_interface.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ struct TipAdvance
3434
uint32_t version{0};
3535
};
3636

37+
/// Header/think path payload: a block was connected to the active chain. The
38+
/// bare full_block carries the block body but NOT the height CoinStateMaintainer
39+
/// ::on_block_connected needs to drive MnStateMachine::apply_block (the DIP3
40+
/// special-tx height is a chain-position input apply_block cannot recover from
41+
/// the block alone). block_connected pairs the two so the reception wire feeds
42+
/// apply_block the exact (block, height) apply_block expects -- purely additive,
43+
/// dash interface only (leg 2's new_tip added TipAdvance for the same reason a
44+
/// bare best_block_hash was insufficient).
45+
struct BlockConnected
46+
{
47+
coin::BlockType block;
48+
uint32_t height{0};
49+
};
50+
3751
struct Node
3852
{
3953
Variable<uint256> best_block_hash;
@@ -48,6 +62,14 @@ struct Node
4862
// tip-readiness prerequisite without a direct poke.
4963
Event<TipAdvance> new_tip;
5064

65+
// Header/think path: fires when a block is connected to the active chain,
66+
// carrying (block, height) (see BlockConnected). The reception wire
67+
// subscribes CoinStateMaintainer::on_block_connected to this so the DMN set
68+
// the embedded coinbase pays auto-maintains incrementally between full
69+
// mnlistdiff snapshots -- a block that empties the set demotes to the dashd
70+
// fallback rather than backing a template with a phantom payee.
71+
Event<BlockConnected> block_connected;
72+
5173
// SPV A1 (parity audit): fires when dashd announces a ChainLock has
5274
// been aggregated for a block. Carries {block_hash, height}.
5375
// Consumers (e.g. block-find submit handler) can consult

test/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,21 @@ if (BUILD_TESTING AND GTest_FOUND)
560560
target_link_libraries(test_dash_node_embedded_wire PRIVATE c2pool_payout c2pool_hashrate c2pool_merged_mining c2pool_storage pool) # OBJECT-lib SCC direct-naming (#22/#39)
561561
gtest_add_tests(test_dash_node_embedded_wire "" AUTO)
562562

563+
# Reception wire (legs 1-3): interfaces::Node reception Events ->
564+
# CoinStateMaintainer. Proves the wire_*_ingest() subscriptions fold off the
565+
# real Events (no direct poke), honour dispose(), and reach the embedded
566+
# template. Same header-only link set as the maintainer suite (no NodeImpl
567+
# -> no pool/storage dep).
568+
add_executable(test_dash_node_reception_wire test_dash_node_reception_wire.cpp)
569+
target_link_libraries(test_dash_node_reception_wire PRIVATE
570+
GTest::gtest_main GTest::gtest
571+
dash_x11 core
572+
nlohmann_json::nlohmann_json
573+
${Boost_LIBRARIES}
574+
)
575+
target_link_libraries(test_dash_node_reception_wire PRIVATE c2pool_payout c2pool_hashrate c2pool_merged_mining) # OBJECT-lib SCC direct-naming (#22/#39)
576+
gtest_add_tests(test_dash_node_reception_wire "" AUTO)
577+
563578
# DASH CSimplifiedMNListDiff (mnlistdiff wire, S8.1 leaf): vendored diff
564579
# round-trip + dashcore field-layout pin + apply_diff semantics. Header-only
565580
# over the SimplifiedMNList leaf + coin/transaction; no ltc/pool SCC dep.

0 commit comments

Comments
 (0)