Skip to content

Releases: blindrun/soat-miner

v0.2.8 - Lithos security fixes (wallet-API exposure, issue #4)

Choose a tag to compare

@blindrun blindrun released this 19 Aug 00:02

Found and reported by @odiseusme in #4 — thank you. The Lithos node-API exposure was a genuine remote-wallet-control hole.

A security and correctness release for the Lithos support. Ergo pool and solo mining are unchanged. Pearl (pearl-pow) is not in this build.

Security: the Lithos quickstart no longer exposes your wallet

lithos-quickstart.sh bound the Ergo node's wallet-capable API to 0.0.0.0 with an API key hardcoded in this public repo. Any peer that could reach the port could spend from the wallet, and it survived reboots. It now binds loopback only and generates a per-install key, stored root-only. If you ran the old quickstart on a reachable host, treat that wallet as exposed.

Also hardened:

  • Ergo jar and Lithos client are fetched from pinned URLs and SHA-256 verified (first run and rerun); the Adoptium signing-key fingerprint is pinned; a mainnet install refuses an unpinned artifact.
  • Node and client run as an unprivileged per-network service account, not root, with NoNewPrivileges/ProtectSystem=strict.
  • The wallet password no longer lands in a world-readable file.
  • Testnet and mainnet fully isolate: dirs, unit names, service users, and ports.

Correctness

  • lithos-status now reaches the client (it was querying the node's port, so it always read "client DOWN").
  • A zero-target job (a Lithos client with no share target yet) no longer serves stale work or a misleading timeout; it reports what is actually happening, on both startup and mid-session.
  • The extranonce handler no longer has undefined behaviour on a malformed assignment, and stops work rather than mining a guessed nonce subspace.

Full detail in issue #4. No dev fee.

Windows: Defender will flag this as a coin-miner

Windows Defender flags every GPU miner, including this one, as a trojan (Trojan:Win32/CoinMiner, threat 2147731250) and refuses to launch it. That is the heuristic doing its job on a real miner, not a compromise of this build - the source is right here and the binary is built in CI. To run it, add a Defender folder exclusion for the miner's folder (Windows Security -> Virus & threat protection -> Manage settings -> Exclusions), or verify the SHA-256 above and run it from a folder you have excluded.

v0.2.7 - fix Vulkan wrong-hits miscompile on NVIDIA + Windows GPU-watchdog crash

Choose a tag to compare

@blindrun blindrun released this 17 Aug 21:16
ff12657

A correctness fix for the Vulkan backend, contributed by @K-Singh in #3 — thank you.

Vulkan backend computed wrong hits on NVIDIA (every share rejected)

Mining with the Vulkan build on an affected NVIDIA card, every share came back
Low difficulty share even though the miner reported a healthy hashrate and its
own local re-verification passed. NVIDIA's shader compiler miscompiled the
byte-array repack in genElement — the blake2b hash was correct, but rebuilding
the 64-bit dataset limbs from a staged uint8_t[] came back with corrupted high
bytes, so every dataset element was wrong and therefore every hit was wrong.
Nothing downstream could catch it: search() and verify() read the same wrong
table and agreed with each other. AMD (RDNA2), where this backend was developed,
compiles it correctly, which is why it hid.

The fix derives the limbs directly from the blake2b state words with byte swaps
and a mask, so there is no byte array for the compiler to get wrong. Verified on
an RTX 3070 Ti against the reference vectors, and this build still reproduces a
pinned mainnet block byte-for-byte on both backends (make test).

Windows GPU watchdog killed the dataset build

Building a 2.15 GB chunk in a single dispatch is ~2.1 s of GPU time, over
Windows' 2-second TDR limit — two runs in three died with VK_ERROR_DEVICE_LOST
before mining even started. The build is now sliced into ~130 ms dispatches; the
work and the result are identical, only the number of submissions changes.

CUDA is unaffected by both issues. No dev fee.

v0.2.6 - --mem-oc by memory type, NVIDIA GDDR6X P2-restore

Choose a tag to compare

@blindrun blindrun released this 17 Aug 20:11

--mem-oc now does the safe thing for your card automatically, chosen by
memory type, and covers NVIDIA as well as AMD. Opt-in, off by default,
Linux only (the clock control it uses does not exist on Windows), and the clock
is put back when the miner stops.

  • NVIDIA GDDR6X (4090 / 4080 / 4070-family, 3090 / 3080 / 3070 Ti): restores
    the P2 memory downclock back to the rated speed - about 2.5%. That is undoing a
    downclock the driver imposes under compute load, not an overclock.
  • AMD GDDR6 (RX 7000 / 6000): raises the memory a conservative amount over
    stock via overdrive - a 7900 XT reaches 1325 MHz, about 5%. Needs
    amdgpu.ppfeaturemask=0xffffffff on the kernel command line + a reboot, and
    the miner tells you so if it is off.
  • GDDR6 / GDDR7 NVIDIA cards have no P2 downclock, so they are left alone;
    use --mclk-offset N by hand if you know your card.

No dev fee. make test green on both backends.

v0.2.5 - stratum & dispatch correctness fixes (issue #2)

Choose a tag to compare

@blindrun blindrun released this 17 Aug 19:51

Six correctness fixes in the stratum and dispatch paths, all from an external
audit (issue #2, thanks @odiseusme) and verified against the code:

  1. Robust socket writes - the send path now writes the whole buffer or fails,
    so a short write can't send truncated JSON as a successful share; it uses
    MSG_NOSIGNAL and ignores SIGPIPE, so a pool disconnecting mid-send no longer
    kills the miner.
  2. Job id travels with the job - a new block arriving mid-batch can no longer
    cause a solution to be submitted under the wrong job id and rejected.
  3. Nonce stays in your subspace - a launch that would cross the owned-nonce
    boundary is clamped, so no work leaks into the pool's extranonce prefix.
  4. --batch is validated - clamped to a non-zero multiple of 256, closing the
    overlap / infinite-retest / skip-and-overstate cases.
  5. Vulkan memory barrier - the dataset build's writes are now a guaranteed
    dependency for the search reads, not just fence-ordered.
  6. Lenient JSON - trailing whitespace in a pool's numeric fields no longer
    silently drops the subscribe reply onto the default extranonce.

No dev fee. make test green on both backends.

v0.2.4 - Lithos test-network-ready + solution-buffer hardening

Choose a tag to compare

@blindrun blindrun released this 17 Aug 18:42

Lithos is now test-network-only, not experimental. The Lithos stratum support
is tested end to end against a live Lithos client (v4.2.0) on the Ergo test
network: the miner connects, receives real jobs, and its shares are accepted by
the client (95 accepted / 0 rejected in the run that cleared it), not just checked
against the mock. It has not been validated on mainnet yet, so run it on
testnet only for now - the bundled lithos-quickstart.sh defaults to testnet on
purpose. See the "Lithos" section of the README for the from-scratch guide.

Hardened the search solution buffer. One search batch at a deliberately low
difficulty (exactly the Lithos-test regime) can find far more than the old
32-solution buffer held, and anything past it was silently dropped - a bug that
scales with hashrate and masquerades as flaky hardware. The buffer is now 256
(still 10 KB) and the miner warns when a batch overflows instead of losing shares
invisibly.

No dev fee. make test green on both backends.

v0.2.3 - conservative memory OC + per-GPU --device

Choose a tag to compare

@blindrun blindrun released this 17 Aug 06:17

Two additions, both opt-in and off by default.

--mem-oc — a conservative memory overclock chosen by GPU generation
(memory is the same across a generation, so one validated value covers it).

On AMD it raises the memory clock a safe amount over stock through the amdgpu
overdrive sysfs table: it resets the table to defaults first so a bump never
compounds on an already-raised clock, reads the true stock, applies stock+bump
clamped to the driver's range, and puts the clock back when the miner stops.
RDNA3 ships +75 MHz - a 7900 XT measured stable at +100 and correctness-verified,
crashing at +150, so +75 leaves margin - worth about 5%. RDNA2 gets a smaller
+50; anything unproven is left alone. It needs amdgpu overdrive enabled
(amdgpu.ppfeaturemask=0xffffffff on the kernel command line, then reboot) and
root, and it tells you exactly that if it is off. On NVIDIA it points you at
--mclk-offset instead, which undoes the P2 downclock.

--device N picks the GPU (CUDA now has it too; Vulkan already did). Run one
process per card for a multi-GPU rig, each with its own --device and
--mem-oc:

./soat-miner --device 0 --mem-oc --pool ... &
./soat-miner --device 1 --mem-oc --pool ... &

One process per card means a hung overclock on one GPU cannot take the others
down. A single process driving every GPU at once is not built yet.

No dev fee. Verified: 7900 XT 1250 -> 1325 MHz, reset-on-exit confirmed, make
test green on both backends.

v0.2.2 - streaming loads, +8-21% on CUDA

Choose a tag to compare

@blindrun blindrun released this 17 Aug 04:51

CUDA got 8-21% faster from a one-line change: the dataset reads now use
streaming loads (__ldcs) instead of the read-only data cache (__ldg).

The dataset is 7.27GB and any given element is reused about 0.5% of the time, so
caching each one only evicts others and starves the 33 random reads per nonce
that are the whole bottleneck. Telling the hardware the data will not be reused
stops the cache fighting itself.

Measured, interleaved, at the 7.27GB dataset:

GPU before after gain
RTX 4090 217.5 235.5 +8.3%
RTX 4080 120 140 +16.7%
RTX 4070 SUPER 97.9 117.6 +20%
RTX 4060 Ti 63.5 76.9 +21%

It helps more on smaller cards, where the cache is smaller relative to the
dataset. The 4090 now matches the fastest closed-source miner we can measure
like-for-like (SRBMiner ~235 at the same dataset size), with no dev fee.

Correctness is unchanged - a cache hint does not change the value loaded, and
make test still reproduces mainnet block 500012 through search()/verify() and
byte-for-byte on the Vulkan path. CUDA only; Vulkan (AMD, RTX 50-series) is
unchanged because GLSL has no clean non-temporal load qualifier. No dev fee.

v0.2.1 - Windows CUDA build

Choose a tag to compare

@blindrun blindrun released this 17 Aug 01:04

Windows now ships the CUDA build. It used to be Vulkan-only because nvcc cannot
cross-compile from Linux; it is built on Windows in CI now and folded into the
archive.

Windows (soat-miner_v0.2.1_Win64.zip) carries both backends. soat-miner.bat
picks by GPU: CUDA on 40-series and older (about 34% faster on Ada), Vulkan on
Blackwell and on AMD/Intel. The CUDA binary is a multi-arch fat build (Turing,
Ampere, Ada native, plus PTX for Hopper and Blackwell) with the CUDA runtime
linked statically, so there is no cudart64 DLL to chase and no Toolkit to
install. It was verified to run on a machine with no CUDA Toolkit present.

Measured CUDA hashrate at the 7.27 GB dataset: 4080 125.3, 4070 SUPER 97.9,
4060 Ti 63.5 MH/s.

No source change to the miner itself. No dev fee, still.

v0.2.0

Choose a tag to compare

@blindrun blindrun released this 16 Aug 20:36

Autolykos v2 miner for Ergo. CUDA and Vulkan, Linux and Windows, pool and solo, no dev fee.

What's new

  • Build the next block's dataset ahead of time (--cache-dag, CUDA). Ergo's
    dataset changes every block; building the next one in the background removes
    the rebuild stall when a block arrives. Auto-skips when it will not fit in VRAM.
  • Lithos support (experimental)--lithos mines to a local
    Lithos client. Verified against a
    mock built from the Lithos client's own source, not yet against a live client
    end to end. See the README. The rest of the miner is unaffected.
  • Payout address is now printed on startup, and the shipped config no longer
    carries a real default address, so nobody mines to it by accident. Thanks
    @odiseusme for the report (#1).

Tested this release

  • RTX 4090, CUDA: 217 MH/s, pool shares accepted.
  • RX 6700 XT, Vulkan: 82 MH/s, pool shares accepted.

Downloads

  • Linux (CUDA + Vulkan): soat-miner_v0.2.0_Lin64.tar.gz
  • Windows (Vulkan): soat-miner_v0.2.0_Win64.zip

Unzip, edit WALLET in config.txt or a mine_ergo_* script, and run.

SOAT Miner v0.1.2 - NVIDIA Vulkan was 50x too slow

Choose a tag to compare

@blindrun blindrun released this 16 Aug 01:56

If you have an NVIDIA card, replace v0.1.1. It was giving you about 3 MH/s.

Vulkan was 50x too slow on NVIDIA

The dataset was not allocated as a dedicated allocation, so the driver never
gave it large pages. Every one of the 33 random lookups per nonce missed the
TLB. The card sat at 100% utilisation doing almost nothing.

Measured at the current 7.27GB dataset:

GPU v0.1.1 v0.1.2
RTX 5080 5.7 267.6
RTX 4090 2.9 162.5
RX 6700 XT 82.9 82.9

AMD was never affected. Memory utilisation on the 5080 went from 4% to 99%.

The CUDA build only ran on 40-series cards

v0.1.1 shipped one cubin, sm_89, and no PTX. On anything else it refused to
start with "no kernel image is available for execution on the device".

Two causes. The architecture list was hardcoded to Ada. And separable
compilation was throwing away the PTX, so there was no fallback either.

Now it builds sm_75, sm_86, sm_89 and sm_120 where the toolkit supports them,
plus PTX so newer cards still work. The list comes from asking nvcc what it can
target instead of being written down.

Backend auto now goes by GPU, not by brand

Vulkan is faster on Blackwell. CUDA is faster on Ada. Both were measured on
Linux and Windows and they agree.

GPU picks margin
RTX 5080 Vulkan 22%
RTX 4090 CUDA 34%
RX 6700 XT Vulkan only option

Leave BACKEND=auto alone and it sorts itself out.

Building on Windows never worked

The CMake build did not compile run.cpp or stratum.cpp, so it failed to link.
It is the only supported way to build CUDA on Windows. Fixed and tested on a
5080 with CUDA 12.9.

RTX 50-series needs CUDA Toolkit 12.8 or newer for native code. Older toolkits
fall back to PTX and still work.

Also

  • --list-devices works in the CUDA build. It used to start mining instead.
  • The Vulkan backend is now checked by make test against the same mainnet block
    as CUDA, with a negative control. Nothing was gating it before.
  • The README is half the length and tells you how to mine in the first screen.

Verify your download

fccfc03fcb9764c8fedb196515ecdd0afa02f6f7aa2f328ba6df6b50127f35b9  soat-miner_v0.1.2_Lin64.tar.gz
f947d00359a2df1e607f4b237a28186f11e9c36e004a7c58b22705615ba37f25  soat-miner_v0.1.2_Win64.zip

The Windows zip is the Vulkan build only. CUDA cannot be cross compiled from
Linux. Build it from source if you want CUDA on Windows.