Skip to content

fix(c3/s2): correct HW SHA full double-hash instead of software (#34) - #39

Merged
SneezeGUI merged 2 commits into
mainfrom
fix/c3-s2-hw-sha
Sep 19, 2026
Merged

SneezeGUI merged 2 commits into
mainfrom
fix/c3-s2-hw-sha

Conversation

@SneezeGUI

Copy link
Copy Markdown
Owner

Draft — contains new hardware register sequencing that has not been tested on a physical C3 yet.

Problem

ESP32-C3 mines in software at ~1 KH/s (#34). Cause: single-core SoCs only spawned the software miner task; the HAL HW path was dead code — and it used the same unsupported SHA_H+SHA_CONTINUE midstate restore as the S3 bug (#28), so routing C3 to it would also yield 0 shares.

Fix

  • Implements sha256_ll_double_hash_full() for S2/S3/C3 using the legitimate START → CONTINUE flow (no midstate injection), reusing this file's proven helpers.
  • Routes single-core builds to it at low priority with frequent yields (so WiFi/Stratum stay alive on the one core).
  • Software-verify gate: every HW candidate is re-hashed in software before submitting, so a wrong HW hash can never become a bad share. Worst case if the HW sequence is off = 0 shares + [HW-DBG] output, never a bad submission.
  • Boot banner now honestly reports Hardware SHA (C3 envs).

⚠️ Testing (required before merge)

  • Flash a real ESP32-C3 with -D DEBUG_SHARE_VALIDATION; confirm [HW-DBG] ... SW verify=PASS and shares at the pool, hashrate well above 1 KH/s.

Closes #34.

)

ESP32-C3/S2 builds were mining in pure software (~1 KH/s) because
setupTasks() spawned the software miner_task_core0 on single-core SoCs;
the hardware HAL mining task (miner_task_core1) was never instantiated and
was effectively dead code. The reporter's "Software (Optimized)" banner and
low hashrate were the symptom.

Simply routing C3 to the old HAL task would NOT have worked: its
sha256_ll_double_hash() restores a midstate into SHA_H and issues
SHA_CONTINUE, which the S2/S3/C3 SHA engine ignores (the same root cause as
the S3 zero-shares bug, #28). So this:

- Implements sha256_ll_double_hash_full() for S2/S3/C3 (previously a stub
  returning false). It hashes block 1 + block 2 with the legitimate
  START -> CONTINUE flow and the second SHA with a fresh START -- no
  external midstate injection -- which is correct on every variant. It
  re-hashes block 1 each nonce (no midstate cache), trading a little speed
  for correctness; still far faster than software.
- Rewrites the C3/S2 miner_task_core1 to mine with that HW path and
  re-verify every candidate in software (miner_sha256_header) before
  submitting, so a wrong HW hash can never become a bad share. Enable
  -D DEBUG_SHARE_VALIDATION to log PASS/FAIL per candidate.
- Routes single-core builds to miner_task_core1 at low priority with
  frequent yields, so WiFi/Stratum/Monitor stay responsive on the one core.
- Fixes the boot banner: C3 envs now define USE_HARDWARE_SHA (was the dead
  USE_SOFTWARE_SHA), so the reported SHA implementation is honest.

Needs on-device confirmation on an ESP32-C3 (watch for [HW-DBG] SW
verify=PASS lines and shares landing at the pool).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jmarquez84 pushed a commit to jmarquez84/SparkMiner that referenced this pull request Jul 22, 2026
jmarquez84 added a commit to jmarquez84/SparkMiner that referenced this pull request Jul 22, 2026
…fallback

The raw-register HW path has never run on real C3/S2 silicon. If the
register sequence disagrees with the chip, the failure mode is silent:
fast hashrate counter, zero shares, no logs (#34). Adds a boot-time
known-vector check (all-zero header, nonce 0x0000C4E6, true double-SHA
starts 0x000025EE so both 16-bit early-reject gates pass) comparing
sha256_ll_double_hash_full against the software reference; on mismatch
the miner task falls back to the software path (pre-#39 behavior).

Also corrects the root-cause comments: S2/S3/C3 SHA_H digest-state
registers expect big-endian state words (espressif/esp-idf#12440) --
the midstate path seeded little-endian -- rather than 'ignores SHA_H
writes on CONTINUE'.

Co-Authored-By: Claude <noreply@anthropic.com>
@SneezeGUI
SneezeGUI marked this pull request as ready for review September 19, 2026 18:46
@SneezeGUI

Copy link
Copy Markdown
Owner Author

Full review done against main, cross-checked against the on-hardware self-test data from #32. Now marked ready and merged.

What holds up

  • The new S2/S3/C3 branch in sha256_ll_double_hash_full (sha256_ll.cpp) is the legitimate flow: block1 → SHA_START, block2 → SHA_CONTINUE, then ll_fill_inter_block() + SHA_START for the second hash. No SHA_H injection — that's the ESP32S3: S3 share validation - SW verify=FAIL hash[28-31] #28 failure mode, avoided.
  • The register conventions it reuses are proven on real S3 silicon by Add support for Heltec WiFi LoRa 32 V3 (ESP32-S3 + SSD1306 OLED) #32's boot log (test=1 hw_full_64_from_iv match=PASS, [S3-SHA2] hw_block_match=PASS hw_fast_match=PASS): BE words into SHA_TEXT, START from IV, bswapped digest out of SHA_H, H→TEXT inter-block. C3/S2 use the same programming model.
  • Submit path mirrors the proven S3 pattern: software re-hash per candidate, submit only on PASS. A wrong HW hash can't become a bad share.
  • Merges clean with main (including the just-merged fix(s3): mine first SHA in software to fix zero-shares (#28, #10, #5) #36) — disjoint paths, S3 dual-core vs single-core fallback. CI 3/3 green, including esp32-c3-supermini.

The change that unblocked merging
The failure mode if C3 silicon disagreed was silent: no env sets DEBUG_SHARE_VALIDATION, so we'd ship "fast hashrate, 0 shares, no logs" — worse than today's ~1 KH/s, which at least mines. Added a one-shot boot self-test: a fixed known vector (all-zero header, nonce 0x0000C4E6, true double-SHA starts 0x000025EE, so both 16-bit early-reject gates pass and full digests are written) through the HW path vs the software reference. On mismatch the boot log says so loudly and the miner task falls back to software (pre-#39 behavior). C3 can now disagree safely and visibly instead of silently.

Also corrected the root-cause comments while in here: the S2/S3/C3 SHA_H digest-state registers expect big-endian state words (espressif/esp-idf#12440) — the old midstate path seeded little-endian — rather than "ignores SHA_H writes on CONTINUE". Same conclusion (no injection here), accurate mechanism.

#34 — @bwhiteman21-commits the flash test is still worth running on real C3 silicon; with this merged a stock build reports at boot whether the HW path passed its self-test, which makes your report a one-liner. Hashrate should jump from ~1 KH/s by a couple of orders of magnitude; if the self-test FAILs on your board, that log line is exactly what I need.

@SneezeGUI
SneezeGUI merged commit e53199e into main Sep 19, 2026
3 checks passed
trcjr pushed a commit to trcjr/SparkMiner that referenced this pull request Sep 22, 2026
…se automation

- Bump AUTO_VERSION to v2.9.6-pre across all envs
- README: honest S3 (~50-55 KH/s, software-verified) and C3 (pending
  validation) numbers; old 280-400 KH/s figures were invalid shares
- CHANGELOG entry for everything in this batch (SneezeGUI#36 SneezeGUI#37 SneezeGUI#38 SneezeGUI#39 SneezeGUI#44 SneezeGUI#45)
- build.yml: upload factory-bin test builds on every PR
- release.yml: tag-triggered build of all 17 targets + GitHub Release
  with factory/firmware bins (uses post_build_merge.py output)

Co-Authored-By: Claude <noreply@anthropic.com>
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.

C3 using bitsy software at 1k H/s not compiled HW SHA

1 participant