Skip to content

Commit 0c7147a

Browse files
committed
Adaptive-precision fmtPct so small miners don't render as 0.00%
toFixed(2) on share_of_pool_pct hid legitimate small contributors: a 875 KH/s rig next to a 2 TH/s ASIC is 0.000044% of the pool — '0.00%' looked like the row was broken. The new fmtPct picks a decimal count from the magnitude so every non-zero contributor gets a non-zero display: >= 1% -> 2 decimals >= 0.01% -> 3 decimals >= 0.0001% -> 4 decimals else -> 2 sig figs == 0 -> '0%' null / NaN -> '—' Exported as stats.fmtPct; passed to both index.ejs (pool leaderboards) and worker.ejs (per-worker page) via server.js. Existing per-share reject-rate % on index.ejs still uses toFixed(2) because reject rates aren't as sensitive to display precision; leaving that alone to keep the diff small. Live spot-check confirms the fix: rig1 (875 KH/s next to testrig's 2 TH/s, share of pool ~4.4e-5%) renders as '0.000044%' instead of '0.00%'.
1 parent f1cb7de commit 0c7147a

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

dashboard/lib/stats.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,3 +407,24 @@ export function fmtHashrate(hps) {
407407
}
408408
return `${v.toFixed(2)} ${UNITS[i]}`;
409409
}
410+
411+
/* Percentage of the pool. A small rig next to a large ASIC is
412+
* legitimately a tiny fraction — `toFixed(2)` on 0.000044 renders
413+
* "0.00%" and looks like a bug. Adaptive precision so every
414+
* contributor sees a non-zero number:
415+
* >= 1% — 2 decimals (e.g., "54.32%")
416+
* >= 0.01% — 3 decimals (e.g., "0.523%")
417+
* >= 0.0001% — 4 decimals (e.g., "0.0523%")
418+
* > 0 — 2 sig figs (e.g., "4.4e-5%")
419+
* == 0 — "0%"
420+
* Kept as a stat-lib export so both the pool-wide and per-worker
421+
* pages can share it. */
422+
export function fmtPct(p) {
423+
if (p == null || !isFinite(p)) return '—';
424+
if (p === 0) return '0%';
425+
const abs = Math.abs(p);
426+
if (abs >= 1) return p.toFixed(2) + '%';
427+
if (abs >= 0.01) return p.toFixed(3) + '%';
428+
if (abs >= 0.0001) return p.toFixed(4) + '%';
429+
return p.toPrecision(2) + '%';
430+
}

dashboard/server.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ app.get('/', (req, res) => {
4242
stratumUrl: PUBLIC_STRATUM_URL,
4343
fmtHashrate: stats.fmtHashrate,
4444
fmtBtc: stats.fmtBtc,
45+
fmtPct: stats.fmtPct,
4546
});
4647
});
4748

4849
app.get('/worker/:name', (req, res) => {
4950
const w = stats.worker(db, req.params.name, 86400, PPS_SATS_PER_DIFF);
5051
if (!w.worker) return res.status(404).render('404', { what: 'worker' });
51-
res.render('worker', { ...w, name: req.params.name, fmtHashrate: stats.fmtHashrate });
52+
res.render('worker', {
53+
...w, name: req.params.name,
54+
fmtHashrate: stats.fmtHashrate,
55+
fmtPct: stats.fmtPct,
56+
});
5257
});
5358

5459
app.get('/blocks', (req, res) => {

dashboard/views/index.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ password: (ignored — any value)</pre>
143143
<td><%= fmtN(m.rigs) %></td>
144144
<td><%= fmtN(m.shares) %></td>
145145
<td><%= fmtHashrate(m.hashrate_est) %></td>
146-
<td><%= m.share_of_pool_pct.toFixed(2) %>%</td>
146+
<td><%= fmtPct(m.share_of_pool_pct) %></td>
147147
<td title="<%= fmtTs(m.last_seen) %>"><%= ago(m.last_seen) %></td>
148148
</tr>
149149
<% }) %>
@@ -170,7 +170,7 @@ password: (ignored — any value)</pre>
170170
<td><%= fmtHashrate(w.hashrate_5m) %></td>
171171
<td><%= fmtHashrate(w.hashrate_1h) %></td>
172172
<td><%= fmtHashrate(w.hashrate_est) %></td>
173-
<td><%= w.share_of_pool_pct.toFixed(2) %>%</td>
173+
<td><%= fmtPct(w.share_of_pool_pct) %></td>
174174
<td title="<%= fmtTs(w.last_seen) %>"><%= ago(w.last_seen) %></td>
175175
</tr>
176176
<% }) %>

0 commit comments

Comments
 (0)