arena: cumulative authorship counter so the leaderboard follows the time range #9

Merged
grenade merged 1 commits from arena/authored-counter into main 2026-09-03 13:11:07 +00:00
2 changed files with 18 additions and 4 deletions

View File

@@ -325,6 +325,12 @@ class Arena:
# while the node is catching up: it ingests historical blocks at import
# speed, so "the last hour" can contain half a million blocks.
self.blocks = deque(maxlen=window_blocks) # (height, preimage)
# Cumulative per-preimage count since the exporter started, for panels
# that follow the dashboard's time range (increase() over $__range).
# The windowed gauge above cannot do that: it is always the last N
# blocks. Not capped to top N: a counter that appears and disappears
# loses increments, and the label set is bounded by distinct miners.
self.authored_total = {}
# Tip observations only — used for the block interval, which is real
# elapsed time between blocks and therefore only valid at the tip.
self.tip_samples = deque(maxlen=200) # (unix_ts, height)
@@ -352,6 +358,7 @@ class Arena:
with self.lock:
self.blocks.append((height, pre))
self.blocks_seen += 1
self.authored_total[pre] = self.authored_total.get(pre, 0) + 1
if at_tip:
self.tip_samples.append((time.time(), height))
@@ -494,6 +501,13 @@ class Arena:
shown = sum(keep.values())
out.append(f"quantus_blocks_authored{{preimage=\"other\",self=\"false\"}} {total - shown}")
out.append("# HELP quantus_blocks_authored_total Blocks observed authored since the exporter "
"started, by reward preimage. Cumulative; use increase() over a range.")
out.append("# TYPE quantus_blocks_authored_total counter")
for pre, n in sorted(self.authored_total.items(), key=lambda kv: kv[1], reverse=True):
is_self = "true" if pre == self.self_preimage else "false"
out.append(f'quantus_blocks_authored_total{{preimage="{pre}",self="{is_self}"}} {n}')
if self.balance is not None and self.decimals is not None:
free, reserved, frozen, nonce = self.balance
scale = 10 ** self.decimals

View File

@@ -9,7 +9,7 @@
],
"timezone": "browser",
"schemaVersion": 39,
"version": 11,
"version": 12,
"refresh": "30s",
"time": {
"from": "now-6h",
@@ -1705,7 +1705,7 @@
},
{
"type": "table",
"title": "Authorship leaderboard",
"title": "Authorship leaderboard (dashboard time range)",
"datasource": {
"type": "prometheus",
"uid": "prometheus"
@@ -1716,7 +1716,7 @@
"x": 0,
"y": 62
},
"description": "Blocks authored per reward preimage, decoded from each header's PreRuntime digest \u2014 every miner on the network, no indexer needed.\n\nThe window is a BLOCK COUNT, capped at 3600 (~12h at the current interval), not a time range: a time window is meaningless while the node catches up, since it ingests history at import speed. It refills from empty after an arena-exporter restart, so the panels to the right show how full it actually is \u2014 read those before comparing shares.\n\nThe dashboard time picker does NOT change this window; the exporter owns it.",
"description": "Blocks observed authored within the selected time range, by reward preimage, from the cumulative counter quantus_blocks_authored_total. Counts exist from the moment the exporter started exporting it and within Prometheus retention; increase() extrapolates across scrape gaps, so treat the last digit as approximate. The fixed 3600-block window is quantus_blocks_authored.",
"targets": [
{
"datasource": {
@@ -1725,7 +1725,7 @@
},
"editorMode": "code",
"refId": "A",
"expr": "topk(20, quantus_blocks_authored)",
"expr": "sort_desc(topk(20, round(increase(quantus_blocks_authored_total[$__range]))))",
"instant": true,
"range": false,
"format": "table"