Skip to content
Difficulty Adjustment
step 1/5

Reading — step 1 of 5

Read

~2 min readProof of Work

Difficulty Adjustment

Bitcoin promises a block every ~10 minutes. But hashrate is wildly non-constant — it has grown by a factor of about 10^14 since 2009 as CPUs gave way to GPUs, then ASICs, then warehouse-scale farms. Without a feedback loop, today's network would mine 2009-difficulty blocks thousands of times per second. The loop is the difficulty retarget:

every 2016 blocks (~2 weeks):
    new_target = old_target * actual_time / expected_time
    clamped to [old_target/4, old_target*4]

expected_time = 2016 blocks * 10 min

Reason through the direction once and you'll never confuse it. The target is a ceiling — a bigger target admits more hashes and makes mining easier. Blocks arriving too fast means actual < expected, ratio < 1, target shrinks, mining gets harder. Blocks too slow: target grows, mining eases. The block rate is the sensor; the target is the actuator.

Why the 4× clamp?

Robustness. A retarget window with a freak timespan — a measurement bug, a timestamp manipulation, a massive hashrate crash — could otherwise swing the target by orders of magnitude in one step and stall the chain (imagine difficulty ×1000 after hashrate leaves: the next 2016 blocks, and thus the next retarget, might take years). Clamping to 4× per window bounds the damage and lets recovery happen over a few windows. Trivia for the protocol-lawyers: Bitcoin's actual implementation measures the timespan across 2015 intervals instead of 2016 — an off-by-one bug that's now consensus law, because fixing it would hard-fork the network. Other designs retarget every block (Ethereum pre-merge did; most modern chains do some form of continuous adjustment), trading smoothness of the 2016-block average for responsiveness. And the numbers are staggering: the original 2009 target was about 2^224; today's is near 2^176 — the ceiling has dropped by ~14 orders of magnitude of decimal difficulty.

The implementation idiom

python

Compute first, clamp second, floor to an integer. Both clamps, both directions.

Your exercise

Input <old_target>|<actual_seconds>|<expected_seconds>; print the new target as an integer. The graded mistakes are exactly the clamps: for 100|9999999|600 the unclamped formula says 1,666,666 but the answer is 400 (4× ceiling); for 100|1|600 the unclamped floor says 0 — a target of zero would make mining impossible — but the answer is 25 (the 100/4 floor). Code with no clamp fails the first; code that clamps only the easing direction fails the second. Also keep it integer: 200|151|600 is 50.33 by real division and must print 50.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…