Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,13 @@ jobs:
- name: Build c2pool-dgb binary (AUX_DOGE seam ON)
run: cmake --build build_dgb_auxdoge --target c2pool-dgb -j8

# Link-level companion to the compile-time aux_doge_isolation_guard.hpp:
# fail the build if the DGB parent (AUX_DOGE seam ON) ODR-uses any LTC
# per-coin consensus symbol (make_ltc_chain_params / ltc::coin::HeaderChain
# / ltc::coin::ChainParams). Positive control asserts dgb::coin:: present.
- name: Link-isolation guard (no LTC consensus surface in DGB parent)
run: bash scripts/ci/dgb_aux_doge_link_isolation_guard.sh build_dgb_auxdoge/src/c2pool/c2pool-dgb

- name: Smoke test (--help)
run: |
BIN=build_dgb_auxdoge/src/c2pool/c2pool-dgb
Expand Down
67 changes: 67 additions & 0 deletions scripts/ci/dgb_aux_doge_link_isolation_guard.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
#
# DGB AUX_DOGE link-isolation guard (negative-symbol check)
# ----------------------------------------------------------
# Companion to the compile-time src/impl/dgb/coin/aux_doge_isolation_guard.hpp.
# The compile guard pins DGB-parent traits to dgb::coin types via static_assert;
# this guard closes the gap it cannot see -- LINK-level consensus reachability.
#
# Invariant: c2pool-dgb built with -DCOIN_DGB=ON -DAUX_DOGE=ON (dual-parent,
# DGB-Scrypt parent + DOGE aux) must NOT ODR-use any LTC per-coin CONSENSUS
# symbol. A dropped dgb specialization could silently re-route the DGB parent
# through ltc::coin chain-params / header-chain serialization -- a foreign
# consensus path. That is the failure mode this guard freezes out.
#
# SCOPE (deliberate): hard-fail on the named LTC consensus entrypoints only.
# ltc::coin wire-generic types (transaction.hpp) are header-only / inlined and
# emit NO external symbols, so they are out of scope here. A wire-type
# RELOCATION toward bitcoin_family (the v37 (b) path) is caught by the D0-seam
# flag protocol with ltc-doge, not by this link guard.
#
# POSITIVE CONTROL: assert dgb::coin:: consensus symbols ARE present, so the
# guard cannot pass vacuously on a wrong / empty / stripped binary.
#
# Usage: dgb_aux_doge_link_isolation_guard.sh [path-to-c2pool-dgb]
set -euo pipefail

BIN="${1:-build_dgb_auxdoge/src/c2pool/c2pool-dgb}"

if [[ ! -f "$BIN" ]]; then
echo "FAIL: binary not found: $BIN" >&2
exit 2
fi

if ! command -v nm >/dev/null 2>&1; then
echo "FAIL: nm not available on this runner" >&2
exit 2
fi

SYMS="$(nm -C "$BIN" 2>/dev/null || true)"
if [[ -z "$SYMS" ]]; then
echo "FAIL: nm produced no symbols (binary stripped?): $BIN" >&2
exit 2
fi

# --- Negative: forbidden LTC consensus surface (defined T/t/W/V or referenced U) ---
FORBIDDEN_RE='make_ltc_chain_params|make_litecoin_chain_params|ltc::coin::HeaderChain|ltc::coin::ChainParams'

HITS="$(printf '%s\n' "$SYMS" | grep -E "$FORBIDDEN_RE" || true)"
if [[ -n "$HITS" ]]; then
echo "FAIL: c2pool-dgb (AUX_DOGE) links forbidden LTC consensus symbol(s):" >&2
printf '%s\n' "$HITS" >&2
echo " -> DGB parent must not reach ltc::coin consensus surface. Route to D0 seam thread." >&2
exit 1
fi

# --- Positive control: DGB parent consensus types must be present ---
DGB_COUNT="$(printf '%s\n' "$SYMS" | grep -cE 'dgb::coin::' || true)"
if [[ "${DGB_COUNT:-0}" -eq 0 ]]; then
echo "FAIL: no dgb::coin:: symbols found -- wrong/empty binary, guard would pass vacuously: $BIN" >&2
exit 1
fi

echo "PASS: dgb-aux-doge link isolation"
echo " binary : $BIN"
echo " forbidden LTC : 0 hits ($FORBIDDEN_RE)"
echo " dgb::coin:: syms : $DGB_COUNT (positive control OK)"
exit 0
68 changes: 68 additions & 0 deletions src/impl/dgb/coin/aux_doge_isolation_guard.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once
// ---------------------------------------------------------------------------
// DGB+DOGE merged-mining (D0.5) -- per-coin consensus-isolation guard.
//
// The -DAUX_DOGE=ON DGB-as-parent build links ltc_coin (substrate path (a),
// integrator-ratified) for Bitcoin-wire-generic value/serialization types ONLY
// (BlockType, MutableTransaction, compute_merkle_root, ...). The LTC CONSENSUS
// surface -- ltc::coin::HeaderChain, make_ltc_chain_params_mainnet/testnet, the
// scrypt pow binding, Art-Forz retarget -- is present-but-dead at link and must
// NEVER reach a live DGB-parent call path. "DGB-parent never instantiates
// ltc::coin::HeaderChain nor calls make_ltc_chain_params_*" is today a discipline
// invariant; this header converts the most regression-prone half into a
// COMPILE-TIME invariant so one future edit cannot silently re-route the
// DGB-parent path through foreign (LTC) consensus serialization.
//
// Two-part guard (per the isolation-invariant hardening):
// * compile-time (this header): assert the DGB-parent aux seam binds DGB's OWN
// consensus serialization (dgb::coin::TX_NO_WITNESS), not bitcoin_family's
// default that LTC/DASH inherit, and that the DGB parent coinbase type is
// distinct from ltc::coin's.
// * link-time (fast-follow, src/impl/dgb/CMakeLists.txt POST_BUILD): an
// `nm -C` negative-symbol check on the c2pool-dgb binary that FAILS the
// build if `make_ltc_chain_params` or `ltc::coin::HeaderChain` is ODR-used.
// (Staged separately -- it needs an AUX_DOGE build slot to validate the
// demangled-symbol grep.)
// ---------------------------------------------------------------------------

#ifdef AUX_DOGE

#include <type_traits>

#include <impl/doge/coin/auxpow.hpp> // CAuxPow<>, parent_coinbase_no_witness<>
#include <impl/dgb/coin/transaction.hpp> // dgb::coin::MutableTransaction, TX_NO_WITNESS
#include <impl/dgb/coin/aux_doge_parent_traits.hpp> // doge::coin::parent_coinbase_no_witness<dgb::coin::MutableTransaction>
#include <impl/ltc/coin/transaction.hpp> // ltc::coin::MutableTransaction (wire-generic, ALLOWED on link)

namespace dgb::coin::aux_doge_guard {

// (1) The DGB-parent witness-strip trait in effect MUST resolve to DGB's own
// consensus serialization. The shared aux module defaults this trait to
// bitcoin_family::coin::TX_NO_WITNESS (the LTC/DASH path); the dgb
// specialization in aux_doge_parent_traits.hpp overrides it to
// dgb::coin::TX_NO_WITNESS. If a refactor ever dropped that specialization,
// the DGB-parent coinbase would silently serialize through bitcoin_family's
// (foreign) params -- caught here at compile time.
static_assert(
std::is_same_v<
std::decay_t<decltype(
::doge::coin::parent_coinbase_no_witness<dgb::coin::MutableTransaction>::value)>,
dgb::coin::TxParams>,
"AUX_DOGE isolation: DGB-parent coinbase must serialize through dgb::coin::TxParams "
"(its OWN consensus params), never bitcoin_family's default (the LTC/DASH path). "
"A failure here means the dgb specialization in aux_doge_parent_traits.hpp was dropped.");

// (2) The DGB parent coinbase type is DGB-owned, distinct from ltc::coin's. The
// shared aux module's DEFAULT parent is ltc::coin::MutableTransaction; the
// DGB seam pins the parser to dgb::coin::MutableTransaction instead. This
// records that the two parent types are genuinely distinct, so a regression
// that left the ltc default in place is a type change, not a silent alias.
static_assert(
!std::is_same_v<dgb::coin::MutableTransaction, ::ltc::coin::MutableTransaction>,
"AUX_DOGE isolation: DGB parent coinbase type must be distinct from ltc::coin's; "
"the DGB seam pins the parser to dgb::coin::MutableTransaction, not the shared "
"module's ltc default.");

} // namespace dgb::coin::aux_doge_guard

#endif // AUX_DOGE
12 changes: 12 additions & 0 deletions src/impl/dgb/coin/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@
// (parse_aux_header<dgb::coin::MutableTransaction> / CAuxPow<dgb::coin::Mutable-
// Transaction>) inside the PRODUCTION dgb object library, not merely in fixtures.
#include <functional>
#include <type_traits>

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

namespace dgb
Expand Down Expand Up @@ -75,6 +77,16 @@ struct AuxDogeParse
// DGB-parent parse. std::function so bind_aux_doge_parsers() can ASSIGN it (real,
// callable binding -- never a no-op), forcing ODR-use of the templated parser.
using AuxDogeParserFn = std::function<AuxDogeParse(PackStream&)>;

// D0.5 isolation (live-path half): the seam's structured proof MUST be pinned to
// the DGB parent coinbase type. If a regression let the shared module's default
// (ltc::coin::MutableTransaction) bind here, the DGB live dispatch would parse the
// aux proof through the LTC parent type -- caught at compile time, in production.
static_assert(
std::is_same_v<decltype(AuxDogeParse::m_aux),
::doge::coin::CAuxPow<dgb::coin::MutableTransaction>>,
"AUX_DOGE isolation: AuxDogeParse must carry CAuxPow<dgb::coin::MutableTransaction> "
"(DGB-parent-pinned), never the shared module's ltc default.");
#endif

template <typename ConfigType>
Expand Down
Loading