- POOL_INTEGRATION.md: exact job/submit format, pool-side validation & scoring on the SHA256D pow-hash, and a zero-downtime dual-accept rollout plan (deploy dual-accept pool before announcing drg-xmrig). - Restore doc/build/ docs removed during the initial copy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.1 KiB
Pool integration & migration guide (drg-xmrig)
drg-xmrig mines DragonX with the pow-hash share model: it filters every hash on
SHA256D(header + RandomX(header)) (the block-bearing hash), not on the RandomX hash.
A pool must score shares on that same pow-hash. This document is the spec for updating
the DragonX stratum pool to support drg-xmrig, plus a zero-downtime rollout plan.
See PROTOCOL.md for the exact byte-level wire format. This file is the pool's view.
1. Job (pool → miner)
Send a standard XMRig job with:
| field | value |
|---|---|
job_id |
unique per job |
algo |
rx/dragonx (aliases also accepted: rx/hush, dragonx) |
blob |
140-byte header hex (280 chars): header[0:108] + nonce[108:140] |
target |
4- or 8-byte compact target, standard XMRig convention (diff = 0xFFFF…/target) |
seed_hash |
RandomX seed hash for the current key block |
height |
block height |
Blob layout (140 bytes): version(4) + prevHash(32) + merkleRoot(32) + blockCommitments(32) + nTime(4) + nBits(4) = 108, then a 32-byte nonce field at [108:140].
Extranonce (REQUIRED for >1 miner): the miner only varies the uint32 at [108:112]
and copies bytes [112:140] verbatim into the submitted nonce. So the pool MUST write
a unique per-connection value into nonce bytes [112:140] (28 bytes) of every blob.
Without it, two miners scan the same 2^32 space and waste work / collide. (This is the
existing extranonce mechanism — it just lives in the upper 28 nonce bytes.)
2. Submit (miner → pool)
{ "id": "<rpcId>", "job_id": "<job_id>",
"nonce": "<64 hex = full 32-byte nonce field [108:140]>",
"result": "<64 hex = 32-byte RandomX hash>",
"algo": "rx/dragonx" } // present only if pool advertised the "algo" login extension
nonce is the full 32 bytes = [4-byte counter | 28-byte extranonce you assigned].
result is the raw RandomX hash (the PoW solution), NOT the double-SHA.
3. Pool-side validation & scoring
For each submit:
- Reconstruct the 140-byte header:
blob[0:108](from the job you sent) +nonce[0:32](from the submit, placed at[108:140]). - Authenticity: verify
RandomX(header140, seed) == result. (Reject otherwise — this stops a fakeresult+ cheap SHA256D from farming credit.) - Pow-hash:
pow = SHA256D( header140 + 0x20 + result )(0x20 = compact-size 32). - Block?
pow <= network_target→ submit block to daemon. - Valid share? compare the last 8 bytes of
pow(little-endian uint64 atpow[24:32]) against the workertarget— i.e.leu64(pow[24:32]) < target. CreditshareDiff = 0xFFFF…/target.
Note: difficulty/target math is the same as today's RandomX-share path. The ONLY change
is which hash you score: the double-SHA pow instead of the RandomX result. Block
detection (step 4) is what today's pool already does on every submitted share.
4. Zero-downtime migration (dual-accept)
The current fleet runs xmrig-hac (XMRig-HAC/6.25.1-hac), which submits RandomX-filtered
shares. If the pool switches to scoring pow only, those miners' shares get rejected. So:
Run both metrics during the transition. For each submit, after the RandomX authenticity check, accept the share if it clears the worker target on either:
- the RandomX hash
result(legacy xmrig-hac), or - the pow-hash
pow(drg-xmrig).
Both represent ~D RandomX attempts, so credit shareDiff identically — hashrate accounting
stays consistent across both miner types. Block detection (step 4) runs for every accepted
share regardless of metric, so legacy miners keep finding blocks too.
Distinguish miner type (for stats/telemetry only) by login user-agent:
DRG-XMRig/* vs XMRig-HAC/*.
Rollout order (important)
- Deploy the dual-accept pool first. It is backward-compatible — the existing fleet is unaffected (their RandomX shares still credit).
- Then announce / publish drg-xmrig. Early adopters' pow-hash shares now credit immediately, and their block candidates stop being dropped.
- Once the fleet has migrated, optionally retire the RandomX-share acceptance path (pow-only), which also lets you simplify/raise difficulty cleanly.
Do not announce drg-xmrig before the dual-accept pool is live, or early adopters will have shares rejected.
5. What this fixes
- Candidate gap: blocks are a subset of shares, so the pool receives 100% of candidates (the ~50% under-submission of xmrig-hac 6.25.x pool mode is gone).
- Hashrate accuracy: shares are on the block metric, so pool hashrate is directly comparable to the network hashrate.
- Nonce overlap: handled by the per-connection extranonce in nonce bytes
[112:140].