feat(header): real last-refresh time with live "N ago" counter#105
Merged
Conversation
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
approved these changes
May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Replaces the top-right
last refresh #X · next ~N blocksindicator with the validator's real last-flush block plus a live, count-up "N ago" timer:…until the next flush, when it snaps back to
#<new block> · just now.Why
The old line computed
lastRefresh = floor(currentBlock / 600) * 600andnext = 600 − (block mod 600). That assumes the validator flushes crown/rate data at absolute block multiples of 600 — it doesn't.SCORING_WINDOW_BLOCKSgates scoring off the validator's forward-step counter (self.step % 600 == 0inforward.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" }updatedAtadvances only inside a real flush (flush_scoring_window/flush_halt_windowwrite thecrown_holders_max_blockcursor), so it's a true "last refreshed" timestamp. The elapsed half counts up client-side (1s tick on an isolatedRefreshIndicator), no extra network calls.Safety / ordering
healthylabel whenupdatedAtis 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.~14m ago,just nowfor 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.