Skip to content

Mining: reuse FiroPoW inputs and join CPU workers - #1949

Draft
reubenyap wants to merge 1 commit into
masterfrom
mining/cpu-miner-safety
Draft

Mining: reuse FiroPoW inputs and join CPU workers#1949
reubenyap wants to merge 1 commit into
masterfrom
mining/cpu-miner-safety

Conversation

@reubenyap

Copy link
Copy Markdown
Member

PR intention

Remove repeated FiroPoW header preparation from nonce loops and make the built-in CPU miner safe to start, stop, and use concurrently. Keep the existing light-cache implementation and single-worker default for testing.

Code changes brief

  • Reuse the bundled managed light epoch cache, which retains a context for each calling thread and synchronizes creation. Check for a null context before hashing.
  • Precompute the fixed header input once per background mining batch or RPC block template. Refresh after template, timestamp, difficulty, or extra-nonce changes.
  • Serialize miner start/stop, interrupt and join old workers before replacement, and clean up partially created worker groups. Keep previous-block extra-nonce history thread-local.
  • Check template/tip consistency under cs_main in both mining paths. End background batches after 256 unsuccessful hashes or one second, checked after each hash, and rebuild after a solution.
  • Add regression tests for independent header serialization, all serialized-field changes, concurrent epoch transitions, extra-nonce independence, and completed worker restart/stop.

Safety evaluation: hashing algorithms, byte conversions, difficulty rules, and normal block validation are preserved. The hashing path reads the light cache; there is no full-DAG mutation or new dependency. All current miner-controller callers were checked to be outside cs_main, so joining workers does not hold that chain lock. Stop still waits for in-progress hashing/context initialization or validation to return. Idle threads can retain an older light cache until their next epoch request or exit. Review found no outstanding correctness issue in the changes.

Validation:

  • Full native macOS arm64 Release build of firod, firo-cli, and test_firo, using pinned depends packages with assertions and hardening retained.
  • ctest --test-dir <build> -R '^(firpow_tests|miner_tests|progpow_tests)$' --output-on-failure -j1: all three suites passed (34.51 seconds), including the 55 existing FiroPoW vectors and transition/epoch-limit tests.
  • Actual crypto sources/tests passed standalone Release and ASan/UBSan checks; both new crypto cases passed TSan. Standalone sanitizer runs omit node-fixture initialization. Focused lifecycle tests also passed ASan/UBSan using the exact production controller/extra-nonce functions; the complete tests subsequently passed in test_firo.
  • Disposable, disconnected regtest nodes passed legacy and FiroPoW RPC generation, zero-attempt limits, consecutive templates, background mining with two workers, and shutdown.
  • git diff --check passed.

Performance evaluation: an Apple M3 -O2 hashing-kernel benchmark used 2,048 nonces per sample, three interleaved repeats, and untimed context/worker setup. Median rates were:

Path Workers Hashes/second
Existing wrapper 1 1,281
Prepared header 1 1,126
Prepared header 2 2,615
Prepared header 4 5,163

The initial single-worker median was 12.1% lower. A follow-up comparison on the same persistent thread, alternating old/new order, did not reproduce a consistent regression: paired throughput ratios ranged from 0.918 to 1.217. Warm managed-context lookup averaged about 6.5 ns against roughly 1 ms per hash. These variable local timings support neither a reliable single-thread speedup claim nor a consistent regression. The multicore results demonstrate concurrent hashing throughput; they do not compare against the old miner with multiple workers or establish end-to-end mining gains.

Reuse the managed light epoch cache and prepare fixed header inputs once
per mining batch. Serialize worker replacement, join interrupted workers,
and keep extra nonce history per thread. Check template/tip consistency
and bound stale work by elapsed time as well as nonce count.

Add regression tests for prepared headers, concurrent epoch changes,
independent extra nonce histories, and worker restart/stop completion.
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@reubenyap reubenyap left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 1b6c585c11a4f3a85922dbb42959e48d5d344670; one actionable issue remains.

  • [P1] Make the lock-not-held assertion safe on fresh threadssrc/miner.cpp:1254

    AssertLockNotHeld(cs_main) runs before any tracked lock has initialized this thread’s lockstack. The new lifecycle test calls GenerateBitcoins from a fresh std::async thread, and Debug CI deterministically SIGSEGVs while dereferencing that null stack in AssertLockNotHeldInternal; the base revision has no such call, while Release omits the debug lock-order check. This blocks the Debug build and can crash any otherwise valid fresh-thread caller before mining state is touched. Please make the assertion helper treat a missing stack as “no locks held,” or otherwise perform a safe non-locking initialization, then rerun miner_tests.

The prepared-header vectors, concurrent epoch checks, Release build, and the remaining platform matrix pass.

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