Skip to content

Commit 3e5a67c

Browse files
committed
Merge master (22359c6) into dash/s8-poolnode-share-messages-leaf3 — refresh vs #582/#587/#592/#605 landings
ctest allowlist union: test_dash_poolnode_messages (from #582) + test_dash_share_messages. Sources auto-merged; re-runs the stale (pre-runner-reset) CodeQL c-cpp.
2 parents 1f96419 + 22359c6 commit 3e5a67c

21 files changed

Lines changed: 5772 additions & 27 deletions

.github/workflows/build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
test_threading test_weights \
8989
test_header_chain test_mempool test_template_builder \
9090
test_doge_chain test_compact_blocks test_dash_x11_kat \
91-
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_cb_payee test_dash_share_messages \
91+
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_cb_payee test_dash_poolnode_messages test_dash_share_messages \
9292
test_multiaddress_pplns test_pplns_stress \
9393
test_hash_link test_decay_pplns \
9494
test_pplns_consensus \
@@ -100,7 +100,7 @@ jobs:
100100
dgb_gentx_coinbase_test dgb_connection_coinbase_test dgb_pplns_payout_split_test nmc_auxpow_merkle_test nmc_template_builder_test nmc_auxpow_wire_test nmc_reconstruct_won_block_test nmc_mempool_name_test nmc_block_broadcast_test nmc_host_dualpath_test nmc_fallback_path_conformance_test dgb_gentx_share_path_test dgb_conn_pplns_producer_test dgb_other_tx_resolver_test \
101101
dgb_other_tx_assembler_test dgb_reconstruct_won_block_test dgb_reconstruct_closure_test dgb_gentx_unpack_test dgb_work_source_test dgb_template_builder_test dgb_embedded_coin_node_test dgb_embedded_tx_select_test dgb_template_other_txs_test dgb_coinbase_value_parity_test dgb_submit_classify_test dgb_aux_parent_coinbase_parity_test dgb_template_capture_test dgb_aux_doge_db_commitment_bind_test dgb_aux_doge_mm_commitment_test dgb_aux_doge_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test dgb_aux_dual_target_select_test dgb_aux_broadcast_path_election_test \
102102
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
103-
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_target_retarget_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_min_protocol_ratchet_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test v37_test \
103+
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_target_retarget_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_auto_ratchet_sim_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_min_protocol_ratchet_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test v37_test \
104104
-j8
105105
106106
- name: Run tests
@@ -238,7 +238,7 @@ jobs:
238238
test_threading test_weights \
239239
test_header_chain test_mempool test_template_builder \
240240
test_doge_chain test_compact_blocks test_dash_x11_kat \
241-
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_cb_payee test_dash_share_messages \
241+
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_cb_payee test_dash_poolnode_messages test_dash_share_messages \
242242
test_hash_link test_decay_pplns \
243243
test_pplns_consensus \
244244
test_v36_script_sorting test_v36_cross_impl_refhash \
@@ -249,7 +249,7 @@ jobs:
249249
dgb_gentx_coinbase_test dgb_connection_coinbase_test dgb_pplns_payout_split_test nmc_auxpow_merkle_test nmc_template_builder_test nmc_auxpow_wire_test nmc_reconstruct_won_block_test nmc_mempool_name_test nmc_block_broadcast_test nmc_host_dualpath_test nmc_fallback_path_conformance_test dgb_gentx_share_path_test dgb_conn_pplns_producer_test dgb_other_tx_resolver_test \
250250
dgb_other_tx_assembler_test dgb_reconstruct_won_block_test dgb_reconstruct_closure_test dgb_gentx_unpack_test dgb_work_source_test dgb_template_builder_test dgb_embedded_coin_node_test dgb_embedded_tx_select_test dgb_template_other_txs_test dgb_coinbase_value_parity_test dgb_submit_classify_test dgb_aux_parent_coinbase_parity_test dgb_template_capture_test dgb_aux_doge_db_commitment_bind_test dgb_aux_doge_mm_commitment_test dgb_aux_doge_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test dgb_aux_dual_target_select_test dgb_aux_broadcast_path_election_test \
251251
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
252-
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_target_retarget_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_min_protocol_ratchet_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
252+
dgb_coin_node_seam_test dgb_block_broadcast_test dgb_won_block_dispatch_test dgb_forced_won_share_dualpath_test dgb_scrypt_pow_test dgb_nonce_grinder_test dgb_regrind_block_test dgb_won_block_finalize_test dgb_share_target_genesis_test dgb_share_target_retarget_test dgb_share_bits_oracle_pin_test dgb_pool_msg_wire_test dgb_get_shares_walk_test dgb_download_stops_test dgb_think_p1_walk_bounds_test dgb_think_p1_desired_emit_test dgb_think_p6_desired_cutoff_test dgb_think_p4_head_keys_test dgb_think_p3_best_head_test dgb_g1_oracle_byte_parity_test dgb_think_p2_walk_bounds_test dgb_expected_time_to_block_test dgb_tail_score_endpoints_test dgb_pool_attempts_per_second_test dgb_pool_efficiency_test dgb_think_p5_best_share_punish_test dgb_auto_ratchet_tail_guard_test dgb_auto_ratchet_sim_test dgb_binomial_conf_interval_test dgb_desired_version_tally_test dgb_min_protocol_ratchet_test dgb_get_height_and_last_endpoints_test dgb_chain_walk_window_test dgb_redistribute_delegate_ghal_test dgb_share_weight_decay_test dgb_naughty_propagation_test dgb_hash_format_parity_test dgb_emergency_decay_saturation_test test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
253253
v37_test \
254254
-j8
255255

src/c2pool/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,15 @@ add_executable(c2pool-bch
238238
${CMAKE_SOURCE_DIR}/src/impl/bch/coin/p2p_node.cpp
239239
${CMAKE_SOURCE_DIR}/src/impl/bch/coin/coin_node.cpp
240240
${CMAKE_SOURCE_DIR}/src/impl/bch/coin/rpc.cpp
241+
# M5 pool-node body TUs: NodeImpl out-of-line methods (node.cpp) + the two
242+
# p2pool p2p protocol dispatchers (Legacy/Actual handle_message_* family) +
243+
# the stratum work source. These define the previously-undefined NodeImpl::
244+
# and protocol symbols so the --pool path LINKS. Per-coin isolation holds
245+
# (src/impl/bch only); compiled directly into the target like the coin TUs.
246+
${CMAKE_SOURCE_DIR}/src/impl/bch/node.cpp
247+
${CMAKE_SOURCE_DIR}/src/impl/bch/protocol_actual.cpp
248+
${CMAKE_SOURCE_DIR}/src/impl/bch/protocol_legacy.cpp
249+
${CMAKE_SOURCE_DIR}/src/impl/bch/stratum/work_source.cpp
241250
)
242251
target_compile_definitions(c2pool-bch PRIVATE C2POOL_VERSION="${C2POOL_GIT_VERSION}")
243252
# --ibd RUN-LOOP slice (integrator 2026-06-18): the read-only headers-first IBD

src/core/factory.hpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include <boost/asio.hpp>
3+
#include <optional>
34

45
#include <core/log.hpp>
56
#include <core/socket.hpp>
@@ -19,7 +20,7 @@ class Server
1920
{
2021
private:
2122
INetwork* m_node;
22-
io::ip::tcp::acceptor m_acceptor;
23+
std::optional<io::ip::tcp::acceptor> m_acceptor;
2324

2425
protected:
2526
void accept()
@@ -30,7 +31,7 @@ class Server
3031
// fall back to raw m_node (preserves prior behavior).
3132
auto weak_node = m_node->weak_from_this();
3233
bool was_managed = weak_node.lock() != nullptr;
33-
m_acceptor.async_accept(
34+
m_acceptor->async_accept(
3435
[this, weak_node, was_managed](boost::system::error_code ec, io::ip::tcp::socket io_socket)
3536
{
3637
if (ec)
@@ -57,32 +58,43 @@ class Server
5758

5859
public:
5960
Server(io::io_context* context, INetwork* node, const std::string& /*label*/ = "")
60-
: m_acceptor(*context), m_node(node)
61+
: m_node(node)
6162
{
63+
// Rig-free / test construction (context == nullptr, e.g. a default-
64+
// constructed BaseNode used for share-admit unit tests) leaves the
65+
// acceptor unengaged so no null io_context is dereferenced. listen()
66+
// is only valid once a real io_context has been wired in.
67+
if (context)
68+
m_acceptor.emplace(*context);
6269
}
6370

6471
void listen(auto listen_port)
6572
{
73+
if (!m_acceptor)
74+
{
75+
LOG_ERROR << "listen() called on a context-less Server";
76+
return;
77+
}
6678
io::ip::tcp::endpoint listen_ep(io::ip::tcp::v4(), listen_port);
6779

68-
m_acceptor.open(listen_ep.protocol());
69-
m_acceptor.set_option(io::socket_base::reuse_address(true));
70-
m_acceptor.bind(listen_ep);
71-
m_acceptor.listen();
80+
m_acceptor->open(listen_ep.protocol());
81+
m_acceptor->set_option(io::socket_base::reuse_address(true));
82+
m_acceptor->bind(listen_ep);
83+
m_acceptor->listen();
7284
accept();
7385

7486
LOG_INFO << "Factory started for port: " << listen_ep.port();
7587
}
7688

77-
uint16_t listen_port() const { return m_acceptor.local_endpoint().port(); }
89+
uint16_t listen_port() const { return m_acceptor->local_endpoint().port(); }
7890
};
7991

8092
class Client
8193
{
8294
private:
8395
INetwork* m_node;
8496
io::io_context* m_context;
85-
io::ip::tcp::resolver m_resolver;
97+
std::optional<io::ip::tcp::resolver> m_resolver;
8698
std::string m_label = "Net"; // chain/protocol label for log messages
8799

88100
void connect_socket(boost::asio::ip::tcp::resolver::results_type endpoints)
@@ -136,7 +148,12 @@ class Client
136148
// only enforce the alive check when there WAS a shared owner to
137149
// begin with.
138150
bool was_managed = weak_node.lock() != nullptr;
139-
m_resolver.async_resolve(addr.address(), addr.port_str(),
151+
if (!m_resolver)
152+
{
153+
LOG_ERROR << "resolve() called on a context-less Client";
154+
return;
155+
}
156+
m_resolver->async_resolve(addr.address(), addr.port_str(),
140157
[this, weak_node, was_managed, addr = addr](const auto& ec, auto endpoints)
141158
{
142159
if (ec)
@@ -160,8 +177,13 @@ class Client
160177

161178
public:
162179
Client(io::io_context* context, INetwork* node, const std::string& label = "Net")
163-
: m_context(context), m_resolver(*context), m_node(node), m_label(label)
180+
: m_node(node), m_context(context), m_label(label)
164181
{
182+
// Rig-free / test construction (context == nullptr) defers the resolver
183+
// so no null io_context is dereferenced; resolve()/connect() are only
184+
// valid once a real io_context has been wired in.
185+
if (context)
186+
m_resolver.emplace(*context);
165187
}
166188

167189
void connect(NetService addr)

src/impl/bch/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
# TODO(M3): add_library(impl_bch ...) sources, link bitcoin_family shared base,
66
# wire embedded BCHN daemon slice under daemon/. Stub only at M2.
77
if(COIN_BCH)
8-
message(STATUS "c2pool: BCH coin module enabled (skeleton)")
9-
# add_subdirectory(coin)
8+
message(STATUS "c2pool: BCH coin module enabled")
9+
add_subdirectory(coin)
10+
add_subdirectory(stratum)
1011
# add_subdirectory(daemon)
1112
add_subdirectory(test)
1213
endif()

src/impl/bch/coin/CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
# bch::coin library — c2pool-bch coin module (V36). Mirrors src/impl/btc/coin.
3+
# Built when -DCOIN_BCH=ON via the parent add_subdirectory(coin).
4+
# BCH-specific: SHA256d (BTC PoW family), NO SegWit, CashTokens transparent,
5+
# ABLA dynamic block-size, ASERT DAA. Embedded BCHN daemon body lives here.
6+
7+
set(bch_coin_impl
8+
rpc_data.hpp
9+
rpc.hpp rpc.cpp
10+
p2p_connection.hpp p2p_connection.cpp
11+
p2p_node.cpp p2p_node.hpp
12+
p2p_messages.hpp
13+
node.hpp
14+
coin_node.hpp coin_node.cpp
15+
)
16+
17+
set(bch_coin_interface
18+
txidcache.hpp
19+
node_interface.hpp
20+
block.hpp
21+
transaction.hpp transaction.cpp
22+
header_chain.hpp
23+
mempool.hpp
24+
template_builder.hpp
25+
)
26+
27+
# BCH-specific consensus + embedded-daemon headers (header-only at this slice).
28+
set(bch_coin_bchn
29+
abla.hpp abla_block_feed.hpp abla_runtime.hpp abla_tracker.hpp
30+
asert.hpp softfork_check.hpp
31+
merkle.hpp cashaddr.hpp regtest_block.hpp
32+
header_sync.hpp block_download.hpp block_connector.hpp
33+
compact_blocks.hpp block_broadcast_guard.hpp
34+
bchn_anchor_record.hpp chain_seeds.hpp
35+
embedded_daemon.hpp
36+
)
37+
38+
add_library(bch_coin ${bch_coin_interface} ${bch_coin_impl} ${bch_coin_bchn})
39+
40+
target_link_libraries(bch_coin core nlohmann_json::nlohmann_json)

src/impl/bch/coin/embedded_daemon.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class EmbeddedDaemon {
100100
/// EmbeddedCoinNode::getwork() is the live in-process work source.
101101
void run() {
102102
m_chain.init(); // load genesis / fast-start checkpoint (network-free)
103-
m_node.run(); // init_rpc(): external BCHN-RPC fallback retained
103+
m_node.run(/*embedded_primary=*/true); // init_rpc(): eager external GBT non-fatal (embedded-primary); RPC fallback retained
104104
assemble(); // network-free seam + ABLA wiring (see below)
105105
wire_chain_ingest(); // new_headers --> HeaderChain (advances synced height)
106106
pin_cold_start_anchor(); // operator-APPROVED VM300 anchor (decisions@ 2026-06-18); floor-equivalent

src/impl/bch/coin/node.hpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,30 @@ class Node : public bch::interfaces::Node
5555
m_p2p->connect(m_config->coin()->m_p2p.address);
5656
}
5757

58-
void init_rpc()
58+
// embedded_primary: when the in-process embedded daemon is the PRIMARY work
59+
// source (v36 external_fallback invariant), a dead / 0-peer external BCHN that
60+
// cannot yet answer getblocktemplate must NOT abort bring-up -- the embedded
61+
// source provides work and the external RPC is only the fallback sink. When the
62+
// external RPC IS the work source (embedded_primary == false), a failure here
63+
// stays fatal exactly as before.
64+
void init_rpc(bool embedded_primary)
5965
{
6066
m_rpc = std::make_unique<NodeRPC>(m_context, this, m_config->m_testnet);
6167
m_rpc->connect(m_config->m_rpc.address, m_config->m_rpc.userpass);
6268

63-
// work
64-
work.set(m_rpc->getwork());
69+
// work (eager prime from external RPC)
70+
if (embedded_primary) {
71+
try {
72+
work.set(m_rpc->getwork());
73+
} catch (const std::exception& e) {
74+
LOG_WARNING << "[EMB-BCH] init_rpc: external BCHN getwork() unavailable"
75+
" at bring-up (" << e.what() << "); embedded-primary ->"
76+
" deferring to embedded work source, RPC retained as"
77+
" fallback sink.";
78+
}
79+
} else {
80+
work.set(m_rpc->getwork());
81+
}
6582
}
6683

6784
public:
@@ -70,10 +87,12 @@ class Node : public bch::interfaces::Node
7087
{
7188
}
7289

73-
void run()
90+
// embedded_primary defaults false: an external-RPC-as-work-source config still
91+
// hard-fails on a dead RPC at bring-up. The embedded daemon passes true.
92+
void run(bool embedded_primary = false)
7493
{
7594
// RPC
76-
init_rpc();
95+
init_rpc(embedded_primary);
7796
}
7897

7998
/// Start P2P connection to coin daemon for fast block relay.

0 commit comments

Comments
 (0)