Commit Graph
4 Commits
Author SHA1 Message Date
satoshi e881bc930d Revamp dashboard and persist pool stats across restarts
Dashboard now renders 10 tiles in a 5x2 overview: hashrate, best
share, miners, network hashrate, and expected block on the top row;
difficulty, block height, block reward, total work, and the
difficulty-adjustment countdown on the bottom row. Difficulty is
rendered with T/P suffixes instead of scientific notation, the main
hashrate card shows the 1-minute value, and the block-height tile
pulses orange when the network tip advances.

Added a 24-hour hashrate area chart below the overview, sampled
once per minute. Samples are persisted to a new hashrate_samples
SQLite table and restored on startup so the chart doesn't reset
every time kamado-api is restarted.

Cumulative pool work (sum of accepted diff-1-normalized shares) is
now tracked across ckpool restarts. The aggregator integrates only
positive deltas on pool.Shares — a regression means ckpool's
counter reset to zero and the baseline is refreshed without losing
the running total. A hasPoolSharesBaseline flag prevents double-
counting on the first refresh after a kamado-api restart. The
value is persisted to a new kv table once per minute.

Next-block reward (subsidy + fees) is fetched from bitcoind
getblocktemplate at most once per minute and surfaced as a tile.

Header's block-height badge now reads prevHeight via untrack() so
the effect doesn't form a dependency cycle with its own write.
2026-04-22 21:07:22 +03:00
satoshi 64d8af407d Record and display winning share difficulty on found blocks
Logmon now captures the share diff from ckpool's "Possible block
solve" line preceding the confirmation and attaches it to the
BlockEvent. Persisted as share_diff alongside height/hash/reward
and rendered as a new column in the dashboard block history.
2026-04-14 18:15:44 +03:00
satoshi c92a991e89 Make ckpool client resilient to warm-up EOFs
The stratifier can accept a connection and close it without
writing a response during early startup — the refresh loop
then logs 'ckpool poolstats failed: read len: EOF' on every
tick until the stratifier is ready, which is noisy and looks
like a real fault.

- client.Send retries once after 200ms if the server closed
  the connection before any bytes were read (io.EOF anywhere
  in the wrapped chain).
- Aggregator tracks a ckFailStreak counter: first two
  consecutive failures log at DEBUG, third and beyond escalate
  to WARN. Successful refreshes reset the streak.
2026-04-14 10:58:26 +03:00
satoshi d37a23bc57 Phase 3: Svelte 5 UI skeleton
Svelte 5 + Vite + TypeScript dashboard that consumes kamado-api over
REST for the first paint and then subscribes to /api/ws for live
updates. Zero runtime deps beyond svelte itself; plain CSS, no
component library.

Layout:

- Header with brand, WebSocket status badge, chain + height
- PoolOverview: hashrate (1m/5m/1h/24h), miner count, network
  hashrate + diff, pool share (ppb), expected time to block, uptime
- BlocksTable: recent solves from the in-memory ring (will be
  SQLite-backed in Phase 2b.5)
- BestShares: top-10 workers by bestever, falling back to bestdiff
  when the ckpool patch isn't present
- MinersTable: joined view of stratum clients and workers with
  user-agent-based hardware detection (Bitaxe, NerdQAxe, Antminer,
  ...), hashrate, best-round, best-ever, last share

State is a single $state() snapshot store in svelte-runes form;
components read from it via $derived. The store does one initial
REST snapshot fetch, then owns the WebSocket with exponential
backoff reconnects.

Vite dev server on :5173 proxies /api and /api/ws to localhost:8080
so you can run `make ui-dev` alongside `make up` in development.
Production serving (bundled into the Go binary via embed, behind /
on :8080) lands in Phase 4.
2026-04-13 03:07:59 +03:00