Skip to content

main: make /gen actually mine - #42

Merged
Bitflash-sh merged 1 commit into
Bitflash-sh:mainfrom
ericscalibur:fix/headless-solo-mining
Jul 30, 2026
Merged

main: make /gen actually mine#42
Bitflash-sh merged 1 commit into
Bitflash-sh:mainfrom
ericscalibur:fix/headless-solo-mining

Conversation

@ericscalibur

Copy link
Copy Markdown
Contributor

nMineMode defaults to MINE_RELAY (0) and ParseStartupArguments() never changed it, so a node started with /gen would spawn ThreadBitcoinMiner, enter BitcoinMiner(), hit

if (nMineMode == MINE_RELAY)
    return true;

and return before doing any work. The node then ran indefinitely looking completely healthy -- it synced, it held peers, it reported no errors -- while earning nothing. Nothing in the log said otherwise; the only hint was nMineMode = 0 in a startup line that reads like a status echo.

This affects every headless miner, because the GUI is the only other way to select a mining mode.

/gen now implies MINE_SOLO unless /operator or /participant asked for something else. Verify with nMineMode = 1 at startup.

nMineMode defaults to MINE_RELAY (0) and ParseStartupArguments() never changed
it, so a node started with /gen would spawn ThreadBitcoinMiner, enter
BitcoinMiner(), hit

    if (nMineMode == MINE_RELAY)
        return true;

and return before doing any work. The node then ran indefinitely looking
completely healthy -- it synced, it held peers, it reported no errors -- while
earning nothing. Nothing in the log said otherwise; the only hint was
`nMineMode = 0` in a startup line that reads like a status echo.

This affects every headless miner, because the GUI is the only other way to
select a mining mode.

/gen now implies MINE_SOLO unless /operator or /participant asked for something
else. Verify with `nMineMode = 1` at startup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ericscalibur
ericscalibur force-pushed the fix/headless-solo-mining branch from 4195e61 to c4c1bc7 Compare July 30, 2026 05:01
Vic-Nas added a commit to Vic-Nas/bitflash-mod that referenced this pull request Jul 30, 2026
…sh#37); fix /gen not actually mining (port of Bitflash-sh#42)

Two real gaps, both pulled from upstream, both squarely in "the
command line has been neglected" territory.

## Headless build (Bitflash-sh#37)

The GUI binary needs libGL present at load time even when started
with -nogui/-daemon: the dynamic loader resolves every dependency
before main() runs, so the flag arrives far too late. A clean server
-- where a node most naturally lives -- fails outright with a shared-
library error that gives no hint the program would otherwise work
fine. The AppImage additionally needs FUSE, which minimal servers
lack.

`make linux-node-build` (wired into both `linux` and `linux-self`)
produces a second binary, `$(APPNAME)-node-<version>-x86_64`, from
the same node objects, without ImGui/GLFW/OpenGL at all -- no
graphics or FUSE dependency. Two small moves were needed: headless.cpp
provides an empty MainFrameRepaint() (declared in headers_core.h,
previously only ever defined in gui.cpp, which a headless build
doesn't compile), and DateTimeStr moved from gui.cpp to util.cpp
since it's not actually GUI-specific.

Adapted rather than copied: our src/Makefile carries extra objects
(nostr/compactblock/update) and the mandatory REPO/UPDATE_PUBKEY (or
NO_UPDATE=1) machinery upstream doesn't have. Caught one real bug
while wiring the root Makefile's linux-node-build target: forwarding
NO_UPDATE unconditionally (even as an empty value) would have made
`ifdef NO_UPDATE` true in the child invocation regardless -- GNU
Make's ifdef checks whether a variable was set at all, not whether
it's non-empty -- silently disabling the updater in every node build,
including regular (non-self) ones. Branched explicitly instead.

## /gen not mining (Bitflash-sh#42)

nMineMode defaults to MINE_RELAY and nothing in ParseStartupArguments
ever changed it for the plain /gen case (only /operator and
/participant set their own mode) -- so a node started with /gen alone
spawned ThreadBitcoinMiner, hit BitcoinMiner()'s relay guard, and
returned immediately. The node ran indefinitely looking completely
healthy -- synced, held peers, no errors -- while mining nothing, with
the only hint being nMineMode = 0 in a startup line that reads like a
status echo. This affects every headless miner, since the GUI was the
only other way to select a mining mode. /gen now implies MINE_SOLO
unless /operator or /participant asked for something else.
@Bitflash-sh

Copy link
Copy Markdown
Owner

Confirmed, and it is worse than the description claims — I found this running against our own infrastructure while reviewing.

The bootstrap seed node on our VPS has been up for 15h28m with -nogui -debug -gen. Its log:

nMineMode = 0, strParticipantPool = , fGenerateBitcoins = 1

BitcoinMiner started appears zero times, and the process sat at 8.7% CPU — RandomX in fast mode pins a core. It mined nothing for over fifteen hours while every other signal said it was healthy. Exactly the failure mode you describe.

Verified your fix on a clean datadir:

nMineMode = 1, strParticipantPool = , fGenerateBitcoins = 1
[net] BitcoinMiner started
RandomX: dataset ready (fast mode active)
[net] BitcoinMiner: mining with RandomX (fast 2GB)

This is a regression, not a long-standing gap. I bisected it to 294d8f7, the refactor that introduced mining modes, first shipped in v1.2.0. Before that commit /gen only needed to set fGenerateBitcoins, because BitcoinMiner() had no mode gate to return at. So every headless miner from v1.2.0 through v1.2.4 has been mining nothing. GUI users were unaffected — the interface sets a mode explicitly — which is why this went unnoticed for four releases.

On the patch itself: placing it inside the /gen branch and guarding on nMineMode == MINE_RELAY is the right call. /operator and /participant are parsed after it and still win, so -gen -operator correctly stays MINE_OPERATOR. Minimal and in the right spot.

One note, not a change request: /solomine alone still leaves fGenerateBitcoins at 0, so it never spawns the miner thread. That reads as intended — it is a modifier for the peer-wait check, not a mode selector — but it means -solomine without -gen is silently inert. Separate concern from this PR.

Reviewed clean. Nice catch, and thank you for writing it up with the log line that gives it away.

@Bitflash-sh
Bitflash-sh merged commit bb63a99 into Bitflash-sh:main Jul 30, 2026
@Bitflash-sh Bitflash-sh mentioned this pull request Jul 30, 2026
Bitflash-sh added a commit that referenced this pull request Jul 30, 2026
Headless mining fix (#42), ARM64 build (#41), format-string
checking (#44), gitignore for key material (#43).

#42 is the reason this release exists: -gen has mined nothing on
headless nodes since v1.2.0.
@Bitflash-sh

Copy link
Copy Markdown
Owner

Shipped in v1.2.5, along with #41 and #43. Thank you — three PRs, three real bugs, and the diagnosis was right in each one.

#42 got top billing in the release notes. It deserved it: four releases of headless miners earning nothing with no way to tell, and our own bootstrap seed was one of them.

Verified on the merged tree before tagging, both platforms:

nMineMode = 1, fGenerateBitcoins = 1
[net] BitcoinMiner started
[net] BitcoinMiner: mining with RandomX (fast 2GB)

One thing your report led to that is worth flagging, since it is the same shape as the bug you found. #5 was a Linux segfault while syncing — root cause was %I64d, an MSVC-only specifier that glibc mis-parses into a pointer dereference. GCC had been reporting it the whole time and -w was swallowing it. But removing -w alone changed nothing, because every format string here goes through strprintf / error / OutputDebugStringF and none carried a format attribute, so the compiler never inspected a single one. Both are fixed in #44 — that class of bug now fails the build instead of shipping.

Three of your four findings share a root: something was broken and nothing said so. Worth keeping in mind if you keep looking around this codebase — silence is where the bugs are hiding.

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.

2 participants