Commit Graph
10 Commits
Author SHA1 Message Date
satoshi 1157f3501a Add best share analysis page, miner column, and UI improvements
- Best share page: hex + binary hash comparison against network target,
  per-bit coloring showing exactly which bits prevented a valid block,
  toggle between network diff at time of finding vs current diff
- Capture best share hash from ckpool logs with one-time backfill
- Persist network difficulty at time of best share for historical accuracy
- Add miner (worker) column to blocks table via coinbase address matching
- Truncate block hashes in table with full hash on hover
- Increase hashrate chart Y-axis to 7 ticks for better readability
2026-05-18 17:19:35 +03:00
satoshi 5e7be22e8e Add page transition animations and background wallpapers
Wrap page views in {#key} blocks with a fade-in animation for smooth
transitions. Add Demon Slayer wallpapers as fixed pseudo-element
backgrounds on main (Tanjiro for dashboard, Rengoku for accelerator)
with CSS crossfade. Fix section spacing lost by the page-enter wrapper
div. Minor tooltip text fixes.
2026-05-11 09:11:50 +03:00
satoshi dc7da6ab19 Add transaction accelerator (prioritisetransaction UI + API)
Full-stack feature for boosting transactions via bitcoind's
prioritisetransaction RPC:

Backend:
- New accelerator package with Accelerate, Cancel, MaxFeerate, List,
  and background Cleanup goroutine (removes confirmed/dropped txs)
- RPC wrappers: GetMempoolEntry, PrioritiseTransaction,
  GetRawMempoolVerbose, IsRPCError helpers
- SQLite boosted_txs table for persistence across restarts
- Revenue impact measured via getblocktemplate before/after comparison
- Hard cap at 2000 sat/vB; MaxFeerate uses fees.base (not modified)
  to ignore our own prior priority adjustments

Frontend:
- Rocket icon in header with 10s jiggle animation
- AcceleratorPage with flame-gradient border, txid input, feerate
  input, "Prioritize above all" button with spinner, boost list with
  cancel buttons, and dismissible error/success messages
- Hash-based routing (#/accelerator)
- SharesBar font size bump
2026-05-11 03:54:35 +03:00
satoshi 6acff6280f Add block-update latency tracking, raw share counters, and shares bar UI
Log ZMQ→mining.notify latency in ckpool (patch 0005), expose a raw
reject counter (patch 0006), and surface both in the dashboard:

- Block latency card shows avg/last ms, wasted work, and block count
- SharesBar component shows session + all-time accepted/rejected with
  a Demon Slayer flame-slash animation on new shares
- Miners card info moved to MinersTable section header
- Latency stats and share counts persist across restarts via kv store
- Removed misleading pool-wide share stats from per-worker/user pages
  (ckpool doesn't expose per-user raw counts)
2026-05-11 02:12:16 +03:00
satoshi e622f1a81a Add per-worker stats page with cumulative work and luck
Expose ckpool's per-worker cumulative shares via patch 0004, add a
WorkerDetailPage with hashrate, status, best share with per-worker luck
(bestever/shares*100), and total work with pool share percentage.
Worker names are now clickable in MinersTable and UserDetailPage.
Also centers numeric columns below their headers.
2026-05-10 18:02:08 +03:00
satoshi 99302cf4af Tighten fallback latency + alert UI on degraded states
Submit-first ordering. Patch 0004 now calls generator_submitblock
BEFORE writing the pending-block hex to disk. The happy path adds zero
disk I/O — we only dump when the primary returned false. The same
patch bounds generator_submitblock's "no live current_si" spin to
~3s instead of the original infinite loop, so a permanently-down
primary doesn't pin the stratifier; the bounded spin lets the caller
return false and lets local_block_submit dump for kamado-api to take
over.

Default grace lowered from 30s to 3s. With ckpool's bounded spin and
sub-second sweep cadence, the fallback now reacts within ~4s of a
failed primary submit — fast enough that the work is still relevant
for the current chain tip. The submitter's sweep poll dropped to 1s
to match.

UI HealthBanners. New top-of-page strip surfaces:
  * Fallback used (red banner, 24h after most recent event):
    "primary bitcoind didn't accept; backup X took over Y ago"
  * Submit gap (orange banner, only when no recent fallback):
    "N blocks attempted but unconfirmed — configure backups"
  * ZMQ stale (orange banner): no hashblock frame in 30+ minutes
Operators see degraded-but-not-fatal states without checking logs.

Startup readiness gate. main now waits up to 8s on agg.Ready() before
starting the HTTP server so the very first /api/snapshot doesn't show
all-zero state during the aggregator's first refresh. Capped so a
permanently-down bitcoind can't block startup; /healthz is honest
about the degraded state once we do start serving.
2026-04-27 21:53:23 +03:00
satoshi 49c951f94f User page: hash-routed view, full block hash, aligned rewards
The per-user view was an overlay modal, but users asked for an
actual page — focused, scrollable, addressable. Replace the modal
with a hash-routed page: selectUser(addr) sets window.location.hash
to #/user/<addr> and a hashchange listener syncs the selection
state back, so browser back/forward and direct-link refresh all
work without a routing library. App renders the dashboard or the
UserDetailPage based on selection.user.

Make the clickable BTC addresses in the Miners table obviously
interactive: accent colour, always-on dashed underline, brighter on
hover/focus. The previous styling rendered them as dim static text
with a hover underline, so it wasn't obvious they were links.

BlocksTable: show the full 64-char block hash as a link to
mempool.space (auto-picks testnet4/signet based on snap.chain).
word-break: break-all keeps the hash from blowing out the column
width. Reward column is split into a tabular-num number span and a
dim 0.75em "BTC" unit span, matching the Block reward tile in the
overview, so numbers line up cleanly across rows.
2026-04-24 01:02:11 +03:00
satoshi c104c1eefa Dashboard polish: per-user modal, block-found animation, readable chart
Block-reward tile was cached for 60s, so users saw it sit still even
as bitcoind's CreateNewBlock fired every few seconds with updated
fee totals. Drop the template cache TTL to 15s — bitcoind caches
the template internally, so the extra RPC cost is trivial.

Hashrate chart was rendering 1440 raw per-minute points across a
~780px plot, which collapsed into a noisy smear. Bucket-average to
~96 points so the chart actually communicates a trend. Raw samples
under the target pass through unchanged (early process lifetime).

Layout: Blocks found is now full-width, with the Best shares
leaderboard stacked below it. The previous side-by-side was
squeezing both tables on typical displays.

New user-detail modal. Clicking a BTC address in the Miners table
opens a focused view: per-user aggregate hashrate (1m/5m/1h/24h),
best round / best ever, and a worker-level breakdown with the same
columns as the main table. Driven by a small selection store so any
component in the tree can open it. Closes on backdrop click or Esc.

New block-found animation. When the network tip advances, a brief
full-screen overlay plays: a radial Hinokami Kagura ember burst
above the header, a faint sun-ray sweep, and ~22 falling sakura
petals with randomised drift / rotation / delay so no two blocks
look identical. The existing block-height tile flash still fires
alongside; the overlay is pointer-events: none so nothing in the
UI becomes unreachable during the ~3.6s animation.
2026-04-24 00:46:16 +03:00
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 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