@zawy Imagine the proposed rule, that the first block in a period (i.e., one where n = 0 \mod 2016) must have a timestamp no more than 600s before its immediate predecessor (the last block of the previous period).
Call this constant G = 600 (grace period). Also introduce P = 2016 \cdot 600 (the period, 2 weeks).
For simplicity, let’s replace the “timestamp must be strictly larger than MTP” rule with a “timestamp must not be below MTP” rule (i.e., we allow timestamp=MTP). This doesn’t materially affect the attack, but means we don’t need to increment by 1s every 6 blocks.
The following sequence of timestamps for periods is valid, starting at time 0:
- Period 0: [0, 0, 0, …, 0, 0, P].
- Period 1: [P-G, P-G, …, P-G, 2P-G].
- Period 2: [2P-2G, …, 3P-2G].
- Period 3: [3P-3G, …, 4P-3G],
- …
- Period k: [kP-kG, …, (1+k)P-kG].
Within each period, the difference between the first and last block timestamp is exactly P, so the difficulty will not adjust. However, the net timestamp increase per period is only P-G, i.e., 10 minutes less than 2 weeks.
So this allows attacker to permanently keep the block rate higher than intended, without incurring a difficulty increase cost.
The reason for the 600s grace period is that is compensates the effect of the off-by-one in the difficulty calculation (it only looks at how long 2015 blocks take, not 2016), which would otherwise result in (under constant hashrate) periods of 2 weeks plus 10 minutes. So with the proposed rule, a timewarp attacker can not cause a steady constant-difficulty block production rate of more than 2016 per two weeks.
There is another effect due to asymmetry of the Erlang distribution that results in another 10 minutes lengthening under constant hashrate. I forget why this isn’t incorporated for compensation in the proposed GCC rule.
EDIT: ah, it’s explained in footnote [1] in bips/bip-XXXX.mediawiki at 7f9670b643b7c943a0cc6d2197d3eabe661050c2 · TheBlueMatt/bips · GitHub. The attacker can ignore the first effect but not the second.