Run 6 on build-5 (24 leased cores, zero restarts): the real proof's bytes under another block's statement refused as a cheap context refusal (no verifier run, nothing cached); the same bytes under the honest record verified once in consensus and paid exactly once on both honest nodes at the same chain block for the same wei; the invalid bytes verified once and refused again from the cache at a later carrier. H1's and H2's verdicts and paid maps identical. Runs 1 to 5 (the exec pool verifier Off on a node without the counters, a host pin that was not the node's, the harness-unsafe feature missing, the 8-core lease against the 600-block record window, a stale manifest beside the harness) are in the rows as the record of each fault, none the node's. Plan section 6 MEASURED; the batch note carries the result (F01's cell is the enforced lane's). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| difficulty | ||
| economy | ||
| finality-attacks-results | ||
| horizon | ||
| peer-directory | ||
| finality_sim.py | ||
| finality_v2.py | ||
| README.md | ||
| results.md | ||
| results_v2.md | ||
sim
Simulations of Igneum consensus rules. One script per rule, results next to it.
finality_sim.py
Simulates the sustained-mining finality vote-weight rule: each key's weight is the sum over
the trailing 30 days of its counted blocks, where a day's counted blocks are capped at
2x the previous day's counted blocks plus a floor f. A checkpoint locks at two thirds of
total weight. Scenarios A to F (steady state, rental burst, key splitting, honest growth
shock, churn, patient owner) are described in results.md together with the model's
assumptions and the measured numbers.
Requirements: Python 3, numpy (checked present: 3.10.10, numpy 2.2.6 on 3 October 2026).
Run everything (about one second):
python3 finality_sim.py > out.md
Options:
--seed N random seed, default 7 (seed 11 gives the same crossing days)
--scenarios A,B subset of A,B,C,D,E,F
--floors 1,10 floor values in blocks per key per day, default 1,10,100,1000
--growth 2.0 daily cap multiplier (1e9 removes the cap)
--window 30 trailing window in days
--committee 100 committee size, used only for the active-24-hour total in E
--presence 0 proposed presence gate, 0 = off (tested and rejected in results.md)
The runs behind results.md:
python3 finality_sim.py
python3 finality_sim.py --growth 1e9 --scenarios B --floors 1
python3 finality_sim.py --presence 20 --scenarios C,D
python3 finality_sim.py --seed 11 --scenarios A,B --floors 1,1000
Output is markdown tables on stdout. Days in B to E are counted from the event, so "+1" is the first full day after the burst, the doubling or the churn.
Model limits are listed at the end of results.md: no latency, no DAG, no VRF sampling noise,
instant difficulty retarget, free keys.
finality_v2.py
Simulates FINALITY RULE V2 (CLAUDE.md, review round 2): flat 30-day weight window, no damping,
dust threshold 100 blocks, a checkpoint every 30 blocks, every voter signs every checkpoint,
lock at 2/3 of the ACTIVE denominator (weight x participation over a 240-checkpoint presence
window) compared against the TOTAL denominator. Unlike finality_sim.py it steps one 30-s slot
at a time and models regions with message delay, uptime, partitions (each side forms its own
checkpoints and certificates, merged at the heal with conflicting locks counted), an eclipsed
pool, and equivocation stripping. The DAG stays abstract: every block is blue, a side's
checkpoint block at index i is the block at blue score 30i in that side's view.
Three readings of "participation" are selectable with --pmode inside the script (the scenarios
run all three where it matters): cert (the brief, an uncertified index credits nobody),
seen (an uncertified index credits the keys whose votes were observed), frozen (the window
is over certified indices only). Scenarios A to G and every assumption are in results_v2.md.
Requirements: Python 3, numpy (3.10.10, numpy 2.2.6 on 3 October 2026).
Run everything (about five minutes):
python3 finality_v2.py > out_v2.md
Options:
--seed N random seed, default 7
--scenarios A,E subset of A,B,C,D,E,F,G
--delay 2.0 one-way inter-region delay in seconds for the main runs (A also sweeps 0.5, 2, 5)
--grace 15 seconds after a checkpoint during which late votes still enter the certificate
--quick shortened runs for development
The runs behind results_v2.md:
python3 finality_v2.py
python3 finality_v2.py --seed 11 --scenarios B,E
Timing output goes to stderr, tables to stdout. Minutes in C to F are wall minutes after the event.