Files
KamadoPool/ui/src/lib/BestShares.svelte
T
satoshi ea4c514d78 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.
2026-04-26 18:13:18 +03:00

73 lines
2.1 KiB
Svelte

<script lang="ts">
import { snap } from "../stores/snapshot.svelte";
import { formatDifficulty } from "../format";
import type { StratumClient } from "../types";
// "Best (session)" = best diff in the current stratum TCP session,
// i.e. only ckpool's stratum_instance.best_diff. Resets on miner
// disconnect (the instance is freed) and on pool restart (in-memory
// state, not persisted). worker.best_diff is a separate persistent
// counter that survives both events, so we deliberately don't fall
// 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 ws = snap.data?.workers ?? [];
const cs = snap.data?.clients ?? [];
const clientByWorker = new Map<string, StratumClient>();
for (const c of cs) {
const wname = c.workername || `${c.address}.unnamed`;
clientByWorker.set(wname, c);
}
const enriched = ws.map((w) => {
const c = clientByWorker.get(w.worker);
return {
worker: w.worker,
sessionBest: c?.bestdiff ?? 0,
bestEver: w.bestever || w.bestdiff,
};
});
enriched.sort((a, b) => b.bestEver - a.bestEver);
return enriched.slice(0, 10);
});
</script>
<section class="card">
<h2>Best shares leaderboard</h2>
{#if rows.length === 0}
<div class="empty">No shares submitted yet.</div>
{:else}
<table>
<thead>
<tr>
<th>#</th>
<th>Worker</th>
<th class="num">Best (session)</th>
<th class="num">Best (ever)</th>
</tr>
</thead>
<tbody>
{#each rows as r, i (r.worker)}
<tr>
<td>{i + 1}</td>
<td class="mono">{r.worker}</td>
<td class="num">{formatDifficulty(r.sessionBest)}</td>
<td class="num">{formatDifficulty(r.bestEver)}</td>
</tr>
{/each}
</tbody>
</table>
{/if}
</section>
<style>
h2 {
margin: 0 0 1rem;
font-size: 1.05rem;
font-weight: 600;
}
.empty {
color: var(--fg-dim);
padding: 0.5rem 0;
}
</style>