From d7f96943e292981912e1e55feff06cf3384b9ef7 Mon Sep 17 00:00:00 2001 From: frstrtr Date: Sat, 4 Jul 2026 01:17:41 +0000 Subject: [PATCH 1/2] =?UTF-8?q?test(dash-s8):=20mining.submit=20reassembly?= =?UTF-8?q?=20KAT=20=E2=80=94=20close=20subscribe=E2=86=92notify=E2=86=92s?= =?UTF-8?q?ubmit=20triangle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bind the REAL landed producers split_coinb() + merkle_branches_raw() to prove a miner submit (extranonce2, ntime, nonce) reconstructs the EXACT 80-byte block header whose sha256d is the share hash. Reassembled coinbase cross-checks the Python sha256d anchors; extranonce2/ntime/nonce each shown to bind injectively into the share. Fenced test/ + build.yml only, non-consensus, socket/node-free. --- .github/workflows/build.yml | 3 +- test/CMakeLists.txt | 9 + test/test_dash_stratum_submit_reassembly.cpp | 276 +++++++++++++++++++ 3 files changed, 286 insertions(+), 2 deletions(-) create mode 100644 test/test_dash_stratum_submit_reassembly.cpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70461ab1..76c87b3d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,8 +102,7 @@ jobs: core_test sharechain_test share_test btc_share_test \ test_threading test_weights \ test_header_chain test_mempool test_template_builder \ - 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_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_multiaddress_pplns test_pplns_stress \ test_hash_link test_decay_pplns \ test_pplns_consensus \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 154ff40d..dbca4a9d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -738,6 +738,15 @@ if (BUILD_TESTING AND GTest_FOUND) ) target_link_libraries(test_dash_stratum_extranonce_split PRIVATE c2pool_payout c2pool_hashrate c2pool_merged_mining) # OBJECT-lib SCC direct-naming (#22/#39) gtest_add_tests(test_dash_stratum_extranonce_split "" AUTO) + add_executable(test_dash_stratum_submit_reassembly test_dash_stratum_submit_reassembly.cpp) + target_link_libraries(test_dash_stratum_submit_reassembly PRIVATE + GTest::gtest_main GTest::gtest + dash_x11 core + nlohmann_json::nlohmann_json + ${Boost_LIBRARIES} + ) + target_link_libraries(test_dash_stratum_submit_reassembly PRIVATE c2pool_payout c2pool_hashrate c2pool_merged_mining) # OBJECT-lib SCC direct-naming (#22/#39) + gtest_add_tests(test_dash_stratum_submit_reassembly "" AUTO) add_executable(test_compact_blocks test_compact_blocks.cpp) target_link_libraries(test_compact_blocks PRIVATE diff --git a/test/test_dash_stratum_submit_reassembly.cpp b/test/test_dash_stratum_submit_reassembly.cpp new file mode 100644 index 00000000..f2a66ac8 --- /dev/null +++ b/test/test_dash_stratum_submit_reassembly.cpp @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: MIT +// +// DASH S8 stratum mining.submit reassembly contract KAT. +// +// Closes the subscribe -> notify -> submit triangle. The prior leaves pinned +// two of the three sides: +// * #630 test_dash_stratum_binding -- get_work extranonce2 slot geometry +// * #631 test_dash_stratum_notify_roundtrip -- notify merkle_branch fold -> merkle_root +// * #633 test_dash_stratum_extranonce_split -- subscribe coinb1/coinb2 split +// The OPEN side is submit: given a miner's (extranonce2, ntime, nonce), the +// server must reconstruct the EXACT block header whose sha256d IS the share +// hash. This leaf proves that reconstruction end-to-end: +// +// mining.submit [extranonce2, ntime, nonce] +// -> reassemble coinb1 || extranonce2 || coinb2 (REAL split_coinb) +// -> sha256d -> coinbase txid (== #631/#633 golden) +// -> fold notify merkle_branch (index 0) (REAL merkle_branches_raw) +// -> header merkle_root +// -> assemble 80B header [version|prev|root|ntime|nbits|nonce] +// -> sha256d -> the share/header hash +// +// It binds the REAL landed producers dash::coinbase::split_coinb() and +// dash::coinbase::merkle_branches_raw() (src/impl/dash/coinbase_builder.hpp) -- +// the exact code mining.subscribe/mining.notify ship -- and mirrors the +// miner-side reassembly + fold + header assembly locally (the miner is +// cpuminer, not our code; handle_submit's compute_share_difficulty walks the +// identical reconstruction, src/core/stratum_server.cpp:877). +// +// The reconstructed coinbase is cross-checked byte-for-byte against the #631 / +// #633 golden coinbase hashes, and the header hash is pinned to independent +// Python hashlib sha256d anchors (NOT the oracle code, NOT this code) -- so the +// submit reconstruction agrees with the subscribe/notify producers on the +// coinbase, and the header hash is non-circular. extranonce2, ntime, and nonce +// are each shown to bind injectively into the header hash -- i.e. all three +// miner-supplied submit fields are load-bearing in the share the pool verifies. +// +// Oracle (frstrtr/p2pool-dash @9a0a609): +// p2pool/work.py:474 header['merkle_root'] == check_merkle_link(hash256(gentx), link) +// p2pool/dash/data.py block_header_type: version|prev|merkle_root|timestamp|bits|nonce +// p2pool/dash/stratum.py rpc_submit [worker, job_id, extranonce2, ntime, nonce] +// +// Fenced: test/ + build.yml allowlist only. Non-consensus, socket-free, +// node-free -- pure synthetic CoinbaseLayout, no live node / RPC / P2P. + +#include + +#include +#include +#include +#include +#include +#include + +#include // CoinbaseLayout, split_coinb, merkle_branches_raw, sha256d, EXTRANONCE2_SIZE +#include // HexStr, ParseHex +#include + +using dash::coinbase::CoinbaseLayout; +using dash::coinbase::CoinbSplit; +using dash::coinbase::split_coinb; +using dash::coinbase::merkle_branches_raw; +using dash::coinbase::sha256d; +using dash::coinbase::EXTRANONCE2_SIZE; + +namespace { + +// ── Coinbase fixture (identical to #630/#631/#633) ─────────────────────────── +// 40-byte synthetic coinbase: bytes[i] = i, with the 8-byte nonce64 +// (extranonce2) slot at [28,36). nonce64_offset = 40 - locktime(4) - nonce64(8). +constexpr size_t kTotal = 40; +constexpr size_t kNonceOffset = 28; + +CoinbaseLayout make_layout() { + CoinbaseLayout lay; + lay.bytes.resize(kTotal); + for (size_t i = 0; i < kTotal; ++i) lay.bytes[i] = static_cast(i); + for (size_t i = kNonceOffset; i < kNonceOffset + EXTRANONCE2_SIZE; ++i) lay.bytes[i] = 0; + lay.ref_hash_offset = kNonceOffset - 32; + lay.nonce64_offset = kNonceOffset; + return lay; +} + +// Miner-side reassembly: coinb1 || extranonce2 || coinb2 (mirror of cpuminer). +std::vector reassemble(const CoinbSplit& s, std::span e2) { + std::vector b1 = ParseHex(s.coinb1_hex); + std::vector b2 = ParseHex(s.coinb2_hex); + std::vector out; + out.reserve(b1.size() + e2.size() + b2.size()); + out.insert(out.end(), b1.begin(), b1.end()); + out.insert(out.end(), e2.begin(), e2.end()); + out.insert(out.end(), b2.begin(), b2.end()); + return out; +} + +uint256 coinbase_hash(const CoinbSplit& s, std::span e2) { + auto cb = reassemble(s, e2); + return sha256d(std::span(cb.data(), cb.size())); +} + +uint256 fill_hash(unsigned char b) { return uint256(std::vector(32, b)); } + +// Four-leaf tx set: coinbase placeholder at [0] + three sibling tx hashes +// (identical to #631, so the merkle_branch is the exact one mining.notify ships). +std::vector leaves_with(const uint256& cb) { + return { cb, fill_hash(0x11), fill_hash(0x22), fill_hash(0x33) }; +} + +// sha256d(left || right), 32B internal LE each -- mirrors merkle_record_type.pack. +uint256 node_hash(const uint256& l, const uint256& r) { + std::vector buf(64); + auto lc = l.GetChars(); + auto rc = r.GetChars(); + std::memcpy(buf.data(), lc.data(), 32); + std::memcpy(buf.data() + 32, rc.data(), 32); + return sha256d(std::span(buf.data(), buf.size())); +} + +// Miner-side fold for coinbase leaf index 0: running hash always on the LEFT. +uint256 fold_index0(const uint256& tip, const std::vector& branch) { + uint256 cur = tip; + for (const auto& sib : branch) cur = node_hash(cur, sib); + return cur; +} + +// ── 80-byte block-header fields (synthetic) ────────────────────────────────── +constexpr uint32_t VERSION = 0x20000000u; +constexpr uint32_t NBITS = 0x1a0ffff0u; +constexpr uint32_t NTIME = 0x6512a3f4u; +constexpr uint32_t NTIME2 = 0x6512a400u; // distinct ntime (binding guard) +constexpr uint32_t NONCE = 0x0000abcdu; +constexpr uint32_t NONCE2 = 0x0000abceu; // distinct nonce (binding guard) +const char* PREV_DISPLAY = + "00000000000000000000000000000000000000000000000000000000deadbeef"; + +void put_le32(std::vector& b, uint32_t v) { + b.push_back(static_cast( v & 0xff)); + b.push_back(static_cast((v >> 8) & 0xff)); + b.push_back(static_cast((v >> 16) & 0xff)); + b.push_back(static_cast((v >> 24) & 0xff)); +} + +// Assemble the canonical 80-byte header and return its sha256d (the share hash). +// Layout: version(4 LE) | prev(32 internal LE) | merkle_root(32 internal LE) | +// ntime(4 LE) | nbits(4 LE) | nonce(4 LE). +uint256 header_hash(const uint256& merkle_root, uint32_t ntime, uint32_t nonce) { + std::vector h; + h.reserve(80); + put_le32(h, VERSION); + auto prev = uint256S(PREV_DISPLAY).GetChars(); // display -> internal LE + h.insert(h.end(), prev.begin(), prev.end()); + auto root = merkle_root.GetChars(); + h.insert(h.end(), root.begin(), root.end()); + put_le32(h, ntime); + put_le32(h, NBITS); + put_le32(h, nonce); + EXPECT_EQ(h.size(), 80u); + return sha256d(std::span(h.data(), h.size())); +} + +// Full reconstruction from a miner submit: (extranonce2, ntime, nonce) -> share. +uint256 reconstruct_share(const CoinbSplit& s, std::span e2, + uint32_t ntime, uint32_t nonce) { + uint256 cb = coinbase_hash(s, e2); + auto branch = merkle_branches_raw(leaves_with(cb)); + uint256 root = fold_index0(cb, branch); + return header_hash(root, ntime, nonce); +} + +const std::vector E2_ZERO(8, 0x00); +const std::vector E2_A{0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8}; +const std::vector E2_B{0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8}; + +// Cross-bind anchors: coinbase hashes identical to #631/#633 (independent Python). +const char* GOLD_CBHASH_Z = "b0d22de8e7f6765f9d8c289ecd77ad8e0ab6a88c2a4ccf594c509d7775bb54ab"; +const char* GOLD_CBHASH_A = "22a146527ac0731341d026480042a55cee0bdb804043b570af24feb9e76f2c8b"; +const char* GOLD_CBHASH_B = "04c8f4793537be307eaa2166642accc8265add0a59ccf4d01525f0ec54c6237a"; + +// Merkle roots identical to #631 GOLD_ROOT_* (the notify leaf ships this branch). +const char* GOLD_ROOT_Z = "26f79b540fe6f2ac6fc52f37e5af5b33a61f33216bc4ec394635b24235850ea0"; +const char* GOLD_ROOT_A = "4b2d0948edb39954294fd28ca3926a78f0e56990c69d4fd7530a80a40491198e"; +const char* GOLD_ROOT_B = "72f7c45d5d6c65fd77053fec86d20d918681b92aba88c87f5aaa5bf7ab3a8230"; + +// 80-byte header-hash anchors (independent Python hashlib sha256d; display form). +const char* GOLD_HDR_Z = "fee1d073bb4d6329a1dcc557806bde0856353ed9cc564278fb64e7c786174fe8"; +const char* GOLD_HDR_A = "6549fd53a623d482003f58bd9b309b97b86f749c6b0480eb3c74ab29fbc7058b"; +const char* GOLD_HDR_B = "1652fb9178ae66f2edb802bf9b7c3c316e2f80b1dc4bcd21cfc07386bde33742"; +const char* GOLD_HDR_NTIME2 = "8dcaed61b0b47c637316436355030b3927f98042d35bc31784e5fd81a15d2495"; +const char* GOLD_HDR_NONCE2 = "ebc6423bb7454bd964bd07e06fab55c4dad5af62be9f26949d3c39edcd5f0563"; + +} // namespace + +// (1) Submit reconstructs the golden coinbase: reassembling coinb1 (from the +// REAL split_coinb producer) || extranonce2 || coinb2 and sha256d'ing it +// reproduces the EXACT coinbase hash the notify/split leaves golden-anchor +// -- the submit path agrees with subscribe/notify byte-for-byte. +TEST(DashStratumSubmitReassembly, SubmitReconstructsGoldenCoinbase) { + CoinbSplit s = split_coinb(make_layout()); + EXPECT_EQ(coinbase_hash(s, E2_ZERO).GetHex(), GOLD_CBHASH_Z); + EXPECT_EQ(coinbase_hash(s, E2_A).GetHex(), GOLD_CBHASH_A); + EXPECT_EQ(coinbase_hash(s, E2_B).GetHex(), GOLD_CBHASH_B); +} + +// (2) Reconstructed merkle_root matches the #631 notify leaf: folding the REAL +// mining.notify branch over the reassembled coinbase reproduces the exact +// header merkle_root the notify round-trip pins. +TEST(DashStratumSubmitReassembly, ReconstructedRootMatchesNotifyLeaf) { + CoinbSplit s = split_coinb(make_layout()); + for (auto [e2, gold] : std::vector, const char*>>{ + {E2_ZERO, GOLD_ROOT_Z}, {E2_A, GOLD_ROOT_A}, {E2_B, GOLD_ROOT_B}}) { + uint256 cb = coinbase_hash(s, e2); + auto br = merkle_branches_raw(leaves_with(cb)); + EXPECT_EQ(fold_index0(cb, br).GetHex(), gold); + } +} + +// (3) THE closing assertion: the full submit reconstruction -- (extranonce2, +// ntime, nonce) -> reassembled coinbase -> folded merkle_root -> 80B header +// -> sha256d -- yields the exact share hash pinned by an independent Python +// golden. The subscribe->notify->submit triangle is closed. +TEST(DashStratumSubmitReassembly, ReconstructedHeaderHashesToShare) { + CoinbSplit s = split_coinb(make_layout()); + EXPECT_EQ(reconstruct_share(s, E2_ZERO, NTIME, NONCE).GetHex(), GOLD_HDR_Z); +} + +// (4) extranonce2 binds into the share: distinct extranonce2 -> distinct header +// hash, each equal to its independent golden. The miner's nonce64 slot +// propagates all the way into the share the pool verifies. +TEST(DashStratumSubmitReassembly, Extranonce2BindsIntoShareHash) { + CoinbSplit s = split_coinb(make_layout()); + uint256 z = reconstruct_share(s, E2_ZERO, NTIME, NONCE); + uint256 a = reconstruct_share(s, E2_A, NTIME, NONCE); + uint256 b = reconstruct_share(s, E2_B, NTIME, NONCE); + EXPECT_EQ(a.GetHex(), GOLD_HDR_A); + EXPECT_EQ(b.GetHex(), GOLD_HDR_B); + EXPECT_NE(z, a); + EXPECT_NE(z, b); + EXPECT_NE(a, b); +} + +// (5) ntime binds into the share: same extranonce2/nonce, distinct ntime -> +// distinct header hash. ntime is a load-bearing submit field, not decor. +TEST(DashStratumSubmitReassembly, NtimeBindsIntoShareHash) { + CoinbSplit s = split_coinb(make_layout()); + uint256 base = reconstruct_share(s, E2_ZERO, NTIME, NONCE); + uint256 alt = reconstruct_share(s, E2_ZERO, NTIME2, NONCE); + EXPECT_EQ(base.GetHex(), GOLD_HDR_Z); + EXPECT_EQ(alt.GetHex(), GOLD_HDR_NTIME2); + EXPECT_NE(base, alt); +} + +// (6) nonce binds into the share: same extranonce2/ntime, distinct nonce -> +// distinct header hash. The header nonce field is placed correctly. +TEST(DashStratumSubmitReassembly, NonceBindsIntoShareHash) { + CoinbSplit s = split_coinb(make_layout()); + uint256 base = reconstruct_share(s, E2_ZERO, NTIME, NONCE); + uint256 alt = reconstruct_share(s, E2_ZERO, NTIME, NONCE2); + EXPECT_EQ(base.GetHex(), GOLD_HDR_Z); + EXPECT_EQ(alt.GetHex(), GOLD_HDR_NONCE2); + EXPECT_NE(base, alt); +} + +// (7) Golden byte-parity anchors (independent Python sha256d, computed outside +// both the oracle and this code) for coinbase, merkle_root, and header hash. +TEST(DashStratumSubmitReassembly, GoldenAnchors) { + CoinbSplit s = split_coinb(make_layout()); + // coinbase (cross-bind to #631/#633) + EXPECT_EQ(coinbase_hash(s, E2_ZERO).GetHex(), GOLD_CBHASH_Z); + EXPECT_EQ(coinbase_hash(s, E2_A).GetHex(), GOLD_CBHASH_A); + EXPECT_EQ(coinbase_hash(s, E2_B).GetHex(), GOLD_CBHASH_B); + // header shares + EXPECT_EQ(reconstruct_share(s, E2_ZERO, NTIME, NONCE ).GetHex(), GOLD_HDR_Z); + EXPECT_EQ(reconstruct_share(s, E2_A, NTIME, NONCE ).GetHex(), GOLD_HDR_A); + EXPECT_EQ(reconstruct_share(s, E2_B, NTIME, NONCE ).GetHex(), GOLD_HDR_B); + EXPECT_EQ(reconstruct_share(s, E2_ZERO, NTIME2, NONCE ).GetHex(), GOLD_HDR_NTIME2); + EXPECT_EQ(reconstruct_share(s, E2_ZERO, NTIME, NONCE2).GetHex(), GOLD_HDR_NONCE2); +} From 9dddc71aec7192e59ce6a75ad0f49cafc62d6104 Mon Sep 17 00:00:00 2001 From: frstrtr Date: Sat, 4 Jul 2026 21:17:24 +0000 Subject: [PATCH 2/2] ci(dash): add test_dash_stratum_submit_reassembly to ASan/UBSan target allowlist The second (-fsanitize=address,undefined) --target allowlist in build.yml omitted test_dash_stratum_submit_reassembly, so the ASan job never built the binary while ctest still had the 7 DashStratumSubmitReassembly cases registered from configure -> reported (Not Run) -> exit 8 -> RED. The non-ASan Linux/macOS/Windows builds pass because their allowlist (line 105) already includes it. Build-glue only; no source or sanitizer semantics change. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 76c87b3d..63b0a02b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -252,7 +252,7 @@ jobs: test_threading test_weights \ test_header_chain test_mempool test_template_builder \ 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_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_hash_link test_decay_pplns \ test_pplns_consensus \ test_v36_script_sorting test_v36_cross_impl_refhash \