igneum/sim/difficulty/attacks/results.md
igneum-labs c01b9544a4 Difficulty: the live oscillation of 4 October, its cause, the DAG replay and rule v2 (reference window 600 behind a height switch)
Live devnet v4: a second RTX 5090 joining 7 minutes into an epoch left the whole-epoch reference lane polluted for the hour; the short lane read 11 to 25% above it and the 25% trigger flipped between the two for 40 minutes (102M to 164M, 54 to 81 blocks a minute). Record and hash-rate truth under sim/difficulty/records/. sim.py gains a DAG model (miners on nodes with igneum-miner's template staleness, GHOSTDAG, the rule as the node runs it) and --live replay: std of log difficulty 0.115 against the record's 0.134, 4.3 peaks of 1.31x against 4 of 1.37x. The brief's candidates (short lane 240/360, ease clamp 3%, clamp once per DAA second, hysteresis, median of three) leave 0.09 to 0.13; capping the reference lane at the newest 600 blocks of the epoch gives 0.026 with no flips. Rule v2 = that cap, epoch lane only, behind difficulty_v2_activation_daa (devnet-v4 fork). Attack suite and synthetic set before and after, 3-node test network of the switch (testnet_v2.py), analysis document, spec 2.3, bench-log entry, ledger M24, fast-time file carries the new field.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 13:26:23 +00:00

474 lines
37 KiB
Markdown

# Raw simulator output behind README.md (4 October 2026)
Seeds 7, 8, 9 unless stated. Tables are attacks.py output; the candidate igneum-san is the sanitised clock with the 60 s lag bound (README.md, Part B) unless stated.
## Full suite, Kaspa's timestamp rules (the forger under 132 s and the past median)
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum', 'igneum-san', 'kaspa']
### 1. Pool hopping: hopper's blocks per hash against the always-on base (adv = ratio - 1), 24 h
| rule | x | dwell | adv | adv_worst | hop_on_frac | switches | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 10 | 0 | 0.015 | 0.015 | 0.432 | 301.0 | 0.072 | 12.7 | 0.998 | 3 |
| igneum | 10 | 60 | 0.013 | 0.014 | 0.437 | 227.0 | 0.072 | 12.6 | 0.998 | 3 |
| igneum | 30 | 0 | 0.010 | 0.011 | 0.216 | 492.0 | 0.135 | 12.8 | 0.994 | 3 |
| igneum | 30 | 60 | 0.001 | 0.003 | 0.283 | 394.0 | 0.140 | 13.9 | 0.992 | 3 |
| igneum | 50 | 0 | 0.009 | 0.010 | 0.149 | 616.7 | 0.197 | 13.8 | 0.992 | 3 |
| igneum | 50 | 60 | -0.017 | -0.022 | 0.283 | 544.7 | 0.211 | 13.8 | 0.984 | 3 |
| igneum | 100 | 0 | 0.007 | 0.007 | 0.085 | 741.0 | 0.339 | 13.3 | 0.990 | 3 |
| igneum | 100 | 60 | -0.040 | -0.054 | 0.378 | 818.0 | 0.349 | 16.9 | 0.968 | 3 |
| igneum-san | 10 | 0 | 0.015 | 0.015 | 0.432 | 301.0 | 0.072 | 12.7 | 0.998 | 3 |
| igneum-san | 10 | 60 | 0.013 | 0.014 | 0.437 | 227.0 | 0.072 | 12.6 | 0.998 | 3 |
| igneum-san | 30 | 0 | 0.010 | 0.011 | 0.216 | 492.0 | 0.135 | 12.8 | 0.994 | 3 |
| igneum-san | 30 | 60 | 0.001 | 0.003 | 0.283 | 394.0 | 0.140 | 13.9 | 0.992 | 3 |
| igneum-san | 50 | 0 | 0.009 | 0.010 | 0.149 | 616.7 | 0.197 | 13.8 | 0.992 | 3 |
| igneum-san | 50 | 60 | -0.017 | -0.022 | 0.283 | 544.7 | 0.211 | 13.8 | 0.984 | 3 |
| igneum-san | 100 | 0 | 0.007 | 0.007 | 0.085 | 741.0 | 0.339 | 13.3 | 0.990 | 3 |
| igneum-san | 100 | 60 | -0.040 | -0.054 | 0.378 | 818.0 | 0.349 | 16.9 | 0.968 | 3 |
| kaspa | 10 | 0 | 0.008 | 0.009 | 0.367 | 63.7 | 0.054 | 11.8 | 1.000 | 3 |
| kaspa | 10 | 60 | 0.008 | 0.009 | 0.367 | 63.7 | 0.054 | 11.8 | 1.000 | 3 |
| kaspa | 30 | 0 | 0.006 | 0.007 | 0.181 | 88.0 | 0.124 | 12.3 | 1.001 | 3 |
| kaspa | 30 | 60 | 0.006 | 0.007 | 0.181 | 88.0 | 0.124 | 12.3 | 1.001 | 3 |
| kaspa | 50 | 0 | 0.005 | 0.006 | 0.116 | 112.3 | 0.180 | 12.7 | 1.001 | 3 |
| kaspa | 50 | 60 | 0.005 | 0.006 | 0.115 | 111.3 | 0.179 | 12.6 | 1.001 | 3 |
| kaspa | 100 | 0 | 0.005 | 0.006 | 0.061 | 122.7 | 0.304 | 12.5 | 1.001 | 3 |
| kaspa | 100 | 60 | 0.004 | 0.005 | 0.068 | 132.0 | 0.315 | 12.5 | 1.001 | 3 |
### 2. Pulsed hash rate: 50x for 10 min, every hour (period 3600) and once (period 1000000); weight_per_hash = block share / hash share
| rule | period_s | pulse_vs_base | pulse_vs_base_worst | weight_per_hash | weight_per_hash_worst | pulse_vs_steady | base_vs_steady | pulse_block_share | pulse_hash_share | peak_blocks_per_min | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 3600 | -0.963 | -0.964 | 0.263 | 0.267 | -0.977 | -0.375 | 0.234 | 0.893 | 183.7 | 152.5 | 0.824 | 3 |
| igneum | 1000000 | -0.971 | -0.972 | 0.131 | 0.138 | -0.976 | -0.186 | 0.106 | 0.806 | 177.0 | 81.3 | 0.920 | 3 |
| igneum-san | 3600 | -0.964 | -0.965 | 0.262 | 0.267 | -0.977 | -0.362 | 0.234 | 0.893 | 182.3 | 221.4 | 0.823 | 3 |
| igneum-san | 1000000 | -0.971 | -0.972 | 0.130 | 0.136 | -0.976 | -0.179 | 0.105 | 0.806 | 177.0 | 78.4 | 0.927 | 3 |
| kaspa | 3600 | -0.145 | -0.159 | 0.983 | 0.984 | -0.898 | -0.880 | 0.878 | 0.893 | 1734.0 | 102.7 | 0.979 | 3 |
| kaspa | 1000000 | -0.432 | -0.443 | 0.871 | 0.879 | -0.884 | -0.796 | 0.703 | 0.806 | 1734.0 | 68.4 | 0.686 | 3 |
### 3. Timestamp stretching inside the rules: block rate after 1 h of forging (drift = rate - 1), 6 h runs
| rule | ts_rules | share | stamp | forger_offset_s | rate_pre | rate_post | rate_last_hour | drift | drift_worst | D_ratio | std | worst_gap | forger_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum | kaspa | 30 | future | 132.0 | 0.994 | 0.656 | 0.658 | -0.344 | -0.350 | 1.549 | 0.136 | 15.6 | 0.000 | 3 |
| igneum | kaspa | 30 | past | -439.1 | 0.994 | 0.415 | 0.428 | -0.585 | -0.597 | 2.421 | 0.243 | 44.8 | 0.000 | 3 |
| igneum | kaspa | 30 | alt | -70.3 | 0.994 | 0.514 | 0.513 | -0.486 | -0.545 | 1.966 | 0.381 | 37.0 | 0.000 | 3 |
| igneum | kaspa | 50 | future | 132.0 | 0.994 | 0.563 | 0.573 | -0.437 | -0.449 | 1.796 | 0.103 | 17.1 | 0.000 | 3 |
| igneum | kaspa | 50 | past | -2122.9 | 0.994 | 0.116 | 0.119 | -0.884 | -0.925 | 9.886 | 0.186 | 233.8 | 0.000 | 3 |
| igneum | kaspa | 50 | alt | -289.0 | 0.994 | 0.231 | 0.221 | -0.769 | -0.804 | 4.393 | 0.257 | 83.5 | 0.000 | 3 |
| igneum-san | kaspa | 30 | future | 132.0 | 0.994 | 0.091 | 0.100 | -0.909 | -0.911 | 10.9 | 0.055 | 119.1 | 0.000 | 3 |
| igneum-san | kaspa | 30 | past | -195.5 | 0.994 | 0.931 | 0.874 | -0.069 | -0.092 | 1.084 | 0.228 | 20.4 | 0.000 | 3 |
| igneum-san | kaspa | 30 | alt | -786.0 | 0.994 | 0.087 | 0.091 | -0.913 | -0.918 | 11.6 | 0.058 | 126.6 | 0.000 | 3 |
| igneum-san | kaspa | 50 | future | 132.0 | 0.994 | 0.166 | 0.188 | -0.834 | -0.860 | 6.046 | 0.173 | 102.4 | 0.000 | 3 |
| igneum-san | kaspa | 50 | past | -4510.6 | 0.994 | 0.033 | 0.009 | -0.967 | -0.992 | 64.0 | 0.098 | 607.0 | 0.000 | 3 |
| igneum-san | kaspa | 50 | alt | -2039.9 | 0.994 | 0.038 | 0.036 | -0.962 | -0.968 | 25.6 | 0.024 | 439.2 | 0.000 | 3 |
| kaspa | kaspa | 30 | future | 132.0 | 0.993 | 1.049 | 1.049 | 0.049 | 0.052 | 0.959 | 0.018 | 8.825 | 0.000 | 3 |
| kaspa | kaspa | 30 | past | -170.2 | 0.993 | 1.069 | 1.073 | 0.069 | 0.072 | 0.941 | 0.021 | 8.675 | 0.000 | 3 |
| kaspa | kaspa | 30 | alt | 6.993 | 0.993 | 1.090 | 1.092 | 0.090 | 0.092 | 0.923 | 0.023 | 8.463 | 0.000 | 3 |
| kaspa | kaspa | 50 | future | 132.0 | 0.993 | 1.050 | 1.052 | 0.050 | 0.054 | 0.958 | 0.018 | 8.840 | 0.000 | 3 |
| kaspa | kaspa | 50 | past | -235.6 | 0.993 | 1.113 | 1.113 | 0.113 | 0.116 | 0.904 | 0.027 | 8.353 | 0.000 | 3 |
| kaspa | kaspa | 50 | alt | 8.892 | 0.993 | 1.098 | 1.100 | 0.098 | 0.100 | 0.916 | 0.021 | 8.451 | 0.000 | 3 |
### 4. Short-lane oscillation: 25% miner on and off every 120 blocks (std_floor = the hash square wave at a fixed D)
| rule | share | period | std_pre | std_post | std_ratio | std_ratio_worst | std_floor | worst_gap_pre | worst_gap_post | blocks_per_s | osc_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 25 | 120 | 0.045 | 0.160 | 3.753 | 4.815 | 0.143 | 8.789 | 11.0 | 0.980 | -0.014 | 3 |
| igneum-san | 25 | 120 | 0.045 | 0.160 | 3.753 | 4.815 | 0.143 | 8.789 | 11.0 | 0.980 | -0.014 | 3 |
| kaspa | 25 | 120 | 0.010 | 0.147 | 16.4 | 23.5 | 0.143 | 8.906 | 10.3 | 1.001 | 0.000 | 3 |
### 5. Epoch-boundary games: hold dodger (30%, off for blocks 0 to 7), hold flooder (10x, on for blocks 0 to 7), 30% flooder
| rule | kind | gamer_adv | gamer_adv_worst | gamer_on_frac | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|
| igneum | dodge | 0.000 | 0.000 | 0.997 | 0.054 | 9.598 | 1.002 | 3 |
| igneum | flood | 0.007 | 0.024 | 0.000 | 0.470 | 9.986 | 0.995 | 3 |
| igneum | flood30 | 0.003 | 0.021 | 0.001 | 0.054 | 9.811 | 0.997 | 3 |
| igneum-san | dodge | 0.000 | 0.000 | 0.997 | 0.054 | 9.598 | 1.002 | 3 |
| igneum-san | flood | 0.007 | 0.024 | 0.000 | 0.470 | 9.986 | 0.995 | 3 |
| igneum-san | flood30 | 0.003 | 0.021 | 0.001 | 0.054 | 9.811 | 0.997 | 3 |
| kaspa | dodge | 0.000 | 0.000 | 0.997 | 0.026 | 9.360 | 1.001 | 3 |
| kaspa | flood | 0.000 | 0.005 | 0.000 | 0.482 | 9.293 | 1.001 | 3 |
| kaspa | flood30 | -0.001 | 0.004 | 0.002 | 0.030 | 9.278 | 1.001 | 3 |
### 6. Polluted window under adversarial timing: 10x miner joins at block join_k of an epoch and leaves at leave_k (600 = long lane takes over)
| rule | join_k | leave_k | join_first10_s | join_settled_s | leave_first10_s | leave_settled_s | leave_worst_gap_s | leave_below05 | leave_above2x | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 0 | 600 | 88.6 | 134.8 | 303.1 | 303.1 | 16.9 | 55.3 | 0.000 | 3 |
| igneum | 480 | 600 | none | none | 291.9 | 291.9 | 15.2 | 50.3 | 0.000 | 3 |
| igneum | 480 | 720 | 76.3 | 58.3 | 321.4 | 321.4 | 28.4 | 56.7 | 0.000 | 3 |
| igneum | 0 | 1200 | 88.6 | 134.8 | 312.2 | 334.0 | 24.5 | 56.7 | 0.000 | 3 |
| igneum-san | 0 | 600 | 88.6 | 134.8 | 296.8 | 296.8 | 16.4 | 55.3 | 0.000 | 3 |
| igneum-san | 480 | 600 | none | none | 286.7 | 286.7 | 14.8 | 47.3 | 0.000 | 3 |
| igneum-san | 480 | 720 | 76.3 | 58.3 | 312.0 | 312.0 | 28.4 | 54.3 | 0.000 | 3 |
| igneum-san | 0 | 1200 | 88.6 | 134.8 | 304.7 | 328.7 | 24.5 | 55.7 | 0.000 | 3 |
| kaspa | 0 | 600 | none | none | 2910.0 | 2910.0 | 9.954 | 0.000 | 0.000 | 3 |
| kaspa | 480 | 600 | none | none | 0.000 | 0.000 | 8.600 | 0.000 | 0.000 | 3 |
| kaspa | 480 | 720 | none | none | 135.3 | 135.3 | 8.838 | 0.000 | 0.000 | 3 |
| kaspa | 0 | 1200 | none | none | 3539.6 | 3539.6 | 13.1 | 0.000 | 0.000 | 3 |
## Timestamp stretching under the tight rules (README.md, Part A: 10 s ahead, selected parent minus 10 s)
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum', 'igneum-san', 'kaspa']
### 3. Timestamp stretching inside the rules: block rate after 1 h of forging (drift = rate - 1), 6 h runs
| rule | ts_rules | share | stamp | forger_offset_s | rate_pre | rate_post | rate_last_hour | drift | drift_worst | D_ratio | std | worst_gap | forger_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum | tight | 30 | future | 10.0 | 0.994 | 1.008 | 1.006 | 0.008 | 0.018 | 0.999 | 0.067 | 9.662 | 0.000 | 3 |
| igneum | tight | 30 | past | -16.6 | 0.994 | 0.636 | 0.649 | -0.364 | -0.381 | 1.597 | 0.201 | 32.5 | 0.000 | 3 |
| igneum | tight | 30 | alt | 1.012 | 0.994 | 0.975 | 0.968 | -0.025 | -0.035 | 1.030 | 0.067 | 10.7 | 0.000 | 3 |
| igneum | tight | 50 | future | 10.0 | 0.994 | 1.009 | 1.001 | 0.009 | 0.021 | 0.997 | 0.071 | 9.792 | 0.000 | 3 |
| igneum | tight | 50 | past | -30.3 | 0.994 | 0.170 | 0.132 | -0.830 | -0.850 | 5.917 | 0.115 | 106.0 | 0.000 | 3 |
| igneum | tight | 50 | alt | 1.975 | 0.994 | 0.949 | 0.936 | -0.051 | -0.057 | 1.059 | 0.088 | 11.6 | 0.000 | 3 |
| igneum-san | tight | 30 | future | 10.0 | 0.994 | 1.008 | 1.006 | 0.008 | 0.018 | 0.999 | 0.067 | 9.662 | 0.000 | 3 |
| igneum-san | tight | 30 | past | -15.8 | 0.994 | 1.008 | 1.006 | 0.008 | 0.024 | 0.998 | 0.077 | 9.920 | 0.000 | 3 |
| igneum-san | tight | 30 | alt | 1.036 | 0.994 | 1.004 | 1.001 | 0.004 | 0.012 | 1.001 | 0.052 | 9.826 | 0.000 | 3 |
| igneum-san | tight | 50 | future | 10.0 | 0.994 | 1.009 | 1.001 | 0.009 | 0.021 | 0.997 | 0.071 | 9.792 | 0.000 | 3 |
| igneum-san | tight | 50 | past | -21.9 | 0.994 | 1.007 | 1.012 | 0.007 | 0.027 | 1.000 | 0.147 | 10.1 | 0.000 | 3 |
| igneum-san | tight | 50 | alt | 2.017 | 0.994 | 1.011 | 1.005 | 0.011 | 0.022 | 0.995 | 0.071 | 9.996 | 0.000 | 3 |
| kaspa | tight | 30 | future | 10.0 | 0.993 | 1.000 | 1.003 | 0.000 | 0.005 | 1.005 | 0.017 | 9.249 | 0.000 | 3 |
| kaspa | tight | 30 | past | -15.8 | 0.993 | 1.002 | 1.002 | 0.002 | 0.007 | 1.002 | 0.018 | 9.239 | 0.000 | 3 |
| kaspa | tight | 30 | alt | 1.036 | 0.993 | 1.001 | 1.003 | 0.001 | 0.005 | 1.004 | 0.017 | 9.220 | 0.000 | 3 |
| kaspa | tight | 50 | future | 10.0 | 0.993 | 1.001 | 1.002 | 0.001 | 0.005 | 1.004 | 0.017 | 9.252 | 0.000 | 3 |
| kaspa | tight | 50 | past | -21.9 | 0.993 | 1.009 | 1.012 | 0.009 | 0.015 | 0.996 | 0.019 | 9.152 | 0.000 | 3 |
| kaspa | tight | 50 | alt | 1.987 | 0.993 | 1.001 | 1.002 | 0.001 | 0.005 | 1.004 | 0.017 | 9.238 | 0.000 | 3 |
## Base profiles (sim.py metrics) through each rule
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum', 'igneum-san', 'kaspa']
### Base profiles (sim.py metrics) through each rule
| rule | profile | first10_s | settled_s | settled_s_none | worst_gap_s | steady_std | peak_rate | not_recovered | seeds |
|---|---|---|---|---|---|---|---|---|---|
| igneum | up50 | 56.1 | 154.4 | none | 9.719 | 0.042 | none | none | 3 |
| igneum | down50 | 782.3 | 782.3 | none | 78.3 | 0.042 | none | none | 3 |
| igneum | epoch30 | 44.6 | 87.6 | none | 10.8 | 0.039 | none | 0.000 | 3 |
| igneum | walk10 | none | none | 3 | 10.7 | 0.058 | none | none | 3 |
| igneum | hop10 | 213.8 | 239.4 | none | 31.9 | 0.042 | none | 0.000 | 3 |
| igneum | polluted | 70.1 | 70.1 | none | 10.2 | 0.041 | 7.969 | none | 3 |
| igneum | warmup-hard | 381.3 | 381.3 | none | 34.6 | 0.039 | none | none | 3 |
| igneum-san | up50 | 56.1 | 154.4 | none | 9.719 | 0.042 | none | none | 3 |
| igneum-san | down50 | 728.5 | 762.2 | none | 73.9 | 0.042 | none | none | 3 |
| igneum-san | epoch30 | 44.6 | 87.6 | none | 10.8 | 0.039 | none | 0.000 | 3 |
| igneum-san | walk10 | none | none | 3 | 10.7 | 0.058 | none | none | 3 |
| igneum-san | hop10 | 210.3 | 245.1 | none | 35.6 | 0.042 | none | 0.000 | 3 |
| igneum-san | polluted | 74.9 | 74.9 | none | 10.2 | 0.041 | 11.4 | none | 3 |
| igneum-san | warmup-hard | 305.8 | 326.5 | none | 34.6 | 0.039 | none | none | 3 |
| kaspa | up50 | 1764.8 | 1764.8 | none | 9.869 | 0.014 | none | none | 3 |
| kaspa | down50 | 12306.2 | 12306.2 | none | 155.2 | 0.014 | none | none | 3 |
| kaspa | epoch30 | 1663.5 | 1663.5 | none | 10.9 | 0.023 | none | 0.000 | 3 |
| kaspa | walk10 | none | none | 3 | 10.8 | 0.044 | none | none | 3 |
| kaspa | hop10 | none | none | 3 | 45.6 | 0.014 | none | 12.0 | 3 |
| kaspa | polluted | 695.0 | 2713.3 | none | 11.4 | 0.013 | 8.225 | none | 3 |
| kaspa | warmup-hard | 5975.0 | none | 3 | 68.8 | 43.4 | none | none | 3 |
## Lag bound of the sanitised clock (older naming: igneum-san = 120 s bound, igneum-san-j60 = 60 s bound; 60 s was adopted)
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum-san', 'igneum-san-j60']
### Base profiles (sim.py metrics) through each rule
| rule | profile | first10_s | settled_s | settled_s_none | worst_gap_s | steady_std | peak_rate | not_recovered | seeds |
|---|---|---|---|---|---|---|---|---|---|
| igneum-san | up50 | 56.1 | 154.4 | none | 9.719 | 0.042 | none | none | 3 |
| igneum-san | down50 | 720.9 | 758.9 | none | 73.9 | 0.042 | none | none | 3 |
| igneum-san | epoch30 | 44.6 | 87.6 | none | 10.8 | 0.039 | none | 0.000 | 3 |
| igneum-san | walk10 | none | none | 3 | 10.7 | 0.058 | none | none | 3 |
| igneum-san | hop10 | 210.3 | 245.1 | none | 35.6 | 0.042 | none | 0.000 | 3 |
| igneum-san | polluted | 83.6 | 83.6 | none | 10.2 | 0.041 | 17.8 | none | 3 |
| igneum-san | warmup-hard | 305.8 | 326.5 | none | 34.6 | 0.039 | none | none | 3 |
| igneum-san-j60 | up50 | 56.1 | 154.4 | none | 9.719 | 0.042 | none | none | 3 |
| igneum-san-j60 | down50 | 728.5 | 762.2 | none | 73.9 | 0.042 | none | none | 3 |
| igneum-san-j60 | epoch30 | 44.6 | 87.6 | none | 10.8 | 0.039 | none | 0.000 | 3 |
| igneum-san-j60 | walk10 | none | none | 3 | 10.7 | 0.058 | none | none | 3 |
| igneum-san-j60 | hop10 | 210.3 | 245.1 | none | 35.6 | 0.042 | none | 0.000 | 3 |
| igneum-san-j60 | polluted | 74.9 | 74.9 | none | 10.2 | 0.041 | 11.4 | none | 3 |
| igneum-san-j60 | warmup-hard | 305.8 | 326.5 | none | 34.6 | 0.039 | none | none | 3 |
# Difficulty attacks, seeds [7], rules ['igneum-san', 'igneum-san-j60']
### 3. Timestamp stretching inside the rules: block rate after 1 h of forging (drift = rate - 1), 6 h runs
| rule | ts_rules | share | stamp | forger_offset_s | rate_pre | rate_post | rate_last_hour | drift | drift_worst | D_ratio | std | worst_gap | forger_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum-san | tight | 30 | future | 10.0 | 0.978 | 1.010 | 0.998 | 0.010 | 0.010 | 0.989 | 0.084 | 10.3 | 0.000 | 1 |
| igneum-san | tight | 30 | past | -15.9 | 0.978 | 1.014 | 1.000 | 0.014 | 0.014 | 0.984 | 0.097 | 11.1 | 0.000 | 1 |
| igneum-san | tight | 30 | alt | 1.051 | 0.978 | 1.009 | 0.999 | 0.009 | 0.009 | 0.989 | 0.068 | 10.9 | 0.000 | 1 |
| igneum-san | tight | 50 | future | 10.0 | 0.978 | 1.009 | 0.986 | 0.009 | 0.009 | 0.989 | 0.086 | 10.7 | 0.000 | 1 |
| igneum-san | tight | 50 | past | -22.1 | 0.978 | 1.040 | 1.030 | 0.040 | 0.040 | 0.960 | 0.190 | 10.7 | 0.000 | 1 |
| igneum-san | tight | 50 | alt | 2.023 | 0.978 | 1.014 | 0.991 | 0.014 | 0.014 | 0.984 | 0.097 | 11.3 | 0.000 | 1 |
| igneum-san-j60 | tight | 30 | future | 10.0 | 0.978 | 1.010 | 0.998 | 0.010 | 0.010 | 0.989 | 0.084 | 10.3 | 0.000 | 1 |
| igneum-san-j60 | tight | 30 | past | -15.9 | 0.978 | 1.012 | 0.995 | 0.012 | 0.012 | 0.986 | 0.096 | 11.1 | 0.000 | 1 |
| igneum-san-j60 | tight | 30 | alt | 1.051 | 0.978 | 1.009 | 0.999 | 0.009 | 0.009 | 0.989 | 0.068 | 10.9 | 0.000 | 1 |
| igneum-san-j60 | tight | 50 | future | 10.0 | 0.978 | 1.009 | 0.986 | 0.009 | 0.009 | 0.989 | 0.086 | 10.7 | 0.000 | 1 |
| igneum-san-j60 | tight | 50 | past | -22.2 | 0.978 | 1.002 | 1.013 | 0.002 | 0.002 | 0.999 | 0.181 | 10.7 | 0.000 | 1 |
| igneum-san-j60 | tight | 50 | alt | 2.023 | 0.978 | 1.014 | 0.991 | 0.014 | 0.014 | 0.984 | 0.097 | 11.3 | 0.000 | 1 |
## Clock without a lag bound (first candidate): base profiles, seed 7 to 9
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum', 'igneum-san']
### Base profiles (sim.py metrics) through each rule
| rule | profile | first10_s | settled_s | settled_s_none | worst_gap_s | steady_std | peak_rate | not_recovered | seeds |
|---|---|---|---|---|---|---|---|---|---|
| igneum | up50 | 56.1 | 154.4 | none | 9.719 | 0.042 | none | none | 3 |
| igneum | down50 | 782.3 | 782.3 | none | 78.3 | 0.042 | none | none | 3 |
| igneum | epoch30 | 44.6 | 87.6 | none | 10.8 | 0.039 | none | 0.000 | 3 |
| igneum | walk10 | none | none | 3 | 10.7 | 0.058 | none | none | 3 |
| igneum | hop10 | 213.8 | 239.4 | none | 31.9 | 0.042 | none | 0.000 | 3 |
| igneum | polluted | 70.1 | 70.1 | none | 10.2 | 0.041 | 7.969 | none | 3 |
| igneum | warmup-hard | 381.3 | 381.3 | none | 34.6 | 0.039 | none | none | 3 |
| igneum-san | up50 | 56.1 | 154.4 | none | 9.719 | 0.042 | none | none | 3 |
| igneum-san | down50 | 718.8 | 757.2 | none | 73.9 | 0.042 | none | none | 3 |
| igneum-san | epoch30 | 44.6 | 87.6 | none | 10.8 | 0.039 | none | 0.000 | 3 |
| igneum-san | walk10 | none | none | 3 | 10.7 | 0.058 | none | none | 3 |
| igneum-san | hop10 | 210.3 | 245.1 | none | 35.6 | 0.042 | none | 0.000 | 3 |
| igneum-san | polluted | 75.5 | 75.5 | none | 10.2 | 0.041 | 274.4 | none | 3 |
| igneum-san | warmup-hard | 305.8 | 326.5 | none | 34.6 | 0.039 | none | none | 3 |
## Early variant study, clock without a lag bound, Kaspa's timestamp rules, seed 7 (flat weights, lag, 10 T cap)
# Difficulty attacks, seeds [7], rules ['igneum-san-flat-lag0', 'igneum-san-flat-lag1', 'igneum-san-flat-lag2', 'igneum-san-lwma-lag1', 'igneum-san-lwma-lag2', 'igneum-san-flat-lag1-cap10']
### 3. Timestamp stretching inside the rules: block rate after 1 h of forging (drift = rate - 1), 6 h runs
| rule | share | stamp | forger_offset_s | rate_pre | rate_post | rate_last_hour | drift | drift_worst | D_ratio | std | worst_gap | forger_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum-san-flat-lag0 | 30 | future | 132.0 | 0.979 | 1.070 | 1.049 | 0.070 | 0.070 | 0.935 | 0.204 | 9.132 | 0.000 | 1 |
| igneum-san-flat-lag0 | 30 | past | -168.4 | 0.979 | 1.072 | 1.073 | 0.072 | 0.072 | 0.939 | 0.244 | 13.1 | 0.000 | 1 |
| igneum-san-flat-lag0 | 30 | alt | 5.685 | 0.979 | 1.070 | 1.059 | 0.070 | 0.070 | 0.936 | 0.118 | 11.0 | 0.000 | 1 |
| igneum-san-flat-lag0 | 50 | future | 132.0 | 0.979 | 1.063 | 1.042 | 0.063 | 0.063 | 0.943 | 0.438 | 12.5 | 0.000 | 1 |
| igneum-san-flat-lag0 | 50 | past | -285.0 | 0.979 | 0.823 | 0.536 | -0.177 | -0.177 | 1.229 | 14.5 | 77.4 | 0.000 | 1 |
| igneum-san-flat-lag0 | 50 | alt | 8.669 | 0.979 | 1.094 | 1.081 | 0.094 | 0.094 | 0.918 | 0.161 | 11.1 | 0.000 | 1 |
| igneum-san-flat-lag1 | 30 | future | 132.0 | 0.979 | 1.070 | 1.048 | 0.070 | 0.070 | 0.935 | 0.200 | 9.312 | 0.000 | 1 |
| igneum-san-flat-lag1 | 30 | past | -168.4 | 0.979 | 1.072 | 1.072 | 0.072 | 0.072 | 0.939 | 0.243 | 12.8 | 0.000 | 1 |
| igneum-san-flat-lag1 | 30 | alt | 5.639 | 0.979 | 1.069 | 1.058 | 0.069 | 0.069 | 0.936 | 0.117 | 10.7 | 0.000 | 1 |
| igneum-san-flat-lag1 | 50 | future | 132.0 | 0.979 | 1.063 | 1.040 | 0.063 | 0.063 | 0.943 | 0.435 | 12.1 | 0.000 | 1 |
| igneum-san-flat-lag1 | 50 | past | -285.8 | 0.979 | 0.823 | 0.527 | -0.177 | -0.177 | 1.238 | 14.5 | 72.7 | 0.000 | 1 |
| igneum-san-flat-lag1 | 50 | alt | 8.666 | 0.979 | 1.093 | 1.081 | 0.093 | 0.093 | 0.918 | 0.163 | 10.8 | 0.000 | 1 |
| igneum-san-flat-lag2 | 30 | future | 132.0 | 0.979 | 1.069 | 1.047 | 0.069 | 0.069 | 0.936 | 0.199 | 9.121 | 0.000 | 1 |
| igneum-san-flat-lag2 | 30 | past | -168.5 | 0.979 | 1.071 | 1.071 | 0.071 | 0.071 | 0.939 | 0.243 | 15.5 | 0.000 | 1 |
| igneum-san-flat-lag2 | 30 | alt | 5.651 | 0.979 | 1.069 | 1.058 | 0.069 | 0.069 | 0.936 | 0.117 | 10.9 | 0.000 | 1 |
| igneum-san-flat-lag2 | 50 | future | 132.0 | 0.979 | 1.061 | 1.031 | 0.061 | 0.061 | 0.944 | 0.431 | 13.4 | 0.000 | 1 |
| igneum-san-flat-lag2 | 50 | past | -285.2 | 0.979 | 0.823 | 0.528 | -0.177 | -0.177 | 1.234 | 13.0 | 78.7 | 0.000 | 1 |
| igneum-san-flat-lag2 | 50 | alt | 8.680 | 0.979 | 1.094 | 1.079 | 0.094 | 0.094 | 0.918 | 0.161 | 10.5 | 0.000 | 1 |
| igneum-san-lwma-lag1 | 30 | future | 132.0 | 0.978 | 1.098 | 1.091 | 0.098 | 0.098 | 0.911 | 0.353 | 9.727 | 0.000 | 1 |
| igneum-san-lwma-lag1 | 30 | past | -162.2 | 0.978 | 1.114 | 1.139 | 0.114 | 0.114 | 0.904 | 0.290 | 12.2 | 0.000 | 1 |
| igneum-san-lwma-lag1 | 30 | alt | 5.272 | 0.978 | 1.065 | 1.053 | 0.065 | 0.065 | 0.942 | 0.132 | 10.7 | 0.000 | 1 |
| igneum-san-lwma-lag1 | 50 | future | 132.0 | 0.978 | 1.233 | 1.258 | 0.233 | 0.233 | 0.823 | 0.709 | 10.2 | 0.000 | 1 |
| igneum-san-lwma-lag1 | 50 | past | -270.0 | 0.978 | 0.934 | 0.609 | -0.066 | -0.066 | 1.076 | 1396.5 | 102.2 | 0.000 | 1 |
| igneum-san-lwma-lag1 | 50 | alt | 8.250 | 0.978 | 1.089 | 1.081 | 0.089 | 0.089 | 0.921 | 0.144 | 11.4 | 0.000 | 1 |
| igneum-san-lwma-lag2 | 30 | future | 132.0 | 0.978 | 1.096 | 1.095 | 0.096 | 0.096 | 0.912 | 0.349 | 9.663 | 0.000 | 1 |
| igneum-san-lwma-lag2 | 30 | past | -162.3 | 0.978 | 1.113 | 1.136 | 0.113 | 0.113 | 0.905 | 0.288 | 13.4 | 0.000 | 1 |
| igneum-san-lwma-lag2 | 30 | alt | 5.288 | 0.978 | 1.064 | 1.055 | 0.064 | 0.064 | 0.943 | 0.131 | 10.7 | 0.000 | 1 |
| igneum-san-lwma-lag2 | 50 | future | 132.0 | 0.978 | 1.229 | 1.257 | 0.229 | 0.229 | 0.826 | 0.699 | 10.8 | 0.000 | 1 |
| igneum-san-lwma-lag2 | 50 | past | -270.4 | 0.978 | 0.931 | 0.600 | -0.069 | -0.069 | 1.085 | 1068.9 | 97.6 | 0.000 | 1 |
| igneum-san-lwma-lag2 | 50 | alt | 8.606 | 0.978 | 1.097 | 1.111 | 0.097 | 0.097 | 0.916 | 0.155 | 9.717 | 0.000 | 1 |
| igneum-san-flat-lag1-cap10 | 30 | future | 132.0 | 0.979 | 1.052 | 1.024 | 0.052 | 0.052 | 0.950 | 0.113 | 9.696 | 0.000 | 1 |
| igneum-san-flat-lag1-cap10 | 30 | past | -175.7 | 0.979 | 1.031 | 0.999 | 0.031 | 0.031 | 0.974 | 0.185 | 13.3 | 0.000 | 1 |
| igneum-san-flat-lag1-cap10 | 30 | alt | 5.566 | 0.979 | 1.068 | 1.058 | 0.068 | 0.068 | 0.938 | 0.119 | 10.7 | 0.000 | 1 |
| igneum-san-flat-lag1-cap10 | 50 | future | 132.0 | 0.979 | 0.938 | 0.918 | -0.062 | -0.062 | 1.071 | 0.404 | 22.1 | 0.000 | 1 |
| igneum-san-flat-lag1-cap10 | 50 | past | -853.2 | 0.979 | 0.226 | 0.019 | -0.774 | -0.774 | 4.585 | 40314.5 | 268.5 | 0.000 | 1 |
| igneum-san-flat-lag1-cap10 | 50 | alt | 7.507 | 0.979 | 1.077 | 1.071 | 0.077 | 0.077 | 0.932 | 0.135 | 11.0 | 0.000 | 1 |
## First run, realised-count estimator (superseded; shows the block-count noise on the epoch flooders)
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum', 'kaspa']
### 1. Pool hopping: hopper's blocks per hash against the always-on base (adv = ratio - 1), 24 h
| rule | x | dwell | adv | adv_worst | hop_on_frac | switches | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 10 | 0 | 0.011 | 0.013 | 0.432 | 301.0 | 0.072 | 12.7 | 0.998 | 3 |
| igneum | 10 | 60 | 0.010 | 0.011 | 0.437 | 227.0 | 0.072 | 12.6 | 0.998 | 3 |
| igneum | 30 | 0 | 0.006 | 0.014 | 0.216 | 492.0 | 0.135 | 12.8 | 0.994 | 3 |
| igneum | 30 | 60 | -0.002 | -0.008 | 0.283 | 394.0 | 0.140 | 13.9 | 0.992 | 3 |
| igneum | 50 | 0 | 0.006 | 0.015 | 0.149 | 616.7 | 0.197 | 13.8 | 0.992 | 3 |
| igneum | 50 | 60 | -0.015 | -0.022 | 0.283 | 544.7 | 0.211 | 13.8 | 0.984 | 3 |
| igneum | 100 | 0 | 0.012 | 0.024 | 0.085 | 741.0 | 0.339 | 13.3 | 0.990 | 3 |
| igneum | 100 | 60 | -0.038 | -0.050 | 0.378 | 818.0 | 0.349 | 16.9 | 0.968 | 3 |
| kaspa | 10 | 0 | 0.005 | 0.009 | 0.367 | 63.7 | 0.054 | 11.8 | 1.000 | 3 |
| kaspa | 10 | 60 | 0.005 | 0.009 | 0.367 | 63.7 | 0.054 | 11.8 | 1.000 | 3 |
| kaspa | 30 | 0 | 0.006 | 0.008 | 0.181 | 88.0 | 0.124 | 12.3 | 1.001 | 3 |
| kaspa | 30 | 60 | 0.006 | 0.008 | 0.181 | 88.0 | 0.124 | 12.3 | 1.001 | 3 |
| kaspa | 50 | 0 | 0.012 | 0.015 | 0.116 | 112.3 | 0.180 | 12.7 | 1.001 | 3 |
| kaspa | 50 | 60 | 0.014 | 0.019 | 0.115 | 111.3 | 0.179 | 12.6 | 1.001 | 3 |
| kaspa | 100 | 0 | 0.010 | 0.029 | 0.061 | 122.7 | 0.304 | 12.5 | 1.001 | 3 |
| kaspa | 100 | 60 | 0.006 | 0.019 | 0.068 | 132.0 | 0.315 | 12.5 | 1.001 | 3 |
### 2. Pulsed hash rate: 50x for 10 min every hour, blocks per hash of the pulser against steady mining
| rule | pulse_vs_steady | pulse_vs_steady_worst | base_vs_steady | pulse_vs_base | pulse_block_share | pulse_hash_share | peak_blocks_per_min | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum | -0.977 | -0.977 | -0.346 | -0.964 | 0.228 | 0.862 | 182.3 | 100.9 | 0.841 | 3 |
| kaspa | -0.896 | -0.897 | -0.879 | -0.139 | 0.878 | 0.862 | 1741.0 | 102.1 | 0.979 | 3 |
### 3. Timestamp stretching inside the rules: block rate after 1 h of forging (drift = rate - 1)
| rule | share | stamp | forger_offset_s | rate_pre | rate_post | rate_last_hour | drift | drift_worst | D_ratio | std | worst_gap | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 30 | future | 132.0 | 0.994 | 0.656 | 0.658 | -0.344 | -0.350 | 1.549 | 0.136 | 15.6 | 3 |
| igneum | 30 | past | -439.1 | 0.994 | 0.415 | 0.428 | -0.585 | -0.597 | 2.421 | 0.243 | 44.8 | 3 |
| igneum | 30 | alt | -70.3 | 0.994 | 0.514 | 0.513 | -0.486 | -0.545 | 1.966 | 0.381 | 37.0 | 3 |
| igneum | 50 | future | 132.0 | 0.994 | 0.563 | 0.573 | -0.437 | -0.449 | 1.796 | 0.103 | 17.1 | 3 |
| igneum | 50 | past | -2122.9 | 0.994 | 0.116 | 0.119 | -0.884 | -0.925 | 9.886 | 0.186 | 233.8 | 3 |
| igneum | 50 | alt | -289.0 | 0.994 | 0.231 | 0.221 | -0.769 | -0.804 | 4.393 | 0.257 | 83.5 | 3 |
| kaspa | 30 | future | 132.0 | 0.993 | 1.049 | 1.049 | 0.049 | 0.052 | 0.959 | 0.018 | 8.825 | 3 |
| kaspa | 30 | past | -170.2 | 0.993 | 1.069 | 1.073 | 0.069 | 0.072 | 0.941 | 0.021 | 8.675 | 3 |
| kaspa | 30 | alt | 6.993 | 0.993 | 1.090 | 1.092 | 0.090 | 0.092 | 0.923 | 0.023 | 8.463 | 3 |
| kaspa | 50 | future | 132.0 | 0.993 | 1.050 | 1.052 | 0.050 | 0.054 | 0.958 | 0.018 | 8.840 | 3 |
| kaspa | 50 | past | -235.6 | 0.993 | 1.113 | 1.113 | 0.113 | 0.116 | 0.904 | 0.027 | 8.353 | 3 |
| kaspa | 50 | alt | 8.892 | 0.993 | 1.098 | 1.100 | 0.098 | 0.100 | 0.916 | 0.021 | 8.451 | 3 |
### 4. Short-lane oscillation: 25% miner on and off every 120 blocks
| rule | share | period | std_pre | std_post | std_ratio | std_ratio_worst | std_floor | worst_gap_pre | worst_gap_post | blocks_per_s | osc_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 25 | 120 | 0.045 | 0.160 | 3.753 | 4.815 | 0.143 | 8.789 | 11.0 | 0.980 | -0.015 | 3 |
| kaspa | 25 | 120 | 0.010 | 0.147 | 16.4 | 23.5 | 0.143 | 8.906 | 10.3 | 1.001 | 0.012 | 3 |
### 5. Epoch-boundary games: hold dodger (30%, off for blocks 0 to 7), hold flooder (10x, on for blocks 0 to 7), 30% flooder
| rule | kind | gamer_adv | gamer_adv_worst | gamer_on_frac | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|
| igneum | dodge | -0.000 | 0.001 | 0.997 | 0.054 | 9.598 | 1.002 | 3 |
| igneum | flood | 0.136 | 0.276 | 0.000 | 0.470 | 9.986 | 0.995 | 3 |
| igneum | flood30 | 0.131 | 0.272 | 0.001 | 0.054 | 9.811 | 0.997 | 3 |
| kaspa | dodge | -0.000 | -0.000 | 0.997 | 0.026 | 9.360 | 1.001 | 3 |
| kaspa | flood | 0.111 | 0.264 | 0.000 | 0.482 | 9.293 | 1.001 | 3 |
| kaspa | flood30 | 0.110 | 0.263 | 0.002 | 0.030 | 9.278 | 1.001 | 3 |
### 6. Polluted window under adversarial timing: 10x miner joins at block join_k of an epoch and leaves at leave_k (600 = long lane takes over)
| rule | join_k | leave_k | join_first10_s | join_settled_s | leave_first10_s | leave_settled_s | leave_worst_gap_s | leave_below05 | leave_above2x | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum | 0 | 600 | 88.6 | 134.8 | 303.1 | 303.1 | 16.9 | 55.3 | 0.000 | 3 |
| igneum | 480 | 600 | none | none | 291.9 | 291.9 | 15.2 | 50.3 | 0.000 | 3 |
| igneum | 480 | 720 | 76.3 | none | 321.4 | 321.4 | 28.4 | 56.7 | 0.000 | 3 |
| igneum | 0 | 1200 | 88.6 | 134.8 | 312.2 | 334.0 | 24.5 | 56.7 | 0.000 | 3 |
| kaspa | 0 | 600 | none | none | 2910.0 | 2910.0 | 9.954 | 0.000 | 0.000 | 3 |
| kaspa | 480 | 600 | none | none | 0.000 | 0.000 | 8.600 | 0.000 | 0.000 | 3 |
| kaspa | 480 | 720 | none | none | 135.3 | 135.3 | 8.838 | 0.000 | 0.000 | 3 |
| kaspa | 0 | 1200 | none | none | 3539.6 | 3539.6 | 13.1 | 0.000 | 0.000 | 3 |
## Scenario 7, flood test output (cargo test -p kaspa-consensus --lib igneum_flood -- --nocapture, diff-attacks branch)
```
target below 2^64 at block 4142 (epoch start 3600), bits 0x900fe5b
thread 'processes::difficulty::tests::igneum_flood_at_85_blocks_per_second_drives_the_target_below_block_work_range' (36166563) panicked at consensus/src/processes/difficulty.rs:431:20:
Work should not exceed 2**192: TryFromIntError
test processes::difficulty::tests::igneum_flood_at_85_blocks_per_second_drives_the_target_below_block_work_range - should panic ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 81 filtered out; finished in 0.01s
```
## Ease clamp against the hopper (igneum-ease6 and igneum-ease3: the spec rule with a 6% or 3% ease clamp), seed 7, 24 h
# Difficulty attacks, seeds [7], rules ['igneum-ease6', 'igneum-ease3']
### 1. Pool hopping: hopper's blocks per hash against the always-on base (adv = ratio - 1), 24 h
| rule | x | dwell | adv | adv_worst | hop_on_frac | switches | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum-ease6 | 10 | 0 | 0.015 | 0.015 | 0.517 | 330.0 | 0.073 | 12.7 | 1.000 | 1 |
| igneum-ease6 | 10 | 60 | 0.014 | 0.014 | 0.505 | 240.0 | 0.073 | 12.7 | 1.000 | 1 |
| igneum-ease6 | 30 | 0 | 0.010 | 0.010 | 0.271 | 565.0 | 0.143 | 11.7 | 0.995 | 1 |
| igneum-ease6 | 30 | 60 | 0.002 | 0.002 | 0.336 | 445.0 | 0.144 | 13.7 | 0.993 | 1 |
| igneum-ease6 | 50 | 0 | 0.009 | 0.009 | 0.185 | 718.0 | 0.209 | 13.6 | 0.992 | 1 |
| igneum-ease6 | 50 | 60 | -0.011 | -0.011 | 0.309 | 576.0 | 0.214 | 12.2 | 0.986 | 1 |
| igneum-ease6 | 100 | 0 | 0.006 | 0.006 | 0.107 | 861.0 | 0.362 | 13.9 | 0.990 | 1 |
| igneum-ease6 | 100 | 60 | -0.032 | -0.032 | 0.396 | 841.0 | 0.346 | 17.0 | 0.970 | 1 |
| igneum-ease3 | 10 | 0 | 0.015 | 0.015 | 0.529 | 308.0 | 0.072 | 11.7 | 0.999 | 1 |
| igneum-ease3 | 10 | 60 | 0.015 | 0.015 | 0.515 | 238.0 | 0.073 | 12.8 | 0.999 | 1 |
| igneum-ease3 | 30 | 0 | 0.009 | 0.009 | 0.284 | 566.0 | 0.142 | 11.7 | 0.994 | 1 |
| igneum-ease3 | 30 | 60 | 0.002 | 0.002 | 0.342 | 446.0 | 0.143 | 13.7 | 0.993 | 1 |
| igneum-ease3 | 50 | 0 | 0.008 | 0.008 | 0.190 | 698.0 | 0.208 | 12.7 | 0.991 | 1 |
| igneum-ease3 | 50 | 60 | -0.012 | -0.012 | 0.321 | 588.0 | 0.213 | 12.1 | 0.984 | 1 |
| igneum-ease3 | 100 | 0 | 0.005 | 0.005 | 0.115 | 896.0 | 0.366 | 11.9 | 0.988 | 1 |
| igneum-ease3 | 100 | 60 | -0.027 | -0.027 | 0.413 | 859.0 | 0.343 | 16.7 | 0.970 | 1 |
---
## Rule v2 (4 October 2026, `igneum:ref_window=600+long_min=100000` = `igneum-v2`): full suite under the tight timestamp rules and the base profiles, seeds 7 to 9. The v1 rows for comparison are the `igneum-san` rows of the sections above (the 4 October rule); `docs/analysis/difficulty-2026-10-04-oscillation.md` section 6 sets them side by side.
# Difficulty attacks, seeds [7, 8, 9], rules ['igneum:ref_window=600+long_min=100000']
### 1. Pool hopping: hopper's blocks per hash against the always-on base (adv = ratio - 1), 24 h
| rule | x | dwell | adv | adv_worst | hop_on_frac | switches | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | 10 | 0 | 0.025 | 0.025 | 0.495 | 529.0 | 0.081 | 12.4 | 0.998 | 3 |
| igneum:ref_window=600+long_min=100000 | 10 | 60 | 0.023 | 0.023 | 0.495 | 399.0 | 0.081 | 12.8 | 0.998 | 3 |
| igneum:ref_window=600+long_min=100000 | 30 | 0 | 0.016 | 0.016 | 0.318 | 923.3 | 0.149 | 12.9 | 0.997 | 3 |
| igneum:ref_window=600+long_min=100000 | 30 | 60 | 0.008 | 0.010 | 0.386 | 631.0 | 0.150 | 14.0 | 0.995 | 3 |
| igneum:ref_window=600+long_min=100000 | 50 | 0 | 0.012 | 0.013 | 0.222 | 1124.3 | 0.218 | 14.2 | 0.996 | 3 |
| igneum:ref_window=600+long_min=100000 | 50 | 60 | -0.003 | -0.008 | 0.377 | 778.3 | 0.219 | 15.3 | 0.989 | 3 |
| igneum:ref_window=600+long_min=100000 | 100 | 0 | 0.010 | 0.011 | 0.122 | 1342.7 | 0.377 | 14.0 | 0.996 | 3 |
| igneum:ref_window=600+long_min=100000 | 100 | 60 | -0.015 | -0.018 | 0.424 | 959.3 | 0.351 | 17.0 | 0.973 | 3 |
### 2. Pulsed hash rate: 50x for 10 min, every hour (period 3600) and once (period 1000000); weight_per_hash = block share / hash share
| rule | period_s | pulse_vs_base | pulse_vs_base_worst | weight_per_hash | weight_per_hash_worst | pulse_vs_steady | base_vs_steady | pulse_block_share | pulse_hash_share | peak_blocks_per_min | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | 3600 | -0.963 | -0.964 | 0.262 | 0.266 | -0.977 | -0.358 | 0.234 | 0.893 | 185.0 | 198.7 | 0.834 | 3 |
| igneum:ref_window=600+long_min=100000 | 1000000 | -0.972 | -0.973 | 0.130 | 0.132 | -0.977 | -0.182 | 0.105 | 0.806 | 172.0 | 97.8 | 0.912 | 3 |
### 3. Timestamp stretching inside the rules: block rate after 1 h of forging (drift = rate - 1), 6 h runs
| rule | ts_rules | share | stamp | forger_offset_s | rate_pre | rate_post | rate_last_hour | drift | drift_worst | D_ratio | std | worst_gap | forger_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | tight | 30 | future | 10.0 | 0.994 | 1.002 | 1.000 | 0.002 | 0.005 | 1.004 | 0.066 | 9.666 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | tight | 30 | past | -15.8 | 0.994 | 0.998 | 0.993 | -0.002 | -0.009 | 1.008 | 0.079 | 9.925 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | tight | 30 | alt | 0.997 | 0.994 | 1.001 | 0.998 | 0.001 | 0.006 | 1.005 | 0.063 | 9.623 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | tight | 50 | future | 10.0 | 0.994 | 1.004 | 0.996 | 0.004 | 0.009 | 1.002 | 0.071 | 9.795 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | tight | 50 | past | -21.9 | 0.994 | 0.992 | 0.984 | -0.008 | -0.015 | 1.013 | 0.173 | 10.3 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | tight | 50 | alt | 1.999 | 0.994 | 1.005 | 1.003 | 0.005 | 0.009 | 1.001 | 0.069 | 9.515 | 0.000 | 3 |
### 4. Short-lane oscillation: 25% miner on and off every 120 blocks (std_floor = the hash square wave at a fixed D)
| rule | share | period | std_pre | std_post | std_ratio | std_ratio_worst | std_floor | worst_gap_pre | worst_gap_post | blocks_per_s | osc_adv | seeds |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | 25 | 120 | 0.049 | 0.159 | 3.293 | 3.707 | 0.143 | 8.725 | 11.0 | 0.983 | -0.012 | 3 |
### 5. Epoch-boundary games: hold dodger (30%, off for blocks 0 to 7), hold flooder (10x, on for blocks 0 to 7), 30% flooder
| rule | kind | gamer_adv | gamer_adv_worst | gamer_on_frac | std | worst_gap | blocks_per_s | seeds |
|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | dodge | 0.000 | 0.000 | 0.997 | 0.062 | 9.602 | 1.000 | 3 |
| igneum:ref_window=600+long_min=100000 | flood | 0.004 | -0.019 | 0.000 | 0.472 | 9.982 | 0.994 | 3 |
| igneum:ref_window=600+long_min=100000 | flood30 | 0.000 | -0.022 | 0.001 | 0.062 | 9.812 | 0.996 | 3 |
### 6. Polluted window under adversarial timing: 10x miner joins at block join_k of an epoch and leaves at leave_k (600 = long lane takes over)
| rule | join_k | leave_k | join_first10_s | join_settled_s | leave_first10_s | leave_settled_s | leave_worst_gap_s | leave_below05 | leave_above2x | seeds |
|---|---|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | 0 | 600 | 89.3 | 135.4 | 296.6 | 296.6 | 16.4 | 55.3 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | 480 | 600 | none | none | 287.6 | 287.6 | 14.8 | 46.3 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | 480 | 720 | 76.3 | 58.3 | 312.3 | 312.3 | 28.5 | 55.0 | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | 0 | 1200 | 89.3 | 135.4 | 307.2 | 331.0 | 24.6 | 55.7 | 0.000 | 3 |
### Base profiles (sim.py metrics) through each rule
| rule | profile | first10_s | settled_s | settled_s_none | worst_gap_s | steady_std | peak_rate | not_recovered | seeds |
|---|---|---|---|---|---|---|---|---|---|
| igneum:ref_window=600+long_min=100000 | up50 | 55.5 | 150.3 | none | 9.596 | 0.053 | none | none | 3 |
| igneum:ref_window=600+long_min=100000 | down50 | 792.3 | 822.0 | none | 76.0 | 0.053 | none | none | 3 |
| igneum:ref_window=600+long_min=100000 | epoch30 | 53.8 | 87.8 | none | 10.6 | 0.049 | none | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | walk10 | none | none | 3 | 10.5 | 0.059 | none | none | 3 |
| igneum:ref_window=600+long_min=100000 | hop10 | 207.4 | 233.2 | none | 42.4 | 0.053 | none | 0.000 | 3 |
| igneum:ref_window=600+long_min=100000 | polluted | 76.3 | 76.3 | none | 10.2 | 0.048 | 12.2 | none | 3 |
| igneum:ref_window=600+long_min=100000 | warmup-hard | 305.8 | 326.5 | none | 34.6 | 0.049 | none | none | 3 |