From 1ddd250a0a42ea026a69f90f9c69d74b891e251f Mon Sep 17 00:00:00 2001 From: Alec Muffett Date: Sun, 28 Jun 2026 09:41:30 +0400 Subject: [PATCH] test(d-miner): pin D-MINER.1 per-worker isolation + all-offline honesty Extends the rollup selftest KAT with two honesty-critical properties the existing checks did not pin: 7) Per-worker isolation in the SAME UTC day: two workers with different online/stale profiles produce independent daily rows. One miner's downtime or stale work must never bleed into another's uptime report. 8) All-offline worker: a worker reporting only live==0 (even while still emitting dead_hashrate) yields hours_online=0 and avg_hashrate=0 (no phantom presence), is NOT dropped from the report, and reads stale=100 when all its reported work was dead. SAFE-ADDITIVE (test-only, rig-free, in-memory, fixed-epoch). 25/25 pass. Stacks on the D-MINER.1 rollup KAT branch. --- scripts/miner_presence_sampler.py | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/scripts/miner_presence_sampler.py b/scripts/miner_presence_sampler.py index e19e4d4b4..e5a91ec0d 100755 --- a/scripts/miner_presence_sampler.py +++ b/scripts/miner_presence_sampler.py @@ -262,6 +262,38 @@ def daily(con): "SELECT 1 FROM daily WHERE day=? AND worker=?", (old_day, "A")).fetchone() check("daily kept forever (pruned-day summary survives)", has_old_daily is not None) + # 7) per-worker isolation: two workers in the SAME UTC day -> independent + # rows; one miner's downtime/stale must never bleed into another's report + con = fresh() + for k in range(4): + add_raw(con, base + k * 3600, "A", 6000.0, 2000.0) # A: 4 online, 25% stale + add_raw(con, base, "B", 9000.0, 0.0) # B: 1 online, 0% stale + add_raw(con, base + 3600, "B", 0.0, 0.0) # B: 1 offline + rollup(con, 3600) + d = daily(con) + iday = list({k[0] for k in d if k[1] == "A"})[0] + aho, aah, an, ash, ast = d[(iday, "A")] + bho, bah, bn, bsh, bst = d[(iday, "B")] + check("isolation: A hours independent of B", abs(aho - 4.0) < 1e-9) + check("isolation: B hours independent of A", abs(bho - 1.0) < 1e-9) + check("isolation: A stale% unmixed [25]", abs(ast - 25.0) < 1e-9) + check("isolation: B stale% unmixed [0]", abs(bst - 0.0) < 1e-9) + check("isolation: B avg over its own online sample [9000]", abs(bah - 9000.0) < 1e-9) + + # 8) all-offline worker: live==0 throughout -> NO phantom presence; a worker + # still emitting dead_hashrate reads stale=100 (its work was all dead), not 0 + con = fresh() + add_raw(con, base, "C", 0.0, 0.0) + add_raw(con, base + 3600, "C", 0.0, 1500.0) # offline but dead work reported + rollup(con, 3600) + d = daily(con) + cday = list({k[0] for k in d if k[1] == "C"})[0] + cho, cah, cn, csh, cst = d[(cday, "C")] + check("all-offline: hours_online == 0 (no phantom presence)", cho == 0.0) + check("all-offline: avg_hashrate == 0 (no phantom rate)", cah == 0.0) + check("all-offline: samples still counted (worker not vanished)", cn == 2) + check("all-offline: stale=100 when only dead work reported", abs(cst - 100.0) < 1e-9) + print("\nSELFTEST PASS" if not fails else "\nSELFTEST FAIL: " + ", ".join(fails)) return 1 if fails else 0