From 9d24ad323ed467eaa71f27c3b47cc7855fff617e Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Tue, 6 Oct 2026 20:03:41 +0000 Subject: [PATCH] Standing fleet: weight_check reads vote-key shares from the hub's inspect and maps boxes by key-hash (tested: two boxes = 1.2 percent of 2,000 blocks) Co-Authored-By: Claude Fable 5.1 --- tools/fleet/lib/standing.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/tools/fleet/lib/standing.py b/tools/fleet/lib/standing.py index c25a361b5..fc2ae192e 100644 --- a/tools/fleet/lib/standing.py +++ b/tools/fleet/lib/standing.py @@ -91,27 +91,28 @@ def rerent(label): return new # ---- the 10 percent rule (20:00Z): never remove more than 10 percent of the live devnet's 30-day weight in any hour ---- WEIGHT_LOG = os.path.join(ROOT, "weight-removals.jsonl") -def weight_shares(window_blocks=30*86400): - """Blue blocks per payout label over the window, from the hub's node (igneum-miner payouts); returns {label: share}.""" +def weight_shares(blocks=2000): + """Vote-key-hash shares over the last `blocks` blocks of the live devnet, from the hub's node (igneum-miner inspect: + one line per block with voteKeyHash=<64 hex>); the hub is pruned, so the 30-day window is approximated by the largest + read the RPC serves (2,000 blocks is about 33 minutes at 1 block/s; pass more when the RPC allows). Returns + ({key_hash: share}, blocks_read).""" hub = next((v for v in Registry.load().values() if v.get("hub") and v.get("state") != "destroyed"), None) if not hub: raise SshError("no hub box") b = Box(hub["ssh_host"], hub["ssh_port"], "hub-1", None, None, hub.get("provider")) - rc, out, err = b.run("/opt/igneum/pkg/bin/igneum-miner payouts grpc://127.0.0.1:26610 2>/dev/null | tail -400", 120) - rows = {} - for ln in out.splitlines(): - parts = ln.split() - nums = [p for p in parts if p.isdigit()] - if len(parts) >= 2 and nums: - rows[parts[0]] = rows.get(parts[0], 0) + int(nums[-1]) - tot = sum(rows.values()) or 1 - return {k: v / tot for k, v in rows.items()}, out[-600:] + rc, out, err = b.run(f"timeout 170 /opt/igneum/pkg/bin/igneum-miner inspect {blocks} grpc://127.0.0.1:26610 2>&1 | grep -oE 'voteKeyHash=[0-9a-f]{{64}}'", 190) + keys = [ln.split("=", 1)[1] for ln in out.split() if ln.startswith("voteKeyHash=")] + n = len(keys) or 1; rows = {} + for k in keys: rows[k] = rows.get(k, 0) + 1 + return {k: v / n for k, v in rows.items()}, len(keys) +def vote_key_hash(label): + """The box's vote key hash: its miner votes with the key its payout label derives (igneum-miner key-hash