fix(mining): restore the miner after a benchmark only if it was running

Cancelling a thread benchmark always stopped and restarted the pool
miner at its pre-benchmark thread count, even when the user had not been
mining before the benchmark began. That silently started the miner on a
plain cancel or a switch to solo mode.

- A cancel now always drops the candidate-thread miner, and restarts the
  pool miner only when the user was mining before the benchmark, read
  from a snapshot taken at the start rather than the live running state
  (the benchmark sweep transiently stops the miner between candidates,
  so a live check would drop the restore).
- Callers that must not restore the miner (leaving solo mode) pass the
  new restore flag as false.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-13 16:00:10 -05:00
co-authored by Claude Opus 4.8
parent 13989cf268
commit fae5ef05b9
5 changed files with 28 additions and 12 deletions
+8
View File
@@ -88,6 +88,14 @@ bool ThreadBenchmark::active() const
return phase != Phase::Idle && phase != Phase::Done;
}
ThreadBenchmarkCancel PlanThreadBenchmarkCancel(const ThreadBenchmark& benchmark)
{
ThreadBenchmarkCancel plan;
plan.restartThreads = benchmark.prev_threads;
plan.restartMiner = benchmark.was_pool_running && benchmark.prev_threads > 0;
return plan;
}
ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark,
float deltaSeconds,
double poolHashrate10s)
+9
View File
@@ -59,6 +59,15 @@ struct ThreadBenchmarkUpdate {
bool inconclusive = false; // finished with no nonzero hashrate sample — caller should warn
};
// What a user-initiated cancel of an active benchmark must do with the miner. Always drop the candidate-thread
// miner; restart only if the user was mining BEFORE the benchmark (snapshot, not live state - the sweep
// transiently stops the miner, so a live check would drop the restore, L-04/L-11).
struct ThreadBenchmarkCancel {
bool restartMiner = false;
int restartThreads = 0;
};
ThreadBenchmarkCancel PlanThreadBenchmarkCancel(const ThreadBenchmark& benchmark);
ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark,
float deltaSeconds,
double poolHashrate10s);
+1 -1
View File
@@ -117,7 +117,7 @@ void RenderMiningModeToggle(App* app, const WalletState& state, const MiningInfo
s_pool_mode = false;
app->settings()->setPoolMode(false);
app->settings()->save();
CancelMiningBenchmark(app); // don't leave a pool benchmark running after switching to solo (L-11)
CancelMiningBenchmark(app, false); // don't leave a pool benchmark running after switching to solo (L-11)
app->stopPoolMining();
}
if (soloHov) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
+8 -9
View File
@@ -55,17 +55,16 @@ bool IsMiningBenchmarkActive() {
return s_benchmark.active();
}
void CancelMiningBenchmark(App* app) {
void CancelMiningBenchmark(App* app, bool restoreMiner) {
if (!s_benchmark.active()) return;
const int restoreThreads = s_benchmark.prev_threads;
const ThreadBenchmarkCancel plan = PlanThreadBenchmarkCancel(s_benchmark); // read BEFORE reset() zeroes both fields
s_benchmark.reset();
// Restore the miner to its pre-benchmark thread count. A benchmark runs in pool mode, so restore
// regardless of the instantaneous running state — the sweep may be mid inter-candidate stop, where an
// isPoolMinerRunning() check would be transiently false and silently drop the restart. (L-04, L-11)
if (app && restoreThreads > 0) {
app->stopPoolMining();
app->startPoolMining(restoreThreads);
}
if (!app) return;
// Always drop the candidate-thread miner. Restore only if the user was mining before the benchmark, using the
// was_pool_running SNAPSHOT (not the live state: the sweep may be mid inter-candidate stop). (L-04, L-11)
app->stopPoolMining();
if (restoreMiner && plan.restartMiner)
app->startPoolMining(plan.restartThreads);
}
// Miner-update version check (one shot per session): fetches the latest DRG-XMRig release tag in
+2 -2
View File
@@ -22,11 +22,11 @@ void RenderMiningTab(App* app);
bool IsMiningBenchmarkActive();
/**
* @brief Cancel a running thread benchmark and restore the miner to its pre-benchmark thread count.
* @brief Cancel a running thread benchmark and restore the miner only if it was running before the benchmark.
* Safe to call when no benchmark is active (no-op). Used when leaving the Mining tab or switching to
* solo mode so the miner isn't left stuck at a benchmark step. (L-04, L-11)
*/
void CancelMiningBenchmark(App* app);
void CancelMiningBenchmark(App* app, bool restoreMiner = true);
} // namespace ui
} // namespace dragonx