EIP-100 Difficulty adjustment based on block time including uncles (Change difficulty adjustment to target mean block time including uncles)

Final · Consensus & staking · EIP status Final · created 2016-04-28

Changes the proof of work era difficulty adjustment formula so that it keeps the average block production rate steady including uncle blocks, not just main chain blocks. Applied starting from the Byzantium fork.

Why it is needed

When this EIP was written, Ethereum still used proof of work mining, and uncle blocks that were mined but did not make it onto the main chain were still rewarded. However, the difficulty adjustment formula looked only at the time interval between main chain blocks and did not account for uncle blocks at all. As a result, even as uncle blocks became more numerous, difficulty stayed the same, which could destabilize the overall block production rate including uncles and the resulting ETH issuance rate. In particular, there was room to deliberately manipulate the uncle rate to push issuance upward, and the source cites a 'uncle mining' consensus protocol flaw analysis article covering this as a reference. This EIP changes difficulty adjustment to target a block production rate that includes uncles, making the issuance rate predictable.

What changes

Today

After EIP-100

Who is affected

In depth

The existing difficulty adjustment formula

The existing formula computes the adjustment factor as adj_factor = max(1 - ((timestamp - parent.timestamp) // 10), -99). It divides the timestamp gap from the parent block into 10 second units, raising difficulty if the block came out quickly and lowering it if it came out slowly, but never dropping by more than -99 at once. The child block's difficulty is child_diff = int(max(parent.difficulty + (parent.difficulty // BLOCK_DIFF_FACTOR) * adj_factor, min(parent.difficulty, MIN_DIFF))), which adds the adjustment factor scaled by one BLOCK_DIFF_FACTORth of the parent's difficulty, while never going below MIN_DIFF. This formula looks only at the main chain block interval and does not account for uncle blocks.

New formula: accounting for uncles and changing the denominator

For block.number >= BYZANTIUM_FORK_BLKNUM, the first line changes to adj_factor = max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99). Two things change. First, if the parent block has even one uncle, the baseline value rises from 1 to 2, pushing difficulty up further. Second, the denominator dividing the time interval shrinks from 10 to 9. The floor of -99 and the difficulty calculation below it stay the same.

Why an approximate formula was used instead of an exact one

The source also presents an exact formula that accounts for the precise number of uncles: adj_factor = max(1 + len(parent.uncles) - ((timestamp - parent.timestamp) // 9), -99). The source explains that this formula is mathematically equivalent, within about an error of 3/4194304, to treating a block with k uncles the same as k+1 blocks appearing consecutively at the same timestamp, and is likely the simplest way to achieve the desired effect. However, this formula requires knowing the number of uncles, so it cannot be computed from the block header alone and needs the full block. The adopted approximate formula only checks whether uncles exist, so it can be computed from the header alone, since comparing the header's uncle hash against the empty hash reveals whether uncles are present.

Why the denominator was changed from 10 to 9

Changing the denominator that divides the time interval from 10 to 9 keeps block time roughly similar to what it was before. This denominator adjustment offsets the change caused by factoring uncles into difficulty. The source calculates that, based on the 7% uncle rate at the time of writing, block time would otherwise have decreased by about 3%.

Effect on preventing issuance rate manipulation

The new formula makes difficulty adjustment keep the block production rate, including uncles, steady. As a result, the issuance rate becomes predictable at a high level of confidence, and it is no longer possible to push issuance upward by manipulating the uncle rate. The source references cite the EIP 100 discussion thread along with a bitslog article dated 2016-04-28 that analyzes uncle based mining strategies as a flaw in Ethereum's consensus protocol.

Timing of application and current status

This EIP was written by Vitalik Buterin on 2016-04-28, and its status is Final. Per the specification's condition block.number >= BYZANTIUM_FORK_BLKNUM, the new formula applies starting from the Byzantium hard fork block. No separate core developer call decision record for this change is included in this material.

Original EIP · ← EIPs