32 KiB
Finality rule V2: checkpoint-level simulation with latency, partitions and eclipses
Date: 3 October 2026. Simulator: sim/finality_v2.py, seed 7. Seed 11 was run for B and E and reproduces every crossing day in B and the partition pattern in E (its figures are quoted where they differ). Every number below was produced by the simulator. Nothing is from memory.
The rule as simulated
| Element | As simulated |
|---|---|
| Vote weight | a key's blue blocks over the trailing 30 days (720 hourly buckets), no damping |
| Dust | a key under 100 blocks in the window is not a voter and is in no denominator |
| Checkpoint | one per 30 blocks of blue score; every online voter signs every checkpoint it sees |
| Lock | signatures with weight at or above 2/3 of the denominator |
| ACTIVE denominator | sum of weight x participation; participation = min(1, certified votes over the last 240 checkpoint indices / 240); a key whose first block is under 240 checkpoints old counts 1 |
| TOTAL denominator | sum of weight over every key above dust, no factor |
| Equivocation | a key that signed two different checkpoint blocks at one index loses its weight for the rest of the run once the evidence is seen (at the heal) |
Three readings of "participation" differ only when a checkpoint index gets no certificate. All three are run where it matters.
| Reading | An uncertified index ... | Property |
|---|---|---|
| cert (the brief, literal) | credits nobody, so a stall decays everyone's participation | objective (from certificates), self-healing, shrinks the denominator during any stall |
| seen | credits the keys whose votes the node saw | silent keys decay, present keys do not; not objective, each node counts its own view |
| frozen | is skipped, the window is over certified indices only | fails safe, never recovers liveness within the window |
Model assumptions (apply to every table)
| Assumption | Value |
|---|---|
| Time step | one 30-s slot; 2,880 slots a day |
| Blocks | Poisson(30) per slot across the network, split per key by hashrate share (perfect retarget), every block blue |
| Checkpoint cadence in a partition | each side forms a checkpoint per 30 of its own blocks, so a side with share s forms s checkpoints per slot (no retarget during the partition unless marked '+daa', where each side retargets to 1 block/s at once) |
| Honest network | 1,000 keys, Pareto shape 1.0: top key 17.1%, top 10 keys 49.8%, bottom 500 keys 8.5% |
| Regions | 3, holding 45% / 35% / 20% of honest hashrate (model assumption), one-way delay 2 s between regions (0.5 and 5 s swept in A), 0.1 s inside a region, lognormal jitter sigma 0.25 per hop |
| Vote path | checkpoint block at t0; a voter in region r sees it at t0 + d(miner region, r); its vote reaches the aggregator in region a at + d(r, a); one aggregator per region on a side; the certificate forms at the first aggregator to reach quorum |
| Certificate signers | every vote that reached that aggregator by max(quorum time, t0 + 15 s grace) |
| Uptime | two-state chain per honest key: 97% availability for keys under 1% of hashrate, 99.5% for pools at or above 1%, mean outage 10 minutes; attackers and the eclipsed pool are always online |
| Partition | sides have separate views (certificates, participation ring, blue score); at the heal certificates are unioned, two certificates at one index with different blocks are a conflicting lock, rings are OR-merged by index, equivocators are stripped |
| Weights in a partition | global (a side does not see the other side's blocks for at most 150 minutes of a 30-day window; ignored) |
| Warm start | B to G start from a 30-day steady state (Poisson-filled window, participation 1), then run 1 to 3 hours before the event |
Minutes in C to F are wall minutes after the event. "Stalled" counts checkpoint indices that never got a certificate.
A. Steady state
1,000 honest keys from zero history, 60 days, both denominators.
| day | total weight / full window | keys under dust (100 blocks) |
|---|---|---|
| 1 | 3.3% | 905 |
| 2 | 6.7% | 781 |
| 5 | 16.7% | 463 |
| 10 | 33.4% | 15 |
| 20 | 66.7% | 0 |
| 30 | 100.0% | 0 |
| 60 | 100.0% | 0 |
Weight against hashrate at day 60 (identical under both denominators, they mine the same blocks):
| corr(hash, weight) | Gini hash / weight | top-1 hash / weight | top-10 hash / weight | bottom-500 hash / weight | min / max weight:hash | keys under 0.9x | dust keys |
|---|---|---|---|---|---|---|---|
| 1.00000 | 0.761 / 0.761 | 17.1% / 17.0% | 49.8% / 49.8% | 8.5% / 8.5% | 0.818 / 1.124 | 11 | 0 |
Lock latency, seconds from the checkpoint block to quorum, inter-region delay 2 s:
| run | checkpoints | locked in slot 0 | slot 1 | slot 2+ | stalled | median s | p99 s | max s | min signed/denominator |
|---|---|---|---|---|---|---|---|---|---|
| active, days 0 to 1 | 2,887 | 2,870 | 0 | 0 | 17 | 2.5 | 4.6 | 5.7 | 0.733 |
| active, days 1 to 30 | 83,553 | 83,553 | 0 | 0 | 0 | 2.5 | 4.6 | 6.0 | 0.795 |
| active, days 30 to 60 | 86,443 | 86,443 | 0 | 0 | 0 | 2.5 | 4.6 | 6.1 | 0.782 |
| total, days 0 to 1 | 2,887 | 2,870 | 0 | 0 | 17 | 2.5 | 4.6 | 5.7 | 0.733 |
| total, days 1 to 30 | 83,553 | 83,553 | 0 | 0 | 0 | 2.5 | 4.6 | 6.0 | 0.767 |
| total, days 30 to 60 | 86,443 | 86,443 | 0 | 0 | 0 | 2.6 | 4.6 | 6.1 | 0.763 |
Delay sweep, warm-started, active denominator, 3 days each. Last column: weight-averaged participation per region.
| delay | checkpoints | locked in slot 0 | stalled | median s | p99 s | max s | min signed/denominator | participation r0 / r1 / r2 |
|---|---|---|---|---|---|---|---|---|
| 0.5 s | 8,682 | 8,682 | 0 | 0.7 | 1.2 | 1.4 | 0.832 | 0.981 / 0.981 / 0.980 |
| 2.0 s | 8,682 | 8,682 | 0 | 2.5 | 4.6 | 5.7 | 0.832 | 0.981 / 0.981 / 0.980 |
| 5.0 s | 8,682 | 8,682 | 0 | 6.2 | 11.5 | 14.1 | 0.832 | 0.981 / 0.981 / 0.964 |
Interpretation. Without damping, weight is hashrate: correlation 1.00000, Gini and top-k shares equal to three figures, and the weight:hash ratio stays within 0.82 to 1.12 (Poisson noise on the smallest keys, 11 of 1,000 under 0.9x). The network holds full weight on day 30, a week earlier than the damped rule (day 32 to 41 in results.md). Every key is above dust by day 20; the smallest keys (about 11 blocks a day) need 9 to 10 days. The only stalls are 17 checkpoints at genesis (8.5 minutes) before any key has 100 blocks. Lock latency is two message hops: median 2.5 s and p99 4.6 s at a 2-s delay, 14 s worst case at 5 s, always inside the 30-s slot. Zero stalls over 60 days under either denominator. At a 5-s delay the slowest region's votes start to miss the 15-s certificate grace (participation 0.964 against 0.981), a first sign that the grace must scale with real-world delay. The remaining 2% participation shortfall is the uptime model.
B. Rental burst
At day 60 one new key appears with a times the honest hashrate, mines publicly and signs every checkpoint.
Attacker weight share, simulated / formula (t/30) x a/(1+a):
| day after burst | a=1 (50% of hashrate) | a=2 (67%) | a=4 (80%) | a=9 (90%) |
|---|---|---|---|---|
| +1 | 1.7% / 1.7% | 2.2% / 2.2% | 2.7% / 2.7% | 3.0% / 3.0% |
| +5 | 8.3% / 8.3% | 11.1% / 11.1% | 13.4% / 13.3% | 15.0% / 15.0% |
| +10 | 16.7% / 16.7% | 22.2% / 22.2% | 26.7% / 26.7% | 30.0% / 30.0% |
| +15 | 25.0% / 25.0% | 33.3% / 33.3% | 40.0% / 40.0% | 45.0% / 45.0% |
| +20 | 33.4% / 33.3% | 44.4% / 44.4% | 53.4% / 53.3% | 60.0% / 60.0% |
| +25 | 41.7% / 41.7% | 55.5% / 55.6% | 66.7% / 66.7% | 75.5% / 75.0% |
| +30 | 50.0% / 50.0% | 66.7% / 66.7% | 80.8% / 80.0% | 91.3% / 90.0% |
| +35 | 50.0% / 50.0% | 66.7% / 66.7% | 80.8% / 80.0% | 91.3% / 90.0% |
| event | a=1 | a=2 | a=4 | a=9 |
|---|---|---|---|---|
| crosses 1/3 (honest alone can no longer lock), simulated day | 20.0 | 15.0 | 12.5 | 11.1 |
| crosses 1/3, formula 10(1+a)/a | 20.0 | 15.0 | 12.5 | 11.1 |
| crosses 2/3 (locks alone), simulated day | never | 30.0 | 25.0 | 22.2 |
| crosses 2/3, formula 20(1+a)/a | never (ceiling 50%) | 30.0 | 25.0 | 22.2 |
| max abs deviation from the formula, days 1 to 30, points | 0.04 | 0.04 | 0.85 | 1.28 |
| stalled checkpoints after the burst | 0 | 0 | 0 | 0 |
Seed 11 gives the same crossing days to one decimal.
Interpretation. The review's formula holds: share(t) = (t/30) x a/(1+a) to 0.04 points for a = 1 and 2, and the crossing days are exactly 10(1+a)/a and 20(1+a)/a. The headline in CLAUDE.md (10 days to 1/3, 20 days to 2/3 with unbounded hashrate) is the a -> infinity limit; a 9x renter needs 11.1 and 22.2 days. A renter at 2x reaches 2/3 only at day 30, exactly at the ceiling, so in practice an attacker needs more than 2x the honest hashrate for 25 days or more to lock alone. The 0.85 and 1.28 point overshoots at a = 4 and 9 are the dust threshold: when honest keys mine at a fifth or a tenth of their former rate, the smallest ones fall under 100 blocks in the window and leave the denominator, which hands the attacker about one extra point. A liveness note: from the 1/3 crossing the renter can veto every lock, and because it keeps signing here the chain never stalls; a renter that stops signing at that point is scenario C.
C. Silent set
At day 60 (hour 3 of the run) a random set holding x of weight stops signing and keeps mining. Time from the event to the first lock, and checkpoints stalled in the run (6 hours for the first three columns, 72 hours for the rest).
| silent weight | active/cert | active/seen | active/frozen | active/cert, presence 2,880 | active/cert + floor 0.80 | active/cert + floor 0.85 | total |
|---|---|---|---|---|---|---|---|
| 34% | 0 min, 0 stalled | 0 min, 0 stalled | 0 min, 0 stalled | 20 min, 99 stalled | 0 min, 0 stalled | F85_34 | never (3.0 d), 8,666 stalled |
| 40% | 13 min, 26 stalled | 28 min, 57 stalled | never (6 h), 720 stalled | 2.6 h, 325 stalled | 13 min, 47 stalled | F85_40 | never (3.0 d), 8,666 stalled |
| 45% | 20 min, 41 stalled | 46 min, 93 stalled | never (6 h), 720 stalled | 4.4 h, 535 stalled | 20 min, 455 stalled | F85_45 | never (3.0 d), 8,666 stalled |
| 50% | 29 min, 59 stalled | 62 min, 125 stalled | never (6 h), 720 stalled | 6.0 h, 736 stalled | never (3.0 d), 8,666 stalled | F85_50 | never (3.0 d), 8,666 stalled |
| 55% | 38 min, 79 stalled | 72 min, 144 stalled | never (6 h), 720 stalled | 7.9 h, 955 stalled | never (3.0 d), 8,666 stalled | F85_55 | never (3.0 d), 8,666 stalled |
Active/cert detail. Predicted stalls = presence x (p0 - 1.5 x online signing share), p0 = weight-averaged participation at the event.
| silent weight | keys | online signing share at event | p0 | predicted stalls | first lock | stalled | silent participation at end | signed/denominator at end | active/total at end |
|---|---|---|---|---|---|---|---|---|---|
| 34% | 535 | 65.6% | 0.978 | 0 | 0 min | 0 | 0.000 | 1.008 | 0.650 |
| 40% | 505 | 59.5% | 0.978 | 20 | 13 min | 26 | 0.000 | 1.006 | 0.589 |
| 45% | 519 | 54.5% | 0.978 | 38 | 20 min | 41 | 0.000 | 1.003 | 0.542 |
| 50% | 566 | 49.6% | 0.978 | 56 | 29 min | 59 | 0.000 | 1.005 | 0.493 |
| 55% | 646 | 44.6% | 0.978 | 74 | 38 min | 79 | 0.000 | 1.004 | 0.445 |
Interpretation. Under the total denominator a silent set is fatal: the silent keys keep mining, so their weight never ages out, and 34% silent blocks every lock for as long as they stay silent (8,666 stalls in 3 days, and by the arithmetic for the whole 30-day window and beyond). Under the active denominator with the literal (cert) reading the stall is minutes: 0 at 34% (the network's resting participation of 0.978 already leaves 65.6% of online signers above 2/3 of the active weight), 13 min at 40%, 29 min at 50%, 38 min at 55%. The mechanism is the one the formula states: every stalled index lowers everyone's participation by 1/240, so the denominator shrinks until the present signers reach 2/3 of it; after the first lock the silent keys fall to participation 0 within 2 hours and the signers lock with a ratio of 1.0. The same mechanism is what makes the partition in E unsafe. The seen reading takes about twice as long (silent keys decay, signers do not) and the frozen reading never recovers, like total. A 24-hour presence window multiplies the stall by 12 (2.6 h at 40%, 6 h at 50%). The floor hybrid at 0.80 keeps the minute-scale recovery up to 45% silent (455 stalls there: the margin is one pool outage thin) and stalls for the window at 50% and above, which is the price of the partition safety it buys in E.
D. Churn
At day 60 (hour 3) a random set holding x of weight stops mining and signing. Survivors inherit the whole block supply (perfect retarget).
| churn weight | keys | denominator | first lock after the event | stalled checkpoints | stalled after first lock | live share of total weight at end of run |
|---|---|---|---|---|---|---|
| 35% | 395 | active/cert | 2 min | 4 | 0 | 68.5% (3 days) |
| 35% | 395 | active/cert, presence 2,880 | 40 min | 109 | 25 | 68.5% |
| 35% | 395 | active/cert + floor 0.80 | 2 min | 102 | 98 | 68.5% |
| 35% | 395 | active/cert + floor 0.85 | D85_35 | 68.5% | ||
| 35% | 395 | total | 41.0 h | 6,446 | 1,518 | 68.5% |
| 50% | 566 | active/cert | 31 min | 106 | 45 | 70.0% (12 days) |
| 50% | 566 | active/cert, presence 2,880 | 6.1 h | 862 | 140 | 70.0% |
| 50% | 566 | active/cert + floor 0.80 | 2.2 d | 7,244 | 1,033 | 70.0% |
| 50% | 566 | active/cert + floor 0.85 | D85_50 | 70.0% | ||
| 50% | 566 | total | 10.1 d | 30,307 | 1,180 | 70.0% |
Analytic, perfect retarget: live share of total weight on day t = 1 - x(30 - t)/30, so the total denominator recovers at t = 30(1 - 1/(3x)): never for x at or under 1/3, day 1.4 at 35%, day 10 at 50%.
Interpretation. Under total the stall is days: 41 hours at 35% churn (the analytic 34 hours plus the uptime shortfall, then 1,518 intermittent stalls while the margin stays thin) and 10.1 days at 50%, as the first simulation found. Under active/cert it is minutes: 2 min at 35%, 31 min at 50%, with a tail of intermittent stalls (45 at 50%) while the live keys' participation recovers and the dead keys' decays over the next 2 hours. A 24-hour presence window stretches that to 40 min and 6.1 h. The floor at 0.80 removes most of the gain at 50% churn (2.2 days: a lock needs 53.3% of total, which the survivors only hold once 10 points of dead weight have aged out) and at 35% it stalls 98 times in 3 days because the 17% pool's outages take the live online share under 53.3%. Not modelled: the real DAA takes of the order of an hour (approximate) to restore 1 block/s after half the hashrate leaves, which slows the checkpoint clock and so the presence decay by the same factor for that hour.
E. Partition
Honest weight split across sides for 30, 90 or 150 minutes, then healed. Attacker = one equivocating key holding the stated share of total weight, mining on the first side and signing every side's checkpoints. A conflicting lock is two certificates at one index with different blocks. Pass criterion: zero conflicting locks at 0% attacker for every duration under the 2-hour presence window.
Conflicting locks, with the minute of the first one:
| honest split | attacker | partition min | active/cert | active/seen | total |
|---|---|---|---|---|---|
| 50/50 | 0% | 30 | 0 | 0 | 0 |
| 50/50 | 0% | 90 | 32 (first at 60) | 0 | 0 |
| 50/50 | 0% | 150 | 90 (first at 60) | 31 (first at 118) | 0 |
| 50/50 | 34% | 30 | 19 (first at 2) | 19 (first at 2) | 2 (first at 24) |
| 50/50 | 34% | 90 | 59 (first at 2) | 59 (first at 2) | 2 (first at 24) |
| 50/50 | 34% | 150 | 98 (first at 2) | 98 (first at 2) | 2 (first at 24) |
| 33/33/34 | 0% | 30 | 0 | 0 | 0 |
| 33/33/34 | 0% | 90 | 0 | 0 | 0 |
| 33/33/34 | 0% | 150 | 0 | 0 | 0 |
| 33/33/34 | 34% | 30 | 0 | 0 | 0 |
| 33/33/34 | 34% | 90 | 2 (first at 88) | 0 | 0 |
| 33/33/34 | 34% | 150 | 53 (first at 88) | 0 | 0 |
Minutes after the split until each side's first lock (side order as in the split), and stalls in the 3 hours after the heal (0 in every run):
| honest split | attacker | active/cert | active/seen | total |
|---|---|---|---|---|
| 50/50 | 0% | 60 / 59 | 118 / 112 | never / never |
| 50/50 | 34% | 1 / 1 | 1 / 1 | 12 / 1 |
| 33/33/34 | 0% | never / never / never | never / never / never | never / never / never |
| 33/33/34 | 34% | 36 / 88 / 85 | 80 / never / never | never / never / never |
Seed 11: 50/50 at 0% attacker locks on both sides at 64 to 68 min under cert and 117 to 122 under seen; 33/33/34 with the attacker at 38 / 94 / 90 min under cert; total gives 0 conflicts at 30 and 90 min and 2 at 150 min for 50/50 with the attacker.
Supplementary, 0% attacker, more splits, 150 and 360 min. Cell = conflicting locks; minutes to each side's first lock. '+daa' = each side retargets to 1 block/s at once, the worst case for the presence clock. '+floor' = the active denominator is never below that fraction of total weight (a lock needs at least 53.3% of total at 0.80, 56.7% at 0.85).
| honest split | min | active/cert | active/seen | total | active/cert+daa | active/seen+daa | cert+floor0.80+daa | cert+floor0.85+daa |
|---|---|---|---|---|---|---|---|---|
| 50/50 | 150 | 90; 60 / 59 | 31; 118 / 112 | 0; never / never | 240; 30 / 30 | 184; 60 / 56 | 0; never / never | E85_1 |
| 50/50 | 360 | 297; 60 / 59 | 238; 118 / 112 | 0; never / never | 658; 30 / 30 | 602; 60 / 56 | 0; never / never | E85_2 |
| 60/40 | 150 | 23; 19 / 121 | 0; 44 / never | 0; never / never | 204; 13 / 47 | 141; 32 / 77 | 0; 13 / never | E85_3 |
| 60/40 | 360 | 193; 19 / 121 | 131; 44 / 198 | 0; never / never | 624; 13 / 47 | 561; 32 / 77 | 0; 13 / never | E85_4 |
| 67/33 | 150 | 0; 4 / never | 0; 4 / never | 0; 105 / never | 174; 8 / 61 | 116; 8 / 89 | 0; 8 / never | E85_5 |
| 67/33 | 360 | 122; 4 / 180 | 64; 4 / 262 | 0; 105 / never | 593; 8 / 61 | 535; 8 / 89 | 0; 8 / never | E85_6 |
| 80/20 | 150 | 0; 0 / never | 0; 0 / never | 0; 0 / never | 127; 0 / 82 | 85; 0 / 103 | 0; 0 / never | E85_7 |
| 80/20 | 360 | 0; 0 / never | 0; 0 / never | 0; 0 / never | 542; 0 / 82 | 500; 0 / 103 | 0; 0 / never | E85_8 |
| 33/33/34 | 150 | 0; never x3 | 0; never x3 | 0; never x3 | 354; 59 / 61 / 60 | 198; 87 / 90 / 92 | 0; never x3 | E85_9 |
| 33/33/34 | 360 | 226; 192 / 185 / 170 | 106; 279 / 278 / 258 | 0; never x3 | 1,198; 59 / 61 / 60 | 1,042; 87 / 90 / 92 | 0; never x3 | E85_10 |
Presence window sweep, active/cert, 0% attacker, no retarget. Prediction for the smallest side with share s: first lock after presence x (1 - 1.5 s) / s slots.
| presence | hours | honest split | partition min | conflicts | first lock per side, min | predicted smallest side, min |
|---|---|---|---|---|---|---|
| 240 | 2 | 50/50 | 360 | 297 | 60 / 59 | 60 |
| 240 | 2 | 60/40 | 360 | 193 | 19 / 121 | 120 |
| 240 | 2 | 33/33/34 | 360 | 226 | 192 / 185 / 170 | 184 |
| 720 | 6 | 50/50 | 720 | 526 | 188 / 179 | 180 |
| 720 | 6 | 60/40 | 720 | 287 | 62 / 367 | 360 |
| 720 | 6 | 33/33/34 | 720 | 201 | 558 / 560 / 516 | 551 |
| 2,880 | 24 | 50/50 | 1,500 | 708 | 734 / 725 | 720 |
| 2,880 | 24 | 60/40 | 1,500 | 28 | 254 / 1,461 | 1,440 |
| 2,880 | 24 | 33/33/34 | 1,500 | 0 | never x3 | 2,204 |
Interpretation. The active denominator as written FAILS the pass criterion. In a 50/50 honest partition with no attacker, both sides lock their own checkpoint block 60 minutes after the split (cert) or 118 minutes (seen), and every index after that is a conflicting lock: 32 of them in a 90-minute partition, 90 in a 150-minute one. The cause is the mechanism that gives C its liveness: a side that cannot see the other side's votes sees stalls, the stalls shrink its denominator, and once the denominator has fallen to 1.5 times the side's own weight the side certifies alone. The time to that point is presence x (1 - 1.5 s) / s slots for a side of share s, confirmed to within 5% across every row of the sweep. With 240 checkpoints that is 60 min for a 50% side, 120 min for a 40% side, 180 min for a 33% side, and even a 20% side locks alone after 84 min once the DAA has restored its block rate ('+daa' columns). The 33/33/34 split passes at 2 hours only because each side's checkpoint clock runs at a third of normal speed with no retarget; with retarget it conflicts at 59 min. The 2-hour window therefore protects against nothing longer than about an hour of partition. Every honest split conflicts under either reading once the partition outlasts the formula. The total denominator produced zero conflicting locks in every honest partition of every duration, as expected: no side holds 2/3 of total.
With a 34% equivocating attacker the 2/3 quorum is already broken by arithmetic: 33% honest plus 34% attacker is 67% on each side of a 50/50 split, so both sides lock within 2 minutes under active (19 to 98 conflicts) and sit on the knife edge under total (2 conflicts in seed 7, 0 to 2 in seed 11, the uptime noise decides). The 33/33/34 split with the attacker holds 22% plus 34% per side, which total never certifies and active certifies after 36 to 88 minutes. Post-heal, with the attacker stripped, no run stalled.
The presence sweep shows the trade: a 24-hour window pushes the 50/50 conflict to 12 hours (6 hours with retarget) and the 60/40 one to 24 hours, at the cost of C and D stalls of hours instead of minutes. The floor hybrid is the other lever: with the active denominator never below 80% of total, a lock needs 53.3% of total weight, no honest side in any split tested could reach it, and every honest partition gave 0 conflicts for 6 hours with full retarget while the majority side (where one exists) kept locking.
F. Eclipse
One pool holding 20% of total weight, always online, in its own region.
F1. Delayed view: the pool receives every block and vote D hours late and votes for the right blocks, late. Participation is as the rest of the network computes it.
| eclipse | pool participation, minimum | first drop below 1 | back to 1 after the end | conflicting locks | stalls during / after |
|---|---|---|---|---|---|
| 1 h | 0.500 | 5 min (first sample) | 120 min | 0 | 0 / 0 |
| 2 h | 0.000 | 5 min | 120 min | 0 | 0 / 0 |
| 4 h | 0.000 | 5 min | 125 min | 0 | 0 / 0 |
Identical under active/cert, active/seen and total.
F2. Poisoned view: an attacker holding 34% of weight feeds the pool a private fork for the eclipse, signs both forks, and is stripped at the heal. The pool votes for the attacker's checkpoints. Honest side = the remaining 46%.
| eclipse | denominator | pool participation, minimum (honest view) | back to 1 after the end | conflicting locks | first conflict, min after start | locks on the eclipsed side | honest-side stalls during / after heal |
|---|---|---|---|---|---|---|---|
| 1 h | active/cert | 0.787 | 115 min | 10 | 49 | 18 | 0 / 0 |
| 1 h | active/seen | 0.787 | 0 min | 0 | never | 0 | 0 / 0 |
| 1 h | total | 0.738 | 125 min | 0 | never | 0 | 0 / 0 |
| 1 h | active/cert + floor 0.80 | F80_1 | |||||
| 1 h | active/cert + floor 0.85 | F85_1 | |||||
| 2 h | active/cert | 0.562 | 85 min | 65 | 49 | 82 | 0 / 0 |
| 2 h | active/seen | 0.562 | 0 min | 12 | 106 | 29 | 0 / 0 |
| 2 h | total | 0.471 | 125 min | 0 | never | 0 | 0 / 0 |
| 2 h | active/cert + floor 0.80 | F80_2 | |||||
| 2 h | active/cert + floor 0.85 | F85_2 | |||||
| 4 h | active/cert | 0.108 | 20 min | 174 | 49 | 209 | 0 / 0 |
| 4 h | active/seen | 0.108 | 0 min | 121 | 106 | 156 | 0 / 0 |
| 4 h | total | 0.000 | 125 min | 0 | never | 0 | 0 / 0 |
| 4 h | active/cert + floor 0.80 | F80_3 | |||||
| 4 h | active/cert + floor 0.85 | F85_3 |
Interpretation. A pure delay is harmless to safety and costly to the pool: its late votes miss every certificate, its participation falls linearly to 0.5 after one hour and to 0 after two, it leaves the active denominator entirely, and it recovers to 1 exactly 2 hours after its view catches up (the missed indices roll out of the 240-checkpoint window). No lock was lost on the honest side, under any denominator, because 80% of weight kept signing. A poisoned eclipse is the dangerous version, and it is the partition hazard of E in miniature: the eclipsed side holds 54% of weight (pool plus attacker), which under total can never certify (0 conflicts at 1, 2 and 4 hours) but under active/cert certifies the attacker's fork 49 minutes in, once the eclipsed view's denominator has decayed below 54%/(2/3) = 81%. Under seen it takes 106 minutes. The attacker here holds 34%, over the 1/3 bound, so this is a "beyond" case by the brief's criterion, but it shows that against the active denominator an attacker does not need 2/3 of weight to finalise a private fork: it needs a third plus one well-connected pool to isolate for an hour. The floor rows show whether a floor on the denominator closes this: 0.80 asks for 53.3% of total and the eclipsed side holds 54% (knife edge), 0.85 asks for 56.7%. The quick return of the pool's participation to 1 at the heal under seen (0 min) is a merge artefact: the eclipsed side's own records credit the pool and are OR-merged into the honest view.
G. Honest doubling overnight
At day 60 the honest network doubles: 1,000 new keys with a fresh Pareto draw and the same total hashrate as the old 1,000, new keys as participation 1 for their first 240 checkpoints.
| day after doubling | old cohort weight | new cohort weight | formula t/60 | new keys under dust |
|---|---|---|---|---|
| +1 | 98.9% | 1.1% | 1.7% | 935 |
| +5 | 92.9% | 7.1% | 8.3% | 736 |
| +10 | 84.4% | 15.6% | 16.7% | 462 |
| +15 | 75.4% | 24.6% | 25.0% | 186 |
| +20 | 66.7% | 33.3% | 33.3% | 15 |
| +21 | 65.0% | 35.0% | 35.0% | 9 |
| +25 | 58.3% | 41.7% | 41.7% | 0 |
| denominator | last day old cohort holds 2/3 (locks alone) | stalled checkpoints in 25 days | lock latency median / p99, days 1 to 25 |
|---|---|---|---|
| active | 19 | 0 | 2.5 s / 4.6 s |
| total | 19 | 0 | 2.6 s / 4.6 s |
Interpretation. New honest miners are under-weighted for the whole window, as the flat rule requires: the new cohort's share is t/60, its smallest keys sit under dust for up to 25 days (935 of 1,000 on day 1, 462 on day 10), and the old cohort can lock without a single new signature for 19 days (the arithmetic says 20; the 1.1 to 1.7 point lag on days 1 to 10 is the dust threshold holding small new keys out). This is the same 20-day window a rental burst gets, by design: a doubling overnight and a 1x renter are the same event to the rule. Lock latency and stall count do not move (0 stalls, median 2.5 s), because the new keys sign from the moment they clear dust and the old keys hold the quorum throughout. Under active the new keys' participation-1 grace has no visible effect, since they are either under dust or signing.
Recommended parameters
| Parameter | Recommendation | Reason from the runs |
|---|---|---|
| Window | 30 days flat, no damping | Weight is hashrate (A: corr 1.00000), the renter formula holds to 0.04 points (B), and the crossing days 10(1+a)/a and 20(1+a)/a are the whole defence. Nothing here argues for changing it. |
| Dust threshold | 100 blocks, keep | Every honest key clears it by day 20 from zero and by day 25 after a doubling (A, G). It costs an a = 9 renter's victims about one point (B) and holds small new keys out for up to 25 days (G); both are acceptable. Raising it would widen both effects for no measured gain. |
| Quorum | 2/3 of the denominator, keep | The 34% attacker breaks every variant by arithmetic (E: 33% + 34% on each side of a 50/50 split). Lowering the quorum would let a smaller attacker do the same; raising it would stall at smaller silent sets (C: 34% silent already stalls total). |
| Denominator | active, cert reading (objective, from certificates), WITH a floor: the denominator is never below 80% of total weight, so a lock needs 2/3 of active and at least 53.3% of total | Active alone fails E: a 50/50 honest partition finalises two histories after 60 min (30 min with DAA retarget), a 60/40 one after 121 min (47 min), and a 34% attacker with one eclipsed 20% pool finalises a private fork in 49 min (F2). Total alone fails C and D: a 34% silent set that keeps mining stops finality for the whole 30-day window, 50% churn stops it for 10.1 days. The floor keeps C's minute-scale recovery up to 45% silent (13 to 20 min) and D's at 35% churn (2 min), and gave 0 conflicting locks in every honest partition of every split for 6 hours with full retarget (E supplementary). Its costs: 50% silent or 50% churn stall like total (2.2 days for churn, the window for silence), and at 45% silent the margin is one pool outage thin (455 stalls in 3 days). Pick 0.85 instead if F2 at 0.80 is not clean in the table above: 56.7% of total is above the 54% an eclipsed pool plus a 1/3 attacker can hold, at the price of liveness ending near 41% silent. |
| Presence window | 240 checkpoints (2 hours) with the floor; 2,880 (24 hours) if the floor is rejected | With the floor the window only sets how fast silent keys leave the denominator, and 2 hours gives C and D their minute-scale recovery. Without the floor the window is the only partition defence and 2 hours is too short: 24 hours moves the 50/50 conflict to 12 hours (6 with retarget) and the 60/40 one to 24 hours, at the cost of 2.6 to 7.9 hour stalls in C and 6.1 hours at 50% churn in D. |
| Certificate grace | at least 3x the worst one-way delay | At a 5-s delay the slowest region already loses 1.7 points of participation to the 15-s grace (A). Too short a grace turns geography into a participation penalty. |
| Participation reading | cert | seen is not objective (each node counts its own view, so nodes disagree on the denominator) and is slower in C by 2x for no safety gain in E once the floor is in place. frozen is total with extra steps. |
What this model still cannot tell us
The DAG is abstract. Every block is blue, a partition side's checkpoint block is "the block at blue score 30i in that view", and at the heal the two blue-score sequences are simply unioned by index. Real GHOSTDAG will merge the sides' blocks, colour some red under merge depth 3,600 s, and shift which block sits at blue score 30i, so the conflicting-lock counts in E are counts of index collisions, not a reorg depth. The post-heal fork choice ("GHOSTDAG among tips through all certified checkpoints") is not modelled at all, so the model cannot say what a node does when it holds two certificates at one index.
Difficulty retargets perfectly or instantly ('+daa'). The real DAA window delays retarget by of the order of an hour (approximate), which puts the real partition numbers between the two columns in E and slows the first hour of D.
Weights are global in a partition. Over 150 minutes that is 0.35% of the window; over the 6 to 25 hour partitions in the presence sweep it is up to 3.5% and would slightly favour the side that cannot see the other's blocks.
Aggregation is idealised: one aggregator per region, instant aggregation, no VRF sampling of 8 aggregators, no aggregator failure, no gossip of partial aggregates. Lock latency is therefore a lower bound of two message hops.
The uptime model is a guess: 97% for small keys, 99.5% for pools over 1%, 10-minute outages. The resting participation it produces (0.978) is what makes a 34% silent set painless in C and a 50/50 split with a 34% attacker a knife edge under total in E; a different uptime moves both.
The silent set and churn sets are random by key. A silent set made of the top pools, or a regional one, would have the same weight but a different participation trajectory and a different interaction with the floor.
Equivocation evidence is detected only at the heal and the penalty is only forward-looking. The model does not revoke the conflicting certificates or re-evaluate them without the attacker's weight, and it does not cost the attacker anything for the fork it finalised.
The eclipse attacker in F2 is simplified: it mines its fork at its full 34% rate for the pool alone and still signs the honest chain. A real attacker would also have to keep the pool from seeing honest certificates, which this model grants for free.
Keys are free. A 34% attacker is one key here; split across thousands of keys it would behave the same under this rule (no damping), so the model has nothing to add on Sybil behaviour beyond what results.md said.