From 894593ed4645804a7d5689acf6ca387216b4172e Mon Sep 17 00:00:00 2001 From: frstrtr Date: Sat, 13 Jun 2026 12:37:38 +0000 Subject: [PATCH] docs(ltc/merged): annotate v36 audit C2/C4 as intentional/non-consensus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C2: merged-chain weights are intentionally flat (no decay) vs the parent LTC decayed-cumulative skiplist, mirroring p2pool get_v36_merged_weights. C4: get_merged_expected_payouts and build_pplns_coinbase_hex output ordering is node-local and non-consensus — the DOGE aux coinbase is submitted only to dogecoind (accepts any valid ordering); the sharechain commits to merged work via the AuxPoW merkle proof, never by re-deriving coinbase outputs across peers. Documentation only; no behavioral change. Closes the C1-C7 cross-check loop (C1/C3/C5 already-satisfied, C6/C7 confirmed, C7 ltc CHAIN_LENGTH=8640). --- src/c2pool/merged/merged_mining.cpp | 5 +++++ src/impl/ltc/share_tracker.hpp | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/c2pool/merged/merged_mining.cpp b/src/c2pool/merged/merged_mining.cpp index 3b9fd83d0..0774c8113 100644 --- a/src/c2pool/merged/merged_mining.cpp +++ b/src/c2pool/merged/merged_mining.cpp @@ -1272,6 +1272,11 @@ void MergedMiningManager::set_block_relay_fn(BlockRelayFn fn) // ─── Shared helpers ────────────────────────────────────────────────────────── +// [v36-audit C4] Output ordering here is NODE-LOCAL and NOT consensus-bearing: +// the assembled DOGE coinbase is submitted only to dogecoind, which accepts any +// valid ordering. The sharechain commits to merged work via the AuxPoW merkle +// proof, not by re-deriving these outputs across peers. Donation split + dust +// tiebreak below are deterministic purely for stable local block assembly. /*static*/ std::string MergedMiningManager::build_pplns_coinbase_hex( int height, const std::vector, uint64_t>>& payouts, diff --git a/src/impl/ltc/share_tracker.hpp b/src/impl/ltc/share_tracker.hpp index 4076bef28..f5140b225 100644 --- a/src/impl/ltc/share_tracker.hpp +++ b/src/impl/ltc/share_tracker.hpp @@ -2304,6 +2304,10 @@ class ShareTracker delta.total_weight = att * 65535; delta.total_donation_weight = att * static_cast(obj->m_donation); + // [v36-audit C2] INTENTIONAL DIVERGENCE: merged-chain weights are FLAT + // (att-weighted, no time-decay). Only the parent/LTC chain applies decay. + // Mirrors p2pool get_v36_merged_weights (flat + cap, data.py:2657) vs the + // parent decayed-cumulative skiplist. Verified intentional, not a bug. delta.weights[weight_key] = att * static_cast(65535 - obj->m_donation); return delta; } @@ -2512,6 +2516,12 @@ class ShareTracker // per_miner = miners_reward * w // accepted_total // rounding_remainder = miners_reward - sum(per_miner) // final_donation = donation_amount + rounding_remainder + // [v36-audit C4] NODE-LOCAL / NON-CONSENSUS. Despite the name, this derives + // THIS node's intended DOGE aux-coinbase payout split from PPLNS weights to + // build the block submitted to dogecoind. Sole caller = the MM payout_provider + // (c2pool_refactored.cpp); never invoked from share verification. Peers validate + // the merged commitment via the AuxPoW merkle proof, NOT by re-deriving these + // outputs, so output ordering is node-local (dogecoind accepts any valid order). std::map, uint64_t> get_merged_expected_payouts(const uint256& best_share_hash, const uint256& block_target,