Skip to content

Commit 7ea1cfc

Browse files
author
WillItMod
committed
AxeDGB 0.8.17: per-worker stats + UI polish
1 parent 4f6730b commit 7ea1cfc

6 files changed

Lines changed: 59 additions & 16 deletions

File tree

willitmod-dev-dgb/data/templates/miningcore.json.template

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
},
5959
"ports": {
6060
"3333": {
61-
"listenAddress": "127.0.0.1",
61+
"listenAddress": "0.0.0.0",
6262
"difficulty": ${STARTDIFF},
6363
"varDiff": {
6464
"minDiff": ${MINDIFF},
@@ -97,7 +97,7 @@
9797
},
9898
"ports": {
9999
"3334": {
100-
"listenAddress": "127.0.0.1",
100+
"listenAddress": "0.0.0.0",
101101
"difficulty": ${STARTDIFF},
102102
"varDiff": {
103103
"minDiff": ${MINDIFF},

willitmod-dev-dgb/docker-compose.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ services:
143143
if type=="object" then
144144
(.paymentProcessing = (.paymentProcessing // {"enabled": false}))
145145
| (.blockRefreshInterval = ((.blockRefreshInterval // 500) | if . < 2000 then 2000 else . end))
146+
| (.ports |= (if type=="object" then with_entries(.value |= (if type=="object" then (.listenAddress="0.0.0.0") else . end)) else . end))
146147
| (.daemons = ((.daemons // []) | (if type=="array" then map(if type=="object" then (.port=$rpcport) else . end) else . end)))
147148
else . end
148149
) else . end))
@@ -178,7 +179,7 @@ services:
178179
"banning": {"enabled": true, "time": 600, "invalidPercent": 50, "checkThreshold": 50},
179180
"ports": {
180181
"3334": {
181-
"listenAddress": "127.0.0.1",
182+
"listenAddress": "0.0.0.0",
182183
"difficulty": $$diff,
183184
"varDiff": {
184185
"minDiff": $$mindiff,
@@ -357,7 +358,7 @@ services:
357358
- ${APP_DATA_DIR}/data/pool/config/coins.json:/app/coins.json:ro
358359

359360
app:
360-
image: ghcr.io/willitmod/axedgb-app-umbrel-dev:0.8.10
361+
image: ghcr.io/willitmod/axedgb-app-umbrel-dev:0.8.17
361362
user: "1000:1000"
362363
restart: on-failure
363364
stop_grace_period: 30s

willitmod-dev-dgb/images/axedgb-app/app.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def _env_or_default(name: str, default: str) -> str:
6363
SUPPORT_TICKET_URL = _env_or_default("SUPPORT_TICKET_URL", f"{DEFAULT_SUPPORT_BASE_URL}/api/support/upload")
6464

6565
APP_ID = "willitmod-dev-dgb"
66-
APP_VERSION = "0.8.16"
66+
APP_VERSION = "0.8.17"
6767

6868
DGB_RPC_HOST = os.getenv("DGB_RPC_HOST", "dgbd")
6969
DGB_RPC_PORT = int(os.getenv("DGB_RPC_PORT", "14022"))
@@ -73,6 +73,7 @@ def _env_or_default(name: str, default: str) -> str:
7373
SAMPLE_INTERVAL_S = int(os.getenv("SERIES_SAMPLE_INTERVAL_S", "30"))
7474
MAX_RETENTION_S = int(os.getenv("SERIES_MAX_RETENTION_S", str(7 * 24 * 60 * 60)))
7575
MAX_SERIES_POINTS = int(os.getenv("SERIES_MAX_POINTS", "20000"))
76+
WORKER_STALE_SECONDS = int(os.getenv("WORKER_STALE_SECONDS", "900"))
7677

7778
INSTALL_ID = None
7879

@@ -228,6 +229,15 @@ def _pool_workers_from_db(pool_id: str):
228229
if hashrate_hs_f is not None and not math.isfinite(hashrate_hs_f):
229230
hashrate_hs_f = None
230231

232+
created_dt = created if isinstance(created, datetime) else None
233+
if created_dt is not None:
234+
try:
235+
age_s = (datetime.now(timezone.utc) - created_dt.astimezone(timezone.utc)).total_seconds()
236+
if WORKER_STALE_SECONDS > 0 and age_s > WORKER_STALE_SECONDS:
237+
continue
238+
except Exception:
239+
pass
240+
231241
hashrate_ths = None
232242
if hashrate_hs_f is not None:
233243
hashrate_ths = hashrate_hs_f / 1e12
@@ -252,6 +262,12 @@ def _pool_workers_from_db(pool_id: str):
252262
}
253263
)
254264

265+
# Miningcore can emit both per-worker rows and an aggregate (worker=null) row for the same miner.
266+
# If we have any named workers, hide the aggregate row so the UI doesn't under/over-count workers.
267+
has_named = any(isinstance(m.get("worker"), str) and m.get("worker") for m in out)
268+
if has_named:
269+
out = [m for m in out if m.get("worker")]
270+
255271
out.sort(key=lambda m: float(m.get("hashrate_hs") or 0), reverse=True)
256272
with _POOL_WORKERS_LOCK:
257273
_POOL_WORKERS_CACHE[pool_id] = {"t": now, "workers": out}

willitmod-dev-dgb/images/axedgb-app/static/app.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,36 @@ function formatAge(v) {
315315
function renderWorkerDetails(miners) {
316316
const status = document.getElementById('worker-details-status');
317317
const rows = document.getElementById('worker-details-rows');
318+
const lastShareEl = document.getElementById('last-share');
318319
if (!rows) return;
319320

320321
rows.innerHTML = '';
321322
const list = Array.isArray(miners) ? miners : [];
322323
if (!list.length) {
323324
if (status) status.textContent = 'No workers connected yet.';
325+
if (lastShareEl) lastShareEl.textContent = '-';
324326
rows.innerHTML = '<div class="px-3 py-2 text-xs text-slate-400">Connect a miner to see per-worker stats.</div>';
325327
return;
326328
}
327329

328-
if (status) status.textContent = `${list.length} worker${list.length === 1 ? '' : 's'} seen (best-effort)`;
330+
if (status) status.textContent = `${list.length} worker${list.length === 1 ? '' : 's'} connected`;
331+
332+
if (lastShareEl) {
333+
let newestMs = 0;
334+
for (const m of list) {
335+
const v = m && m.lastShare;
336+
if (v == null) continue;
337+
const n = Number(v);
338+
if (Number.isFinite(n) && n > 0) {
339+
const ms = n > 1e12 ? n : n * 1000;
340+
if (ms > newestMs) newestMs = ms;
341+
continue;
342+
}
343+
const parsed = Date.parse(String(v));
344+
if (Number.isFinite(parsed) && parsed > newestMs) newestMs = parsed;
345+
}
346+
lastShareEl.textContent = newestMs ? `${formatAge(newestMs)} ago` : '-';
347+
}
329348

330349
for (const m of list.slice(0, 50)) {
331350
const name = m.worker ? String(m.worker) : shortenMiner(m.miner);
@@ -521,6 +540,8 @@ async function refresh() {
521540
} catch {
522541
document.getElementById('workers').textContent = '-';
523542
document.getElementById('hashrate').textContent = '-';
543+
const lastShareEl = document.getElementById('last-share');
544+
if (lastShareEl) lastShareEl.textContent = '-';
524545
document.getElementById('workers-summary').textContent = '-';
525546
document.getElementById('hashrate-summary').textContent = '-';
526547
const bestIds = ['bestdiff-since', 'bestdiff-all', 'bestdiff-summary'];

willitmod-dev-dgb/images/axedgb-app/static/index.html

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
<script defer src="/app.js?v=__APP_VERSION__"></script>
1010
<style>
1111
.axe-shadow-heavy {
12-
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.92), 0 3px 10px rgba(0, 0, 0, 0.95),
13-
0 10px 28px rgba(0, 0, 0, 0.9);
12+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.95), 0 6px 18px rgba(0, 0, 0, 0.98),
13+
0 14px 40px rgba(0, 0, 0, 0.92);
1414
}
1515
</style>
1616
</head>
@@ -162,6 +162,11 @@
162162
<div class="axe-stat__k">Workers</div>
163163
<div class="axe-stat__v" id="workers">-</div>
164164
</div>
165+
<div class="axe-stat">
166+
<div class="axe-stat__k">Last share</div>
167+
<div class="axe-stat__v" id="last-share">-</div>
168+
<div class="axe-stat__k mt-1 text-slate-400">Across all workers</div>
169+
</div>
165170
<div class="axe-stat">
166171
<div class="axe-stat__k">Hashrate</div>
167172
<div class="axe-stat__v" id="hashrate">-</div>
@@ -208,13 +213,6 @@
208213
<div class="axe-stat__k mt-1">Best difficulty (all-time)</div>
209214
<div class="axe-stat__v mt-1" id="bestdiff-all">-</div>
210215
</div>
211-
<div class="axe-stat">
212-
<div class="axe-stat__k">Workers (details)</div>
213-
<div class="mt-2 text-xs text-slate-400" id="worker-details-status">Loading...</div>
214-
<div class="mt-2 overflow-hidden rounded-xl border border-white/10">
215-
<div id="worker-details-rows" class="divide-y divide-white/10"></div>
216-
</div>
217-
</div>
218216
</div>
219217
</div>
220218

@@ -250,6 +248,13 @@
250248
<div class="axe-stat__k">Network difficulty</div>
251249
<canvas id="chart-difficulty" class="mt-2 w-full rounded-xl bg-black/30" height="84"></canvas>
252250
</div>
251+
<div class="axe-stat">
252+
<div class="axe-stat__k">Workers (details)</div>
253+
<div class="mt-2 text-xs text-slate-400" id="worker-details-status">Loading...</div>
254+
<div class="mt-2 overflow-hidden rounded-xl border border-white/10">
255+
<div id="worker-details-rows" class="divide-y divide-white/10"></div>
256+
</div>
257+
</div>
253258
</div>
254259
</div>
255260
</div>

willitmod-dev-dgb/umbrel-app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ manifestVersion: 1
22
id: willitmod-dev-dgb
33
category: altcoin
44
name: AxeDGB
5-
version: "0.8.15"
5+
version: "0.8.17"
66
tagline: DGB node + solo pool
77
description: >-
88
Run a DigiByte full node (DigiByte Core) and a solo Stratum v1 pool (Miningcore) as a single Umbrel app installation.

0 commit comments

Comments
 (0)