Summary
On 2026-05-04, the INTcoin mainnet chain stalled at block height 8614 for over 12 hours before block 8615 was mined. Root cause was a difficulty-adjustment edge case in the LWMA algorithm. This post documents what happened, why, and the fix that ships in v1.0.6.
Timeline (UTC)
- 2026-05-03 05:57 — A community miner produced 23 blocks in ~2 minutes (h=8585 through h=8607). Network hashrate at the moment of the burst peaked around 300 KH/s.
- 2026-05-03 05:58 → 06:00 — Burst miner went offline. Residual community hashrate was on the order of 1–3 KH/s.
- 2026-05-03 06:04 → 17:10 — Sparse blocks (h=8610 through h=8613), each landing hours apart.
- 2026-05-04 06:38 — Block 8614 landed. Difficulty for the next block recalculated higher despite the very long preceding solvetime.
- 2026-05-04 06:38 → 18:57 — 12h 19m of zero blocks. Fleet daemons (UK / EU / US) all reported the same canonical tip; no node was forked. The chain itself had paused.
- 2026-05-04 17:38 — Cause confirmed in
src/pow/difficulty.cpp. v1.0.6 hard-fork plan agreed. - 2026-05-04 18:57 — Block 8615 landed. Difficulty rose another 8% rather than dropping.
Root cause
INTcoin’s LWMA difficulty-adjustment carried an asymmetric solvetime clamp:
if (solvetime < 0) solvetime = 0; // bug: no lower bound on small/zero values
if (solvetime > 6 * T) solvetime = 6 * T; // correct upper bound (timestamp-attack defence)
When 23 burst-mined blocks each contributed a near-zero solvetime to the LWMA-weighted average, the average was pinned below target. The algorithm interpreted this as “blocks are arriving too fast — raise difficulty” — even though the chain was already starved of hashrate. Once the burst miner left, the residual community hashrate could not satisfy the elevated target, and every subsequent long-solvetime block (h=8611, h=8612, h=8613, h=8614 → 8615) drove difficulty higher rather than relieving it.
The chain was deadlocking by the design of the existing rules. zawy12’s reference LWMA-3 implementation — the standard the algorithm was modelled on — includes a T/4 lower clamp specifically to prevent this failure mode. INTcoin’s implementation was missing it.
Why it took until 8585 to surface
Before 2026-05-03 the chain had operated entirely on community hashrate spread across many small miners. Solvetimes hovered around the 120-second target with the natural variance you’d expect; no individual block contributed a near-zero solvetime to LWMA’s window. The 23-blocks-in-2-minutes burst was the first time the lower-end pathology was exercised at scale.
The feature_lwma_difficulty.py regtest covered slow blocks, fast blocks, the powLimit floor, and pre-window-full inheritance — but nothing that simulated a single miner producing a burst of effectively-zero solvetimes followed by departure. That coverage gap allowed the bug to ship.
The fix — v1.0.6
Four coordinated consensus changes (a hard fork) that handle this exact failure mode plus a few related ones:
- IIP-0117 — Symmetric solvetime clamp (
T/4 ≤ s ≤ 6×T). Direct root-cause fix. - IIP-0118 — LWMA window 60 → 144. Wider averaging dilutes single-event noise (a 23-block burst goes from 38% → 16% of the window).
- IIP-0119 — Per-retarget damping clamp ±30%. Bounds single-evaluation diff swings.
- IIP-0120 — Emergency min-difficulty fallback after a 40-minute stall. Guarantees chain liveness — no future stall can persist past one trigger window.
Each IIP has full Boost regtest coverage in src/test/pow_tests.cpp, including a regression test (lwma_burst_mining_recovery) that reproduces this specific incident. The complete v1.0.5→v1.0.6 diff is documented in docs/user/CHANGELOG.md.
Why v1.0.6 breaks compatibility with v1.0.3 / v1.0.4 / v1.0.5
LWMA target computation is consensus-critical: every node validates block.nBits == GetNextWorkRequired(prevBlock). If two nodes disagree on that calculation, they reject each other’s blocks and the network splits. Rather than rely on signalling-bit activation while the chain was already stalled, v1.0.6 bumps the protocol version (70003 → 70004) so v1.0.5 and earlier peers are refused at handshake before any block is exchanged. Clean network split, no orphan storms.
This is the first INTcoin release that drops backwards compatibility with prior stable versions. Every node operator must upgrade to v1.0.6 to remain on the canonical chain.
What changed about how we test
Going forward, the regtest suite covers the burst-then-stall pattern explicitly. Any future LWMA tuning will be validated against the lwma_burst_mining_recovery and lwma_zero_solvetime_lower_bound cases before merge — the failure mode that produced this incident now causes a CI red rather than reaching production.
Acknowledgements
Thanks to @jooosen and others on Discord who reported the stall in real-time, and to everyone who waited patiently while we walked the LWMA code path block by block to confirm the root cause before pushing changes. v1.0.6 lands in tree now — binaries follow once CI completes.
For the technical detail of each consensus change, see the v1.0.6 entry in CHANGELOG.md and the IIP repo.
— INT-devs