arena: backfill the rolling window at startup; leaderboard hides zero-block rows #21

Merged
grenade merged 1 commits from arena/backfill-window into main 2026-09-04 07:24:42 +00:00
2 changed files with 33 additions and 2 deletions

View File

@@ -369,6 +369,9 @@ ATTRIBUTION_MIN_CONFIDENCE = 0.6
# restarts or renames (a new telemetry node id) takes over the attribution
# after a few blocks instead of having to outvote its own history.
ATTRIBUTION_WINDOW = 20
# Startup backfill of the rolling window from chain history is capped by
# wall clock so a slow node cannot hold the exporter's first poll forever.
BACKFILL_BUDGET_S = 180.0
GAP_BUCKETS = [0.5, 1, 2, 3, 5, 8, 12, 16, 24, 32, 48, 64, 128]
# Block timestamp minus the moment this exporter first saw the block, seconds.
@@ -534,6 +537,32 @@ class Arena:
return None
return self.rpc.call("chain_getHeader", [h])
def backfill_window(self, height):
"""Fill the rolling window from chain history at startup, so the
per-author series (leaderboard rows, author labels, timing caps) do
not start from nothing after every restart. Window only: the authored
counter is left alone so `increase()` sees no phantom burst, and no
tip timing is observed for blocks we did not watch arrive."""
start = max(1, height - self.blocks.maxlen + 1)
deadline = time.time() + BACKFILL_BUDGET_S
n = start
got = 0
while n < height and time.time() < deadline:
try:
hdr = self.header_at(n)
except Exception as e: # noqa: BLE001 - history is best effort
LOG.warning("backfill stopped at %s: %s", n, e)
break
if hdr:
pre = author_preimage(hdr)
if pre is not None:
with self.lock:
self.blocks.append((n, pre))
got += 1
n += 1
LOG.info("backfilled %s of %s window blocks (%s..%s) in %.0fs", got, height - start, start, n - 1,
time.time() - (deadline - BACKFILL_BUDGET_S))
def record(self, header, at_tip):
height = int(header["number"], 16)
pre = author_preimage(header)
@@ -636,6 +665,8 @@ class Arena:
hdr = self.header_at(n)
if hdr:
self.record(hdr, at_tip=False)
if self.last_height is None:
self.backfill_window(height)
if self.last_height is None or height > self.last_height:
self.record(head, at_tip=not self.syncing)
self.last_height = height

View File

@@ -9,7 +9,7 @@
],
"timezone": "browser",
"schemaVersion": 39,
"version": 21,
"version": 22,
"refresh": "30s",
"time": {
"from": "now-6h",
@@ -1725,7 +1725,7 @@
},
"editorMode": "code",
"refId": "A",
"expr": "sort_desc(topk(20, round(increase(quantus_blocks_authored_total[$__range]))))",
"expr": "sort_desc(topk(20, round(increase(quantus_blocks_authored_total[$__range])) > 0))",
"instant": true,
"range": false,
"format": "table"