# 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). ## Context Bug-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 s before 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 against the actual retarget code and found it to be a no-op that also schedules a hard fork. ## Analysis The 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`, so consecutive windows do not share an endpoint. A majority miner can push the last block 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 without bound 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 from block `H-61` to `H-1`, and period *k+1* from `H-1` to `H+59`. Consecutive windows share 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. ## Decision 1. **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.