Skip to content

feat(header): real last-refresh time with live "N ago" counter#105

Merged
entrius merged 1 commit into
testfrom
feat/header-last-refresh-ago
May 28, 2026
Merged

feat(header): real last-refresh time with live "N ago" counter#105
entrius merged 1 commit into
testfrom
feat/header-last-refresh-ago

Conversation

@anderdc
Copy link
Copy Markdown
Collaborator

@anderdc anderdc commented May 28, 2026

What

Replaces the top-right last refresh #X · next ~N blocks indicator with the validator's real last-flush block plus a live, count-up "N ago" timer:

●  last refresh #7,172,358 · just now
●  last refresh #7,172,358 · ~14m ago
●  last refresh #7,172,358 · ~1h 2m ago

…until the next flush, when it snaps back to #<new block> · just now.

Why

The old line computed lastRefresh = floor(currentBlock / 600) * 600 and next = 600 − (block mod 600). That assumes the validator flushes crown/rate data at absolute block multiples of 600 — it doesn't. SCORING_WINDOW_BLOCKS gates scoring off the validator's forward-step counter (self.step % 600 == 0 in forward.py), which is anchored to validator boot and persists across restarts (state.npz). A forward step also spans 1–5 blocks, not exactly one. So the shown block boundary and countdown were fabricated — they pointed at a "refresh" that never actually happened at that block.

How

Consumes the new GET /network/scoring-state (das-allways#29):

{ "lastScoredBlock": 7172358, "updatedAt": "2026-05-28T14:31:07.000Z" }

updatedAt advances only inside a real flush (flush_scoring_window / flush_halt_window write the crown_holders_max_block cursor), so it's a true "last refreshed" timestamp. The elapsed half counts up client-side (1s tick on an isolated RefreshIndicator), no extra network calls.

Safety / ordering

  • Falls back to the existing healthy label when updatedAt is null — i.e. before the first flush or if this UI ships before das-allways#29. Safe to merge in either order.
  • paused (halted) behavior unchanged.
  • Format: plain ~14m ago, just now for sub-minute. No "next" estimate (the flush cadence isn't predictable in blocks).

Depends on das-allways#29 for the endpoint to return real data.

Replace the fabricated "last refresh #floor(block/600) · next ~N blocks"
indicator with the validator's true last-flush block and a live elapsed
counter sourced from the new /network/scoring-state endpoint.

The old math assumed the validator flushes at absolute block multiples of
600. It doesn't: scoring is gated on the validator's forward-step counter
(self.step % SCORING_WINDOW_BLOCKS), anchored to boot and persisted across
restarts — so the displayed block boundary and countdown were not real
events. scoring-state exposes crown_holders_max_block (real block scored
through) and its updated_at (real flush time), which the validator advances
only inside a flush.

Header now renders e.g. "last refresh #7,172,358 · ~14m ago", counting up
client-side (1s tick) until the next flush snaps it back to "just now".
Falls back to the existing "healthy" label when updatedAt is null (no flush
yet, or backend not deployed), so it is safe to merge in either order.
@entrius entrius merged commit 15f5ee1 into test May 28, 2026
2 checks passed
@entrius entrius deleted the feat/header-last-refresh-ago branch May 28, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants