git / moonbite-network / docs/ADR-012-no-timewarp-rule-min-chainwork.md · raw

# ADR-012 — No timewarp rule; pin nMinimumChainWork, assumevalid and checkpoints- **Status:** Accepted- **Date:** 2026-10-09- **Related:** ADR-010 (2-minute blocks, 60-block retarget), bug-bounty 2026-10-09  findings #4 (timewarp) and #6 (no minimum chain work), infra audit 2026-10-09 (C1, M1).## ContextBug-bounty finding #4 proposed a Bitcoin "consensus-cleanup" style timewarp rule:the first block of each difficulty period may not be timestamped more than 600 sbefore the last block of the previous period, activating at mainnet height 20000.A draft was written into the core tree. The infra audit (C1) reviewed it againstthe actual retarget code and found it to be a no-op that also schedules a hard fork.## AnalysisThe classic Bitcoin timewarp exists because Bitcoin's retarget window is**off by one**: it measures the time between block `H-2016` and block `H-1`, soconsecutive windows do not share an endpoint. A majority miner can push the lastblock of a period far into the future and start the next period in the past;the gap between periods is never measured, so the error accumulates withoutbound and difficulty collapses.MoonBite inherits Litecoin's fix (`src/pow.cpp`, "Code courtesy of Art Forz"):after the first retarget the window goes back the **full period** —`DifficultyAdjustmentInterval()` = 60 blocks — so period *k* is measured fromblock `H-61` to `H-1`, and period *k+1* from `H-1` to `H+59`. Consecutive windowsshare their endpoint. Consequences:- The measured timespans **telescope**: the sum of all window timespans equals  the time between the first and the last sampled block. A timestamp pushed  backward at one boundary shortens the next window by exactly as much as it  lengthened the previous one. There is no un-measured gap to exploit.- Each window's adjustment is clamped to 4× / 0.25× (Bitcoin/Litecoin rule),  and the median-time-past rule plus the 2-hour future-time bound limit how far  any single timestamp can be moved. The residual attacker freedom is a  **transient** easing of at most about 2× in one window, which is paid back in  the next window. The "33× faster collapse" claimed in bounty #4 does not hold  under a full-period window.- The draft rule constrained block `H % 60 == 0`, which is **not** a window  endpoint in this retarget (the endpoints are `H-61` and `H-1` relative to the  block being mined). It therefore removed zero attacker freedom.- Worse, an honest miner with roughly +1 h of clock skew followed by an honest  block with a correct clock would trip the 600 s rule at a period boundary,  splitting upgraded from non-upgraded nodes. Activating it at height 20000  would have been a scheduled hard fork with no security benefit.## Decision1. **No timewarp rule is added.** The `validation.cpp` rule, the   `Consensus::Params::nTimeWarpFixHeight` field and all chainparams settings   for it are dropped. The retarget stays exactly as ADR-010 defines it.2. **Pin a minimum chain work, an assumevalid block and buried checkpoints**   (bounty #6 / audit M1). Previously all three were zero / genesis-only, so a   fresh node would accept and RandomX-verify arbitrarily long floor-difficulty   header chains from any peer. Values were read from a live seed via   read-only RPC on 2026-10-09 (tip 12656):   | Parameter | Value |   |---|---|   | `nMinimumChainWork` | `0x…aa9c1b51` (chainwork at height 12000) |   | `defaultAssumeValid` | `b0b48cbf1cf1666c861c359a1b7abe72f141e794662c6f8dc72261596c58d82e` (height 12500) |   | checkpoints | `{12000, 67b4f7d0af4fa721a4a9f00d09838d4324dd598d930a25c22480b67459d76b14}`, `{12500, b0b48cbf…}` |   Both heights are below the deepest observed live fork point (12579), so no   honest node can be stalled by them. These values are **policy, not   consensus**: a node that lacks them still follows the same chain, it just   does more work to reject junk during initial sync.## Consequences- No hard fork is scheduled. Nodes on the previous release remain fully  compatible with this one.- Every release should re-bump `nMinimumChainWork` / `defaultAssumeValid` /  checkpoints to a recent buried height, as Bitcoin and Litecoin do.- If the retarget is ever changed to a non-overlapping window, this analysis  must be redone and a real timewarp rule (constraining the actual window  endpoints) considered at that time.