SV2 pool identity: persistent authority key for miner pinning (+ stats correctness fixes) - #31
Merged
Merged
Conversation
The Noise authority key now persists across restarts in
[sv2] authority_key_file (created on first start with owner-only
permissions, the same pattern as bitcoind's .cookie), so the pool keeps
a stable identity that miners can pin. The base58check public key (SRI
key-utils format) is logged at startup, shown in the dashboard Connect
modal with a copy button, and returned by GET /api/info as
sv2_authority_pubkey. persist_authority_key = false opts back into a
fresh key per process; cert_validity_secs makes the certificate window
configurable (default one year).
Upgrade note: with SV2 enabled the pool now fails at boot if it cannot
create the key file. Deployments with a read-only working directory
(e.g. the shipped systemd unit with ProtectSystem=strict) must point
authority_key_file at a writable path; comments added to the unit file
and docker-compose.yml.
Verified on hardware against a NerdQAxe++ (AxeOS SV2): pinned key
verifies and mines, wrong authority key is rejected before a channel
opens. New tests drive real handshakes against a pinning
noise_sv2::Initiator (correct/wrong/expired/no-pin) plus key-file
round-trip and permission checks.
Also in this change:
- Dashboard Copy buttons now work over plain HTTP: fall back to
document.execCommand('copy') outside secure contexts instead of
showing "Copied" without copying.
- Duplicate-share tracking records a share only after validation passes
and clears on clean-job broadcasts, so invalid submissions cannot
occupy dedup slots and replay protection is scoped to live jobs.
- Pool best-share/best-hashrate writes are monotonic (SQL "?1 >" guards
plus a CAS on the in-memory best hashrate).
- Blocks accepted by the background submit retrier now update dashboard
stats, not just Prometheus.
CodeQL's hard-coded-cryptographic-value rule reads the mining header nonce as a cryptographic nonce and flags any constant flowing into it (three critical alerts on PR #31, all in test data). Generate the test keys from a range like the FIFO-eviction test already did, which the rule accepts.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
By default SV2 connects encrypted but the pool has no stable identity to verify: the Noise authority key was generated fresh per process, so there was nothing a miner could pin. This makes the authority key persistent and easy to pin, closing the pool-side half of the story that bitaxeorg/ESP-Miner#1796 and shufps/ESP-Miner-NerdQAxePlus#656 close on the miner side.
[sv2] authority_key_file(defaultsv2-authority.key), created on first start with owner-only permissions, the same pattern as bitcoind's.cookie.key-utilsformat) is logged at startup, shown in the dashboard Connect modal with a copy button, and returned byGET /api/infoassv2_authority_pubkey.persist_authority_key = falseopts back into a fresh key per process.cert_validity_secsmakes the signed certificate window configurable (default one year).Upgrade note (why this is 0.6.0)
With SV2 enabled the pool now creates the key file at boot and fails loudly if it cannot. Deployments with a read-only working directory (the shipped systemd unit uses
ProtectSystem=strict) must setauthority_key_fileto a writable path such as/var/lib/solo-pool-rs/sv2-authority.key, or setpersist_authority_key = false. Comments added to the unit file and docker-compose.yml; per the pre-1.0 convention (breaking bumps minor) this ships as 0.6.0.Also in this PR
navigator.clipboardonly exists in secure contexts; the old code showed "Copied" without copying on the LAN dashboard. Now falls back todocument.execCommand('copy'), with an honest "Copy manually" state if that fails too.duplicate), and the per-session set clears on clean-job broadcasts, scoping replay protection to live jobs instead of FIFO eviction.?1 > ...guards (matching the per-worker variant) and the in-memory best-hashrate update is a CAS loop.Testing
cargo fmt --check,clippy --all-targets --all-features(no warnings),cargo test(62 passed),cargo build --releaseall green.noise_sv2::Initiator: correct key accepted, wrong authority key rejected, certificate outside its validity window rejected, no-pin still connects; plus key-file round-trip/permissions and dedup lifecycle tests.