# How many blocks per second can sustainably be created using a time warp attack?

In a time warp attack, an attacker can reduce proof of work difficulty to its minimum, which allows even a single piece of modern mining equipment to create large numbers of blocks per second. However, these blocks must follow the median time past consensus rule of each block having a block header time greater than the median of the previous 11 blocks' header times. The blocks also can't use a header time more than two hours in the future if they want to be accepted immediately by full nodes.

The block header time field is an integer representing seconds since the Unix epoch.

Given those constraints, what is the greatest number of blocks per second that an attacker can produce? It's clearly possible for them average one block per second, but I've heard that they may be able to produce more than that.

An attacker would be able to sustain a cadence of 6 blocks per second without increasing the difficulty.

The attacker would start by holding the timestamps back by more than 14 days to erode the difficulty. Once the difficulty was reduced to the minimum, they would be able to increase the timestamp only every sixth block, keeping all blocks’ timestamps at least two weeks in the past except for the timestamp of each last block per difficulty period, which they would timestamp with the present time or up to 2h into the future at least 14 days ahead of the first block in the same period.

While the timestamps eventually settle on a series of the same value repeating six times before incrementing it, there is a quirk in how the timestamps sort to find the median when timestamps are first shifted to increasing minimally.

Assuming we start with 11 blocks spaced at 10 minutes, the subsequent minimum timestamps would be as follows:

Block height Timestamp [s] Timestamps of prior 11 blocks (median bold)
1 0 -
2 600 -
3 1200 -
4 1800 -
5 2400 -
6 3000 -
7 3600 -
8 4200 -
9 4800 -
10 5400 -
11 6000 -
12 3001 0, 600, 1200, 1800, 2400, 3000, 3600, 4200, 4800, 5400, 6000
13 3002 600, 1200, 1800, 2400, 3000, 3600, 4200, 4800, 5400, 6000, 3001
14 3003 1200, 1800, 2400, 3000, 3600, 4200, 4800, 5400, 6000, 3001, 3002
15 3004 1800, 2400, 3000, 3600, 4200, 4800, 5400, 6000, 3001, 3002, 3003
16 3005 2400, 3000, 3600, 4200, 4800, 5400, 6000, 3001, 3002, 3003, 3004
17 3006 3000, 3600, 4200, 4800, 5400, 6000, 3001, 3002, 3003, 3004, 3005
18 3007 3600, 4200, 4800, 5400, 6000, 3001, 3002, 3003, 3004, 3005, 3006
19 3007 4200, 4800, 5400, 6000, 3001, 3002, 3003, 3004, 3005, 3006, 3007
20 3007 4800, 5400, 6000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3007
21 3007 5400, 6000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3007, 3007
22 3007 6000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3007, 3007, 3007
23 3007 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3007, 3007, 3007, 3007
24 3008 3002, 3003, 3004, 3005, 3006, 3007, 3007, 3007, 3007, 3007, 3007
25 3008 3003, 3004, 3005, 3006, 3007, 3007, 3007, 3007, 3007, 3007, 3008
26 3008 3004, 3005, 3006, 3007, 3007, 3007, 3007, 3007, 3007, 3008, 3008
27 3008 3005, 3006, 3007, 3007, 3007, 3007, 3007, 3007, 3008, 3008, 3008
28 3008 3006, 3007, 3007, 3007, 3007, 3007, 3007, 3008, 3008, 3008, 3008
29 3008 3007, 3007, 3007, 3007, 3007, 3007, 3008, 3008, 3008, 3008, 3008
30 3009 3007, 3007, 3007, 3007, 3007, 3008, 3008, 3008, 3008, 3008, 3008

this causes the minimum timestamp to increment one second each block at first before it settles to incrementing only after repeating six times.

6 blocks per second can be sustained.

### Satisfying the MTP rule

The timestamp of each block must be strictly larger than the median of the timetamps of the 11 blocks before it.

This can be satisfied using a pattern consisting of repeating the same timestamp 6 times, then incrementing by one second, and repeat again.

So the series would be:

``````... 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 ...
``````

We can abstract over the actual values. With that, there are just 6 distinct "blocks", based on what the 11 timestamps before it were:

• `T+0 T+0 T+0 T+0 T+0 T+1 T+1 T+1 T+1 T+1 T+1`: MTP=`T+2`
• `T+0 T+0 T+0 T+0 T+1 T+1 T+1 T+1 T+1 T+1 T+2`: MTP=`T+2`
• `T+0 T+0 T+0 T+1 T+1 T+1 T+1 T+1 T+1 T+2 T+2`: MTP=`T+2`
• `T+0 T+0 T+1 T+1 T+1 T+1 T+1 T+1 T+2 T+2 T+2`: MTP=`T+2`
• `T+0 T+1 T+1 T+1 T+1 T+1 T+1 T+2 T+2 T+2 T+2`: MTP=`T+2`
• `T+1 T+1 T+1 T+1 T+1 T+1 T+2 T+2 T+2 T+2 T+2`: MTP=`T+2`

Which in each case continues the pattern.

### Keeping the difficulty low

Using the pattern above naively would result in the difficulty adjustment period quadrupling the difficulty every period (the maximum allowed).

To prevent it from doing so, it is necessary to exploit the timewarp bug.

The winning strategy involves setting the timestamp of every block exactly 2 weeks in the past, except those blocks whose height modulo 2016 equals 2015; those are given the current time (or up to two hours in the future). This will make the adjustment algorithm see every period as having taken 2 weeks, and thus not cause any adjustment.