Investigating reported seal submission failures. Root cause analysis:
the miner's job-id staleness chain (worker check, quic-loop filter,
node-side job_id compare) cannot mislabel a candidate — internal and
node job ids are updated atomically together. The remaining benign race
is node-side: a block-template rebuild (new pre_hash, same parent) does
not bump the node's job counter, so an in-flight seal mined on the old
template passes the job-id check and fails seal verification, logging
"Failed to submit seal". Fixing that belongs in the chain repo (bump the
job counter on template rebuild).
Miner-side hardening in this commit:
- gpu_cpu_parity is now a two-phase fuzzer. Phase 1 dumps FULL 512-bit
hashes for randomized (header, nonce) pairs via the real
midstate-resume datapath and verifies each against the canonical CPU
implementation, multi-threaded (defaults to 1M hashes, ~5s; 10M runs
in ~15s). Phase 2 fuzzes whole mining jobs with five profiles: random,
carry-edge starts (saturated low limbs), 2^256-boundary crossings,
impossible difficulty with exact hash-count assertion, and CPU-known
solutions to catch false negatives. Seeded and reproducible; also
asserts the submitted work bytes match the nonce.
Verified clean: 10M bulk hashes + ~1,500 seals across 6 seeds.
- miner-service re-verifies every candidate on the CPU (one hash) before
sending JobResult; an engine-produced invalid seal is never submitted
and is logged loudly instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three stacked optimizations, each verified bit-exact against the CPU
reference (qp-poseidon-core) by the dual-shader component suite and a
new GPU/CPU parity example:
- mining_u64.wgsl: native 64-bit Goldilocks arithmetic with plonky2-style
lazy reduction, used automatically when the adapter supports
SHADER_INT64 (all Apple Silicon, NVIDIA, modern AMD). mining.wgsl
remains the 32-bit fallback. (+50%)
- Midstate precompute: the first two of five sponge permutations absorb
the header and high nonce half, both constant per batch; they are now
computed once on the CPU (pow_core::mining_midstate) and resumed on
the GPU. Batches are clamped so nonces never carry past 2^256. (+77%)
- Lazy second squeeze: the first squeeze yields the most significant 256
bits of the hash, which decide hash-vs-target unless exactly equal to
the target's high half, so the common reject path skips the final
permutation. (+56%)
Apple M4 throughput: 2.81 -> 11.4 MH/s at the default 1M batch
(criterion large_range_1m/gpu: 355.8ms -> 86.3ms, -75.7%).
Also:
- Fix criterion GPU bench crash: thread-local worker resources are now
tagged with an engine id so multiple GpuEngines per process never mix
devices.
- Fix stale end-to-end test harness (6-binding layout) and run the full
component suite against both shader variants.
- New examples: hashrate, gpu_cpu_parity (25 jobs incl. 2^256-boundary
crossing), gpu_features.
- Add Apple M5 family GPU tiers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>