Skip to content

Commit 5ac007e

Browse files
authored
dgb(D0.5): AUX_DOGE consensus-isolation guard (compile-time + link-time) (#589)
* dgb(D0.5): compile-time per-coin consensus-isolation guard for AUX_DOGE seam Freeze the DGB-as-parent isolation invariant into a compile-time check. The -DAUX_DOGE=ON build links ltc_coin (substrate path (a)) for Bitcoin-wire-generic value/serialization types only; the LTC consensus surface (HeaderChain, make_ltc_chain_params_mainnet/testnet, scrypt pow, Art-Forz retarget) stays present-but-dead at link and must never reach the DGB-parent live call path. - aux_doge_isolation_guard.hpp: assert the DGB-parent witness-strip trait resolves to dgb::coin::TxParams (DGB's own consensus params), not bitcoin_family's default that LTC/DASH inherit, and that the DGB parent coinbase type is distinct from ltc::coin's. - node.hpp: assert AuxDogeParse carries CAuxPow<dgb::coin::MutableTransaction> (DGB-parent-pinned), enforced in the production dgb object library, never the shared module's ltc default. Link-time half (CMake POST_BUILD nm -C negative-symbol check on c2pool-dgb) staged as fast-follow; it needs an AUX_DOGE build slot to validate the demangled-symbol grep. * dgb(D0.5): link-time AUX_DOGE consensus-isolation guard Link-level companion to the compile-time aux_doge_isolation_guard.hpp. nm -C negative-symbol check on the AUX_DOGE c2pool-dgb binary: hard-fail if the DGB parent ODR-uses any LTC per-coin consensus symbol (make_ltc_chain_params / ltc::coin::HeaderChain / ltc::coin::ChainParams), with a dgb::coin:: positive control so it cannot pass vacuously on a wrong/stripped binary. Wired as a post-build step in the COIN_DGB+AUX_DOGE CI job. ltc::coin wire-generic types (header-only/inlined, no symbols) are out of scope by design -- a wire-type relocation is caught by the D0-seam flag protocol, not this link guard. --------- Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
1 parent 5a978f5 commit 5ac007e

4 files changed

Lines changed: 154 additions & 0 deletions

File tree

.github/workflows/build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,13 @@ jobs:
866866
- name: Build c2pool-dgb binary (AUX_DOGE seam ON)
867867
run: cmake --build build_dgb_auxdoge --target c2pool-dgb -j8
868868

869+
# Link-level companion to the compile-time aux_doge_isolation_guard.hpp:
870+
# fail the build if the DGB parent (AUX_DOGE seam ON) ODR-uses any LTC
871+
# per-coin consensus symbol (make_ltc_chain_params / ltc::coin::HeaderChain
872+
# / ltc::coin::ChainParams). Positive control asserts dgb::coin:: present.
873+
- name: Link-isolation guard (no LTC consensus surface in DGB parent)
874+
run: bash scripts/ci/dgb_aux_doge_link_isolation_guard.sh build_dgb_auxdoge/src/c2pool/c2pool-dgb
875+
869876
- name: Smoke test (--help)
870877
run: |
871878
BIN=build_dgb_auxdoge/src/c2pool/c2pool-dgb
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env bash
2+
#
3+
# DGB AUX_DOGE link-isolation guard (negative-symbol check)
4+
# ----------------------------------------------------------
5+
# Companion to the compile-time src/impl/dgb/coin/aux_doge_isolation_guard.hpp.
6+
# The compile guard pins DGB-parent traits to dgb::coin types via static_assert;
7+
# this guard closes the gap it cannot see -- LINK-level consensus reachability.
8+
#
9+
# Invariant: c2pool-dgb built with -DCOIN_DGB=ON -DAUX_DOGE=ON (dual-parent,
10+
# DGB-Scrypt parent + DOGE aux) must NOT ODR-use any LTC per-coin CONSENSUS
11+
# symbol. A dropped dgb specialization could silently re-route the DGB parent
12+
# through ltc::coin chain-params / header-chain serialization -- a foreign
13+
# consensus path. That is the failure mode this guard freezes out.
14+
#
15+
# SCOPE (deliberate): hard-fail on the named LTC consensus entrypoints only.
16+
# ltc::coin wire-generic types (transaction.hpp) are header-only / inlined and
17+
# emit NO external symbols, so they are out of scope here. A wire-type
18+
# RELOCATION toward bitcoin_family (the v37 (b) path) is caught by the D0-seam
19+
# flag protocol with ltc-doge, not by this link guard.
20+
#
21+
# POSITIVE CONTROL: assert dgb::coin:: consensus symbols ARE present, so the
22+
# guard cannot pass vacuously on a wrong / empty / stripped binary.
23+
#
24+
# Usage: dgb_aux_doge_link_isolation_guard.sh [path-to-c2pool-dgb]
25+
set -euo pipefail
26+
27+
BIN="${1:-build_dgb_auxdoge/src/c2pool/c2pool-dgb}"
28+
29+
if [[ ! -f "$BIN" ]]; then
30+
echo "FAIL: binary not found: $BIN" >&2
31+
exit 2
32+
fi
33+
34+
if ! command -v nm >/dev/null 2>&1; then
35+
echo "FAIL: nm not available on this runner" >&2
36+
exit 2
37+
fi
38+
39+
SYMS="$(nm -C "$BIN" 2>/dev/null || true)"
40+
if [[ -z "$SYMS" ]]; then
41+
echo "FAIL: nm produced no symbols (binary stripped?): $BIN" >&2
42+
exit 2
43+
fi
44+
45+
# --- Negative: forbidden LTC consensus surface (defined T/t/W/V or referenced U) ---
46+
FORBIDDEN_RE='make_ltc_chain_params|make_litecoin_chain_params|ltc::coin::HeaderChain|ltc::coin::ChainParams'
47+
48+
HITS="$(printf '%s\n' "$SYMS" | grep -E "$FORBIDDEN_RE" || true)"
49+
if [[ -n "$HITS" ]]; then
50+
echo "FAIL: c2pool-dgb (AUX_DOGE) links forbidden LTC consensus symbol(s):" >&2
51+
printf '%s\n' "$HITS" >&2
52+
echo " -> DGB parent must not reach ltc::coin consensus surface. Route to D0 seam thread." >&2
53+
exit 1
54+
fi
55+
56+
# --- Positive control: DGB parent consensus types must be present ---
57+
DGB_COUNT="$(printf '%s\n' "$SYMS" | grep -cE 'dgb::coin::' || true)"
58+
if [[ "${DGB_COUNT:-0}" -eq 0 ]]; then
59+
echo "FAIL: no dgb::coin:: symbols found -- wrong/empty binary, guard would pass vacuously: $BIN" >&2
60+
exit 1
61+
fi
62+
63+
echo "PASS: dgb-aux-doge link isolation"
64+
echo " binary : $BIN"
65+
echo " forbidden LTC : 0 hits ($FORBIDDEN_RE)"
66+
echo " dgb::coin:: syms : $DGB_COUNT (positive control OK)"
67+
exit 0
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#pragma once
2+
// ---------------------------------------------------------------------------
3+
// DGB+DOGE merged-mining (D0.5) -- per-coin consensus-isolation guard.
4+
//
5+
// The -DAUX_DOGE=ON DGB-as-parent build links ltc_coin (substrate path (a),
6+
// integrator-ratified) for Bitcoin-wire-generic value/serialization types ONLY
7+
// (BlockType, MutableTransaction, compute_merkle_root, ...). The LTC CONSENSUS
8+
// surface -- ltc::coin::HeaderChain, make_ltc_chain_params_mainnet/testnet, the
9+
// scrypt pow binding, Art-Forz retarget -- is present-but-dead at link and must
10+
// NEVER reach a live DGB-parent call path. "DGB-parent never instantiates
11+
// ltc::coin::HeaderChain nor calls make_ltc_chain_params_*" is today a discipline
12+
// invariant; this header converts the most regression-prone half into a
13+
// COMPILE-TIME invariant so one future edit cannot silently re-route the
14+
// DGB-parent path through foreign (LTC) consensus serialization.
15+
//
16+
// Two-part guard (per the isolation-invariant hardening):
17+
// * compile-time (this header): assert the DGB-parent aux seam binds DGB's OWN
18+
// consensus serialization (dgb::coin::TX_NO_WITNESS), not bitcoin_family's
19+
// default that LTC/DASH inherit, and that the DGB parent coinbase type is
20+
// distinct from ltc::coin's.
21+
// * link-time (fast-follow, src/impl/dgb/CMakeLists.txt POST_BUILD): an
22+
// `nm -C` negative-symbol check on the c2pool-dgb binary that FAILS the
23+
// build if `make_ltc_chain_params` or `ltc::coin::HeaderChain` is ODR-used.
24+
// (Staged separately -- it needs an AUX_DOGE build slot to validate the
25+
// demangled-symbol grep.)
26+
// ---------------------------------------------------------------------------
27+
28+
#ifdef AUX_DOGE
29+
30+
#include <type_traits>
31+
32+
#include <impl/doge/coin/auxpow.hpp> // CAuxPow<>, parent_coinbase_no_witness<>
33+
#include <impl/dgb/coin/transaction.hpp> // dgb::coin::MutableTransaction, TX_NO_WITNESS
34+
#include <impl/dgb/coin/aux_doge_parent_traits.hpp> // doge::coin::parent_coinbase_no_witness<dgb::coin::MutableTransaction>
35+
#include <impl/ltc/coin/transaction.hpp> // ltc::coin::MutableTransaction (wire-generic, ALLOWED on link)
36+
37+
namespace dgb::coin::aux_doge_guard {
38+
39+
// (1) The DGB-parent witness-strip trait in effect MUST resolve to DGB's own
40+
// consensus serialization. The shared aux module defaults this trait to
41+
// bitcoin_family::coin::TX_NO_WITNESS (the LTC/DASH path); the dgb
42+
// specialization in aux_doge_parent_traits.hpp overrides it to
43+
// dgb::coin::TX_NO_WITNESS. If a refactor ever dropped that specialization,
44+
// the DGB-parent coinbase would silently serialize through bitcoin_family's
45+
// (foreign) params -- caught here at compile time.
46+
static_assert(
47+
std::is_same_v<
48+
std::decay_t<decltype(
49+
::doge::coin::parent_coinbase_no_witness<dgb::coin::MutableTransaction>::value)>,
50+
dgb::coin::TxParams>,
51+
"AUX_DOGE isolation: DGB-parent coinbase must serialize through dgb::coin::TxParams "
52+
"(its OWN consensus params), never bitcoin_family's default (the LTC/DASH path). "
53+
"A failure here means the dgb specialization in aux_doge_parent_traits.hpp was dropped.");
54+
55+
// (2) The DGB parent coinbase type is DGB-owned, distinct from ltc::coin's. The
56+
// shared aux module's DEFAULT parent is ltc::coin::MutableTransaction; the
57+
// DGB seam pins the parser to dgb::coin::MutableTransaction instead. This
58+
// records that the two parent types are genuinely distinct, so a regression
59+
// that left the ltc default in place is a type change, not a silent alias.
60+
static_assert(
61+
!std::is_same_v<dgb::coin::MutableTransaction, ::ltc::coin::MutableTransaction>,
62+
"AUX_DOGE isolation: DGB parent coinbase type must be distinct from ltc::coin's; "
63+
"the DGB seam pins the parser to dgb::coin::MutableTransaction, not the shared "
64+
"module's ltc default.");
65+
66+
} // namespace dgb::coin::aux_doge_guard
67+
68+
#endif // AUX_DOGE

src/impl/dgb/coin/node.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@
3939
// (parse_aux_header<dgb::coin::MutableTransaction> / CAuxPow<dgb::coin::Mutable-
4040
// Transaction>) inside the PRODUCTION dgb object library, not merely in fixtures.
4141
#include <functional>
42+
#include <type_traits>
4243

4344
#include <core/pack.hpp> // PackStream (the byte stream the parser reads)
4445
#include <impl/doge/coin/auxpow.hpp> // shared SSOT: CAuxPow<>, parse_aux_header<>, CPureBlockHeader
4546
#include <impl/dgb/coin/transaction.hpp> // dgb::coin::MutableTransaction (the DGB parent coinbase type)
4647
#include <impl/dgb/coin/aux_doge_parent_traits.hpp> // doge::coin::parent_coinbase_no_witness<dgb::coin::MutableTransaction>
48+
#include <impl/dgb/coin/aux_doge_isolation_guard.hpp> // D0.5 per-coin consensus-isolation guard (compile-time half)
4749
#endif
4850

4951
namespace dgb
@@ -75,6 +77,16 @@ struct AuxDogeParse
7577
// DGB-parent parse. std::function so bind_aux_doge_parsers() can ASSIGN it (real,
7678
// callable binding -- never a no-op), forcing ODR-use of the templated parser.
7779
using AuxDogeParserFn = std::function<AuxDogeParse(PackStream&)>;
80+
81+
// D0.5 isolation (live-path half): the seam's structured proof MUST be pinned to
82+
// the DGB parent coinbase type. If a regression let the shared module's default
83+
// (ltc::coin::MutableTransaction) bind here, the DGB live dispatch would parse the
84+
// aux proof through the LTC parent type -- caught at compile time, in production.
85+
static_assert(
86+
std::is_same_v<decltype(AuxDogeParse::m_aux),
87+
::doge::coin::CAuxPow<dgb::coin::MutableTransaction>>,
88+
"AUX_DOGE isolation: AuxDogeParse must carry CAuxPow<dgb::coin::MutableTransaction> "
89+
"(DGB-parent-pinned), never the shared module's ltc default.");
7890
#endif
7991

8092
template <typename ConfigType>

0 commit comments

Comments
 (0)