Best (session): use only client.best_diff so it actually resets

Math.max(client.best_diff, worker.best_diff) defeated the whole
point of the column. ckpool keeps two separate counters:

  stratum_instance.best_diff  — per TCP session, in memory only,
                                freed on disconnect, gone on
                                ckpool restart.
  worker_instance.best_diff   — per worker name, persisted to the
                                logdir, restored on ckpool restart,
                                survives client disconnects.

Falling back to worker.best_diff when the client value was lower
meant the displayed "session" diff carried over the very events
(miner disconnect, pool restart) that should reset it.

Switch every "Best (session)" computation to read only the live
stratum_instance value. Offline workers — those with a worker
record but no current client — show 0, which is correct: there is
no current session to have a best in.
This commit is contained in:
satoshi
2026-04-26 18:13:18 +03:00
parent 208153bbee
commit ea4c514d78
3 changed files with 24 additions and 24 deletions
+9 -9
View File
@@ -3,12 +3,13 @@
import { formatDifficulty } from "../format"; import { formatDifficulty } from "../format";
import type { StratumClient } from "../types"; import type { StratumClient } from "../types";
// Join client data into worker rows so the "session best" column // "Best (session)" = best diff in the current stratum TCP session,
// matches what the Miners table renders for the same worker. // i.e. only ckpool's stratum_instance.best_diff. Resets on miner
// ckpool's reset_bestshares() zeroes both worker.best_diff and // disconnect (the instance is freed) and on pool restart (in-memory
// client.best_diff when the pool finds a block, but timing or // state, not persisted). worker.best_diff is a separate persistent
// reconnect can leave the two briefly divergent — take the larger // counter that survives both events, so we deliberately don't fall
// of the two to stay consistent with the Miners table. // back to it — that fallback was the bug. Offline workers have no
// current session, so their session-best is 0.
const rows = $derived.by(() => { const rows = $derived.by(() => {
const ws = snap.data?.workers ?? []; const ws = snap.data?.workers ?? [];
const cs = snap.data?.clients ?? []; const cs = snap.data?.clients ?? [];
@@ -19,11 +20,10 @@
} }
const enriched = ws.map((w) => { const enriched = ws.map((w) => {
const c = clientByWorker.get(w.worker); const c = clientByWorker.get(w.worker);
const sessionBest = Math.max(c?.bestdiff ?? 0, w.bestdiff);
return { return {
worker: w.worker, worker: w.worker,
sessionBest, sessionBest: c?.bestdiff ?? 0,
bestEver: w.bestever || sessionBest, bestEver: w.bestever || w.bestdiff,
}; };
}); });
enriched.sort((a, b) => b.bestEver - a.bestEver); enriched.sort((a, b) => b.bestEver - a.bestEver);
+11 -9
View File
@@ -35,20 +35,20 @@
const wname = c.workername || `${c.address}.unnamed`; const wname = c.workername || `${c.address}.unnamed`;
seen.add(wname); seen.add(wname);
const w = byWorker.get(wname); const w = byWorker.get(wname);
// "Session best" is the larger of the live stratum client's // "Session best" = best diff for *this stratum TCP session*.
// best_diff and the worker_instance's best_diff. ckpool's // ckpool zeroes stratum_instance.best_diff when the connection
// reset_bestshares() clears both when the pool finds a block, // ends and on pool restart (in-memory only), so this is the
// but reconnect / timing can leave them briefly divergent — // value that should reset on miner disconnect / pool restart.
// max() keeps this column aligned with the leaderboard. // Don't fall back to worker.best_diff — that's the persistent
const sessionBest = Math.max(c.bestdiff, w?.bestdiff ?? 0); // round counter and would defeat the reset semantics.
out.push({ out.push({
workerName: wname, workerName: wname,
user: c.address, user: c.address,
hardware: detectHardware(c.useragent), hardware: detectHardware(c.useragent),
hashrate1m: c.dsps1 * 2 ** 32, hashrate1m: c.dsps1 * 2 ** 32,
hashrate1h: c.dsps60 * 2 ** 32, hashrate1h: c.dsps60 * 2 ** 32,
bestDiff: sessionBest, bestDiff: c.bestdiff,
bestEver: w?.bestever ?? sessionBest, bestEver: w?.bestever ?? c.bestdiff,
lastShare: c.lastshare, lastShare: c.lastshare,
difficulty: c.diff, difficulty: c.diff,
address: c.address, address: c.address,
@@ -59,13 +59,15 @@
for (const w of workers) { for (const w of workers) {
if (seen.has(w.worker)) continue; if (seen.has(w.worker)) continue;
// Offline worker — no current session, so session-best is 0.
// The lifetime best_ever still applies.
out.push({ out.push({
workerName: w.worker, workerName: w.worker,
user: w.user, user: w.user,
hardware: "offline", hardware: "offline",
hashrate1m: w.dsps1 * 2 ** 32, hashrate1m: w.dsps1 * 2 ** 32,
hashrate1h: w.dsps60 * 2 ** 32, hashrate1h: w.dsps60 * 2 ** 32,
bestDiff: w.bestdiff, bestDiff: 0,
bestEver: w.bestever, bestEver: w.bestever,
lastShare: w.lastshare, lastShare: w.lastshare,
difficulty: w.mindiff, difficulty: w.mindiff,
+4 -6
View File
@@ -49,12 +49,10 @@
hashrate1m: (c?.dsps1 ?? w.dsps1) * 2 ** 32, hashrate1m: (c?.dsps1 ?? w.dsps1) * 2 ** 32,
hashrate1h: (c?.dsps60 ?? w.dsps60) * 2 ** 32, hashrate1h: (c?.dsps60 ?? w.dsps60) * 2 ** 32,
diff: c?.diff ?? w.mindiff, diff: c?.diff ?? w.mindiff,
// Session best = larger of client.bestdiff (this stratum // Session best = ckpool's stratum_instance.best_diff for the
// connection) and worker.bestdiff (this worker in the // currently-connected client only. Resets on miner disconnect
// current round). Matches the MinersTable / BestShares // and pool restart. 0 for offline workers (no current session).
// leaderboard semantics so values are consistent across bestRound: c?.bestdiff ?? 0,
// screens.
bestRound: Math.max(c?.bestdiff ?? 0, w.bestdiff),
bestEver: w.bestever, bestEver: w.bestever,
lastShare: c?.lastshare ?? w.lastshare, lastShare: c?.lastshare ?? w.lastshare,
online: !!c, online: !!c,