Skip to content

dash(s6): consensus-payout conformance — pay nonzero sub-dust, drop only zero (oracle p2pool-dash) - #154

Merged
frstrtr merged 4 commits into
masterfrom
dash/payout-dust-conformance
Jun 18, 2026
Merged

dash(s6): consensus-payout conformance — pay nonzero sub-dust, drop only zero (oracle p2pool-dash)#154
frstrtr merged 4 commits into
masterfrom
dash/payout-dust-conformance

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Operator decision (picker 2026-06-18 14:27 +04): CONFORM TO ORACLE. DASH-only consensus-payout conformance.

What changed

  • src/impl/dash/pplns.hpp: REMOVED the payout dust drop (if (amt < dust_threshold) continue; -> if (amt == 0) continue;) and dropped the dust_threshold parameter 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)).
  • DUST_THRESHOLD (100000 duff) is UNCHANGED in role: it survives solely as the vardiff / share-difficulty floor (c2pool_refactored.cpp mirror of work.py:326). It is no longer consulted in the payout path.

KAT (test/test_dash_conformance.cpp, DashConformancePayoutDust)

Rewritten to assert oracle truth, not the old drop:

  • A1: sub-dust worker B (50000) is PAID its own output.
  • A4a (V=399996): B = floor(399996/4) = 99999 -> under the OLD 54600/100000 floor it was dropped; under the oracle it is PAID. A = 299997; donation = rounding remainder (0).
  • A4b/A2b: symmetric just-above-floor partners.
  • Exactly-zero worker output is the ONLY thing dropped.

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.

frstrtr added 4 commits June 18, 2026 10:57
…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.
@frstrtr
frstrtr changed the base branch from dash/s6-conformance-params to master June 18, 2026 11:12
@frstrtr frstrtr closed this Jun 18, 2026
@frstrtr frstrtr reopened this Jun 18, 2026
@frstrtr frstrtr closed this Jun 18, 2026
@frstrtr frstrtr reopened this Jun 18, 2026
@frstrtr
frstrtr merged commit d96eda6 into master Jun 18, 2026
32 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant