dash(s6): consensus-payout conformance — pay nonzero sub-dust, drop only zero (oracle p2pool-dash) - #154
Merged
Merged
Conversation
…n-A) The DASH payout-dust floor was split across two wrong-semantic relay-policy values: params.hpp carried 5460 (dashd relay floor) and pplns compute_payouts defaulted to 54600. Neither matches the p2pool-dash oracle payout-dust semantic (PARENT.DUST_THRESHOLD = 0.001e8 = 100000 satoshi), which is the value the BTC/BCH/DGB siblings already conform to. Add dash::PoolConfig::DUST_THRESHOLD (100000) as the single SSOT and route both the CoinParams factory (params.hpp) and the PPLNS filter default (pplns.hpp) to PoolConfig::dust_threshold(). No behavior change for existing payouts (all worker splits exceed 100000; the unconditional donation line is unaffected). GATED: payout-filtering under the new 100000 floor is to be confirmed by the captured-corpus KAT before this lands; held for operator approval.
…ated) Wire the dust-floor conformance KATs that gate the b9b3e38 reconciliation (payout dust SSOT -> PoolConfig::dust_threshold() == 100000, V36 Option-A). DashConformancePayoutDust, out-of-band oracle arithmetic mirroring p2pool-dash data.py get_expected_payouts (per-share work = diff-1, fractions exact): - A1 DustWorkerDroppedResidueToDonationLine: a worker whose floor(frac*value) falls below 100000 is dropped from the payout set. - A2 (same case): conservation holds and the dropped-dust residue accrues to the DONATION line (residue = miner_value - allocated), NOT to the largest remaining payout. Pins the actual code path; the pplns.hpp:7-8 header comment is stale. - A2b ThresholdBoundaryExactFloorRetained: amt == 100000 is retained (filter is strict <), guarding against an off-by-one to <=. - A3 DonationLineExemptFromDustFloor: the always-emitted donation line is not subject to the dust floor (sub-100000 residue still present). A4 (live captured-corpus round-trip through get_expected_payouts) is NOT wired: PR #144 @bddd38fb captured consensus-only vectors (X11 hash + DGW-v3 retarget), no payout/PPLNS vector and no sub-100000 proportional share. Not fabricated; held pending an oracle-cross-checked payout corpus. 3/3 new KATs green; full test_dash_conformance 35/35 across 11 suites on Linux x86_64. Held for operator approval; do not push.
A4 was held for a live captured sub-100000 payout corpus, but the p2pool-dash oracle (data.py:682 get_expected_payouts) is algorithmic: floor(weight_frac * value) with the unallocated remainder accruing to DONATION_SCRIPT. With equal-difficulty shares the weight fraction is n/T, so a 3:1 split (B = 1/4) reproduces any exact duff boundary node-free. A4a: V=399996 -> B=floor(99999) < 100000 -> dropped (residue to donation). A4b: V=400004 -> B=floor(100001) >= 100000 -> retained. Together with A2b (V=400000 -> 100000 retained) this pins the strict-< dust gate at single-duff granularity. DUST_THRESHOLD=100000 verified parity vs dash.py:34 / dash_testnet.py:28 / dash_regtest.py:28. ctest -R DashConformance 37/37 (was 35/35).
…zero Operator 2026-06-18 CONFORM-TO-ORACLE (option a). Remove the payout dust floor from pplns.hpp: every NONZERO worker allocation floor(weight_frac * miner_value) is paid to its own script, matching p2pool-dash data.py get_expected_payouts. Only EXACTLY-zero outputs are dropped (oracle if amounts[script]); the donation line carries only the rounding remainder. PoolConfig::dust_threshold() (100000) is retained as the vardiff / share-difficulty floor (c2pool_refactored.cpp mirror of work.py:326) and is no longer consulted in the payout path; the now-dead parameter and its include are removed. Dust KATs A1-A4 rewritten to assert oracle truth (nonzero sub-dust PAID, e.g. 99999 boundary now paid) plus a new A5 pinning the surviving exactly-zero filter.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Operator decision (picker 2026-06-18 14:27 +04): CONFORM TO ORACLE. DASH-only consensus-payout conformance.
What changed
if (amt < dust_threshold) continue;->if (amt == 0) continue;) and dropped thedust_thresholdparameter from compute_payouts(). Every NONZERO worker allocation floor(weight_frac * miner_value) is now paid to its own script; only EXACTLY-zero outputs are dropped, matching p2pool-dash data.py get_expected_payouts (if amounts[script]). Donation line carries ONLY the rounding remainder (miner_value - sum(workers)).KAT (test/test_dash_conformance.cpp, DashConformancePayoutDust)
Rewritten to assert oracle truth, not the old drop:
Scope
Single-coin DASH-only. Stacked on #146 (dash/s6-conformance-params) for the CoinParams SSOT it relies on; diff here is payout-only. GitHub will retarget to master when #146 merges.
Verification
Linux x86_64: cmake --build + ctest -R DashConformance from build/ -> 38/38 passed (real count, not CWD-hollow). Awaiting fresh full CI.
Operator-gated merge: not self-merged.