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
- Difficulty adjustment is based only on the time interval between main chain blocks.
- Even as uncle blocks increase, difficulty stays the same, so the overall block production rate can rise.
- There is room to manipulate the uncle rate to push ETH issuance upward.
After EIP-100
- If the parent block has an uncle, difficulty is adjusted further upward.
- The average block production rate including uncles now targets a steady level.
- The issuance rate becomes predictable and can no longer be raised by manipulating the uncle rate.
- Changing the denominator from 10 to 9 keeps block time itself roughly the same as before.
Who is affected
- Miners: The strategy of manipulating the uncle rate to increase issuance is blocked. Difficulty rises more after a block that has an uncle.
- Client teams: Starting from the Byzantium fork block, the first line of the difficulty calculation must be implemented with the new formula.
- Users and ETH holders: Keeping the block production rate steady including uncles makes the ETH issuance rate easier to predict.
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.