Skip to content

dgb(stratum): score shares via scrypt digest in compute_share_difficulty (unstub 4b/4c)#753

Merged
frstrtr merged 3 commits into
masterfrom
dgb/stratum-compute-share-diff
Jul 19, 2026
Merged

dgb(stratum): score shares via scrypt digest in compute_share_difficulty (unstub 4b/4c)#753
frstrtr merged 3 commits into
masterfrom
dgb/stratum-compute-share-diff

Conversation

@frstrtr

@frstrtr frstrtr commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

DGBWorkSource::compute_share_difficulty was a Stage-4b/4c stub returning 0.0.
The coin-agnostic StratumServer calls it before mining_submit and silently
rejects any share scoring below the vardiff floor (stratum_server.cpp:1128,
error 23 "Low difficulty share", no server-side log). Every otherwise-valid share
was dropped before the stage-4d classify + broadcaster path ever ran, so the DGB
pool could never advance its tip.

What this does

Implements compute_share_difficulty as a byte-for-byte mirror of the
mining_submit reconstruct:

coinb1 || en1 || en2 || coinb2 -> sha256d txid -> ascend merkle branches ->
80-byte header -> scrypt_1024_1_1_256, then bridges the coin-space u256 into
core uint256 via the u256_be_display_hex SSOT and returns
chain::target_to_difficulty against diff-1 0x1d00ffff — unit-identical to the
required_difficulty / pool_difficulty the gate compares against.

Malformed reconstruct (header != 80 bytes) keeps the documented 0.0
not-scored sentinel.

Test

  • Real KAT replaces the ReturnsNotYetSentinel placeholder at
    work_source_test.cpp:342: valid header scores a finite positive difficulty.
  • 31/31 DGB tests green.

Live verification

Deployed to VM115 as c2pool-dgb-csd (pid 56981), testnet, stratum :5025,
rig hashing against it. Shares now score (0.001+) -> cross the vardiff gate
-> 15+ BLOCK FOUND -> dispatch submitblock.

Follow-on (tracked separately, not a regression from this commit): on an
empty embedded chain digibyted rejects the submitted block with
bad-txnmrklroot — the reconstructed header merkleroot does not match the
serialized coinbase. That is the Phase-B GBT-block-template gap; fix is to
source the full block template from digibyted GBT when the embedded chain
is empty.

Scope

src/impl/dgb/ only. No shared-base or src/core changes.

frstrtr added 3 commits July 17, 2026 08:57
…ty embedded chain

A freshly-stood-up c2pool-dgb :5025 node whose Scrypt-only HeaderChain has
not yet ingested a tip (tip_hash()==nullopt) could supply NEITHER a
previousblockhash NOR nBits: the header walk cannot reconstruct MultiShield-V4
(a 5-algo window == V37), and the embedded ingest that populates the tip lands
later. Result: an EMPTY mining.notify prevhash on the live testnet.

Add DGBWorkSource::set_gbt_tip_fn -- a std::function seam (mirrors
set_pplns_inputs_fn and dash #726 dashd_fallback) bound in main_dgb.cpp to a
lambda over NodeRPC::getblocktemplate. When the embedded chain has no tip,
get_current_work_template() AND get_current_gbt_prevhash() (the notify-prevhash
source) draw BOTH previousblockhash and the daemon-authoritative bits from ONE
GBT snapshot (consistent height). A real embedded tip always wins; the RPC
transport stays in main (stratum/ holds only the seam). Unbound / no digibyted
creds / RPC failure -> both fields stay a truthful ABSENCE, byte-identical to
the pre-wire path -- never a fabricated tip/bits. GBT previousblockhash is the
u256_be_display_hex big-endian convention the embedded path emits, so it flows
verbatim (width-guarded at the bind). TTL-cached (5s) so per-heartbeat template
+ prevhash polls do not each trigger a blocking getblocktemplate round-trip.

External-daemon GBT fallback RETAINED (never removed), per V36. Scrypt-only;
no shared-base / other-coin edit; per-coin isolation held.

Tests: 3 new DgbWorkSource.GbtTip* (populate / unbound-absent / nullopt-absent)
over the empty-chain fixture; full dgb_work_source_test 30/30 green.
…lty (unstub 4b/4c)

DGBWorkSource::compute_share_difficulty was a Stage-4b/4c stub returning 0.0.
The coin-agnostic StratumServer calls it BEFORE mining_submit and silently
rejects any share scoring below the vardiff floor (stratum_server.cpp: error 23
Low difficulty share, no server-side log), so every accepted-looking share was
dropped before the stage-4d classify+broadcaster ever ran -- the pool could
never advance its tip.

Implement it as a byte-for-byte mirror of mining_submit reconstruct:
coinb1||en1||en2||coinb2 -> sha256d txid -> ascend merkle branches -> 80-byte
header -> scrypt_1024_1_1_256, then bridge the coin-space u256 into core
uint256 via the u256_be_display_hex SSOT and return chain::target_to_difficulty
(diff-1 0x1d00ffff) -- unit-identical to the required_difficulty / pool_difficulty
the gate compares. Malformed reconstruct (header != 80B) keeps the documented
0.0 not-scored sentinel. KAT: valid header scores a finite positive difficulty;
malformed input still returns 0.0. 31/31 dgb_work_source_test green.
@frstrtr
frstrtr merged commit 300766a into master Jul 19, 2026
38 checks passed
@frstrtr
frstrtr deleted the dgb/stratum-compute-share-diff branch July 19, 2026 16:14
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