Skip to content

Commit ef4e5ce

Browse files
committed
dgb: DGB+DOGE phase-DC dual-target SELECTION scaffold (fenced KAT)
Pure, header-only DC decision contract the eventual DC run-loop wiring (AUX_DOGE node seam + submit) must satisfy, landed BEFORE the seam is touched (seam parked on #82 + ltc-doge written concurrence). coin/aux_dual_target_select.hpp: - aux_mint_decision(aux_enabled, has_doge_job): embed the fabe6d6d MM commitment IFF aux MM enabled AND a DOGE job is present; else no-op (mirrors #486 embed-at-mint nullopt byte-identity). - select_submit(pow, dgb_target, has_doge_job, doge_target): independent per-path thresholds against one scrypt pow_hash (mirrors dc_proof DualTargetIndependentThresholds); DOGE-aux only fires when minted. - selection_is_consistent(): load-bearing DC<->DB guard, fire_doge_aux ==> embed_commitment, coupling submit back to #475/#486. test/aux_dual_target_select_test.cpp: 5/5 KATs, non-circular goldens (fabe6d6d tag, embed truth table, independent threshold table, no-job suppression, the impossible DOGE-win-without-mint state). Registered in test/CMakeLists.txt + both build.yml --target allowlists (#143 trap). Fenced dgb/, not rewired, consumes nothing in src/impl/doge, no node seam touch, zero consensus surface.
1 parent b22daa7 commit ef4e5ce

4 files changed

Lines changed: 197 additions & 2 deletions

File tree

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
test_address_resolution test_compute_share_target \
8383
test_utxo test_dgb_subsidy test_dgb_coinbase_value dgb_share_test dgb_redistribute_test dgb_block_assembly_test dgb_witness_commitment_test dgb_header_sample_build_test dgb_header_ingest_test dgb_mempool_ingest_test \
8484
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 \
85-
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_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test \
85+
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_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test dgb_aux_dual_target_select_test \
8686
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
8787
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_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_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 v37_test \
8888
-j$(nproc)
@@ -214,7 +214,7 @@ jobs:
214214
test_address_resolution test_compute_share_target \
215215
test_utxo test_dgb_subsidy test_dgb_coinbase_value dgb_share_test dgb_redistribute_test dgb_block_assembly_test dgb_witness_commitment_test dgb_header_sample_build_test dgb_header_ingest_test dgb_mempool_ingest_test \
216216
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 \
217-
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_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test \
217+
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_dc_proof_test dgb_aux_doge_bind_parsers_test dgb_compact_blocks_bip152_parity_test dgb_aux_dual_target_select_test \
218218
rpc_request_test softfork_check_test genesis_check_test algo_select_test digishield_walk_test header_chain_test \
219219
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_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_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 test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
220220
v37_test \
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#pragma once
2+
// ---------------------------------------------------------------------------
3+
// DGB+DOGE merged-mining (phase DC) — dual-target SELECTION scaffold.
4+
//
5+
// Pure, header-only, fenced. NOT wired into any production path (no run-loop,
6+
// no node seam, no share-tracker touch) — it pins the load-bearing DC decision
7+
// contract that the eventual DC wiring (node.hpp:57 AUX_DOGE bind + submit) must
8+
// satisfy, BEFORE that seam is touched (seam is parked on #82 + ltc-doge
9+
// concurrence). Zero consensus surface; the DGB-parent consensus path is
10+
// unchanged whether or not these helpers are ever consumed.
11+
//
12+
// Two independent decisions:
13+
//
14+
// MINT-TIME (mirrors #486 embed-at-mint): the DGB parent coinbase embeds the
15+
// fabe6d6d merged-mining commitment (built by #475) IFF aux MM is enabled
16+
// AND a DOGE work job is present. Otherwise no embed -> byte-identical
17+
// no-op coinbase (the #486 nullopt invariant).
18+
//
19+
// SUBMIT-TIME: the DGB-parent target and the DOGE-aux target are INDEPENDENT
20+
// thresholds against the SAME scrypt pow_hash (pow <= target == hit;
21+
// mirrors aux_doge_dc_proof_test DualTargetIndependentThresholds). The
22+
// DOGE-aux path is only a candidate when a DOGE job was minted in.
23+
//
24+
// LOAD-BEARING LINKAGE (DC<->DB): a DOGE-aux win can only be assembled when the
25+
// fabe6d6d commitment was minted — so fire_doge_aux ==> embed_commitment. This
26+
// guard is what couples submit-time selection back to the #475/#486 mint.
27+
// ---------------------------------------------------------------------------
28+
29+
#include <core/uint256.hpp>
30+
31+
namespace dgb
32+
{
33+
namespace coin
34+
{
35+
36+
// fabe6d6d merged-mining commitment tag — the magic prefix #475 prepends to the
37+
// 44-byte MM commitment (fa be 6d 6d || root32BE || size4LE || nonce4LE). Pinned
38+
// here as the non-circular mint anchor; the DC wiring builds the real record.
39+
inline constexpr unsigned char MM_COMMITMENT_TAG[4] = {0xfa, 0xbe, 0x6d, 0x6d};
40+
41+
// MINT-TIME embed decision (#486). embed_commitment is true IFF aux MM is
42+
// enabled and a DOGE work job is present; false -> nullopt / no-op coinbase.
43+
struct AuxMintDecision
44+
{
45+
bool embed_commitment;
46+
};
47+
48+
inline AuxMintDecision aux_mint_decision(bool aux_enabled, bool has_doge_job)
49+
{
50+
return AuxMintDecision{aux_enabled && has_doge_job};
51+
}
52+
53+
// SUBMIT-TIME dual-target fire decision. Independent per-path thresholds against
54+
// one scrypt pow_hash. DOGE-aux only fires when a DOGE job was minted in.
55+
struct DualTargetFire
56+
{
57+
bool fire_dgb_parent;
58+
bool fire_doge_aux;
59+
};
60+
61+
inline DualTargetFire select_submit(const uint256& pow_hash,
62+
const uint256& dgb_target,
63+
bool has_doge_job,
64+
const uint256& doge_target)
65+
{
66+
const bool dgb_hit = !(pow_hash > dgb_target);
67+
const bool doge_hit = has_doge_job && !(pow_hash > doge_target);
68+
return DualTargetFire{dgb_hit, doge_hit};
69+
}
70+
71+
// LOAD-BEARING DC<->DB linkage: a DOGE-aux win is only assemblable when the
72+
// fabe6d6d commitment was minted. fire_doge_aux ==> embed_commitment.
73+
inline bool selection_is_consistent(const AuxMintDecision& mint,
74+
const DualTargetFire& fire)
75+
{
76+
return !fire.fire_doge_aux || mint.embed_commitment;
77+
}
78+
79+
} // namespace coin
80+
} // namespace dgb

src/impl/dgb/test/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,22 @@ if (BUILD_TESTING AND GTest_FOUND)
603603
dgb_coin pool sharechain)
604604
gtest_add_tests(dgb_aux_doge_bind_parsers_test "" AUTO)
605605

606+
# --- DGB+DOGE (phase DC) -- dual-target SELECTION scaffold KAT ------------
607+
# Pins the pure DC decision contract (coin/aux_dual_target_select.hpp): the
608+
# mint-time fabe6d6d embed rule (#486 nullopt no-op), the independent dual-
609+
# target submit thresholds (mirrors dc_proof), and the load-bearing
610+
# fire_doge_aux ==> embed_commitment linkage back to the #475/#486 mint.
611+
# Pure helpers, consumes nothing in src/impl/doge and touches no node
612+
# seam. MUST appear in BOTH this registration AND the
613+
# build.yml --target allowlist (#143 NOT_BUILT trap).
614+
add_executable(dgb_aux_dual_target_select_test aux_dual_target_select_test.cpp)
615+
target_link_libraries(dgb_aux_dual_target_select_test PRIVATE
616+
GTest::gtest_main GTest::gtest
617+
core dgb
618+
c2pool_payout c2pool_merged_mining c2pool_hashrate c2pool_storage
619+
dgb_coin pool sharechain)
620+
gtest_add_tests(dgb_aux_dual_target_select_test "" AUTO)
621+
606622
# dgb_share_target_genesis_test: FENCED KAT pinning ShareTracker::compute_
607623
# share_target genesis/unknown-prev clamp to [MAX_TARGET/30, MAX_TARGET] vs
608624
# the DGB oracle data.py generate_transaction. Links the same proven set as
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// ---------------------------------------------------------------------------
2+
// DGB+DOGE (phase DC) — dual-target SELECTION scaffold KAT.
3+
//
4+
// Fenced / test-only. Pins the pure DC decision contract (coin/aux_dual_target_
5+
// select.hpp) the eventual DC wiring must satisfy, BEFORE the AUX_DOGE node seam
6+
// is touched. Non-circular: every golden is restated by value (the fabe6d6d tag,
7+
// the embed-when-aux+job rule, the independent threshold table, the no-op
8+
// invariant) — it mirrors #475 (fabe6d6d builder) / #486 (embed-at-mint nullopt
9+
// no-op) without including their (not-yet-landed) headers, so it cannot drift
10+
// against them and stands alone on master.
11+
//
12+
// Pure helpers, links only core (uint256). Consumes nothing in src/impl/doge.
13+
// MUST appear in BOTH test/CMakeLists.txt AND the build.yml --target allowlist
14+
// or it becomes a NOT_BUILT sentinel that reds master (#143 trap).
15+
// ---------------------------------------------------------------------------
16+
17+
#include <gtest/gtest.h>
18+
19+
#include <impl/dgb/coin/aux_dual_target_select.hpp>
20+
#include <core/uint256.hpp>
21+
22+
using dgb::coin::aux_mint_decision;
23+
using dgb::coin::select_submit;
24+
using dgb::coin::selection_is_consistent;
25+
using dgb::coin::MM_COMMITMENT_TAG;
26+
27+
// 1) fabe6d6d mint anchor (#475). Non-circular literal golden — the tag the
28+
// real MM-commitment builder prepends. Guards against a silent tag reshape.
29+
TEST(DGB_AuxDualTargetSelect, MmCommitmentTagIsFabe6d6d) {
30+
EXPECT_EQ(MM_COMMITMENT_TAG[0], 0xfa);
31+
EXPECT_EQ(MM_COMMITMENT_TAG[1], 0xbe);
32+
EXPECT_EQ(MM_COMMITMENT_TAG[2], 0x6d);
33+
EXPECT_EQ(MM_COMMITMENT_TAG[3], 0x6d);
34+
}
35+
36+
// 2) MINT-TIME embed truth table (#486). Embed IFF aux enabled AND DOGE job.
37+
// The three non-embed corners are the byte-identical no-op (#486 nullopt).
38+
TEST(DGB_AuxDualTargetSelect, MintEmbedsOnlyWhenAuxEnabledAndDogeJob) {
39+
EXPECT_TRUE (aux_mint_decision(/*aux*/true, /*job*/true ).embed_commitment);
40+
EXPECT_FALSE(aux_mint_decision(/*aux*/true, /*job*/false).embed_commitment);
41+
EXPECT_FALSE(aux_mint_decision(/*aux*/false, /*job*/true ).embed_commitment);
42+
EXPECT_FALSE(aux_mint_decision(/*aux*/false, /*job*/false).embed_commitment);
43+
}
44+
45+
// 3) SUBMIT-TIME independent thresholds — same pow_hash, two independent targets
46+
// (mirrors dc_proof DualTargetIndependentThresholds). DGB-parent is the
47+
// harder (smaller) target; DOGE-aux is easier (larger).
48+
TEST(DGB_AuxDualTargetSelect, SubmitFiresIndependentThresholds) {
49+
const uint256 DGB_TARGET = uint256S("0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff");
50+
const uint256 DOGE_TARGET = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
51+
52+
const uint256 below_both = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
53+
const uint256 doge_only = uint256S("000000000affffffffffffffffffffffffffffffffffffffffffffffffffffff");
54+
const uint256 above_both = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
55+
56+
// below both -> both paths fire
57+
auto a = select_submit(below_both, DGB_TARGET, /*job*/true, DOGE_TARGET);
58+
EXPECT_TRUE(a.fire_dgb_parent);
59+
EXPECT_TRUE(a.fire_doge_aux);
60+
61+
// between -> DOGE-aux fires, DGB-parent does NOT (the common case)
62+
auto b = select_submit(doge_only, DGB_TARGET, /*job*/true, DOGE_TARGET);
63+
EXPECT_FALSE(b.fire_dgb_parent);
64+
EXPECT_TRUE (b.fire_doge_aux);
65+
66+
// above both -> neither fires
67+
auto c = select_submit(above_both, DGB_TARGET, /*job*/true, DOGE_TARGET);
68+
EXPECT_FALSE(c.fire_dgb_parent);
69+
EXPECT_FALSE(c.fire_doge_aux);
70+
}
71+
72+
// 4) No DOGE job suppresses the DOGE-aux path even on a target hit, and leaves
73+
// the DGB-parent path untouched (standalone-parent default build behaviour).
74+
TEST(DGB_AuxDualTargetSelect, NoDogeJobSuppressesAuxPathOnly) {
75+
const uint256 DGB_TARGET = uint256S("0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff");
76+
const uint256 DOGE_TARGET = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
77+
const uint256 below_both = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
78+
79+
auto f = select_submit(below_both, DGB_TARGET, /*job*/false, DOGE_TARGET);
80+
EXPECT_TRUE (f.fire_dgb_parent); // parent path independent of aux
81+
EXPECT_FALSE(f.fire_doge_aux); // no job minted -> no aux win
82+
}
83+
84+
// 5) LOAD-BEARING DC<->DB linkage: fire_doge_aux ==> embed_commitment. A DOGE
85+
// win without a minted commitment is the impossible state the guard rejects.
86+
TEST(DGB_AuxDualTargetSelect, DogeWinRequiresMintedCommitment) {
87+
// reachable: aux on + job -> minted -> a DOGE fire is consistent
88+
EXPECT_TRUE(selection_is_consistent(
89+
aux_mint_decision(true, true),
90+
dgb::coin::DualTargetFire{true, true}));
91+
// reachable: no DOGE fire is always consistent regardless of mint
92+
EXPECT_TRUE(selection_is_consistent(
93+
aux_mint_decision(false, false),
94+
dgb::coin::DualTargetFire{true, false}));
95+
// impossible: DOGE fire without a minted commitment -> guard rejects
96+
EXPECT_FALSE(selection_is_consistent(
97+
aux_mint_decision(false, true),
98+
dgb::coin::DualTargetFire{false, true}));
99+
}

0 commit comments

Comments
 (0)