consensus: soft fork on testnet4 that fixes the min difficulty blocks exploit #35081

pull batmanbytes wants to merge 5 commits into bitcoin:master from batmanbytes:testnet4-softfork changing 6 files +218 −1
  1. batmanbytes commented at 9:35 AM on April 15, 2026: none

    Summary

    Invalidate any block whose timestamp is more than 20 minutes than its previous block's timestamp, after block height 151,200 (epoch 75 boundary).

    Motivation

    Testnet4's min-difficulty rule (allowing difficulty-1 blocks after 20 minutes) is being exploited, causing ~85-90% of blocks to be CPU-mined min-difficulty blocks. This results in a race of CPU miners broadcasting blocks at exactly the second that it's acceptable. This race is so intense that CPU miners have figured out sending empty blocks, as they propagate faster than those that contain transactions, resulting in a network where transactions are confirmed at only the remaining ASIC blocks, that have ~1 hour average block times.

    After the fork, min difficulty blocks will no longer be allowed, as blocks that have a timestamp longer than 20 minutes than their previous blocks become invalid.

    Previously, PR #34420 addressed the same issue, but the change was a hard fork. The current soft fork proposal fixes the problem for non-upgraded nodes as long as majority of the hashrate is mining on upgraded clients, and therefore fixes the problem with the least network disruption.

    Changes

    • Add min_difficulty_blocks_fix_height consensus parameter (default 0 = disabled).
    • Set fork height to 151,200 for testnet4 (epoch 75 boundary).
    • In ContextualCheckBlockHeader(), reject any block whose timestamp exceeds the previous block's timestamp by more than 2 * nPowTargetSpacing (1200 seconds on testnet4) once the activation height is reached. Because the min-difficulty rule only kicks in when the inter-block gap is strictly greater than 2 * nPowTargetSpacing, capping the gap at exactly that boundary makes min-difficulty blocks impossible -- without touching the min-difficulty rule itself.
    • Add GetMaximumTime() in node/miner mirroring GetMinimumTime(), and clamp candidate block timestamps (both in BlockAssembler::CreateNewBlock() and UpdateTime()) so that getblocktemplate never returns a curtime that would produce a block rejected by the new rule.
    • Add unit tests covering boundary behavior of GetMaximumTime and clamping behavior of UpdateTime.

    Soft fork properties

    This is a strict tightening of consensus rules:

    • Any block valid under the new rule is also valid under the old rules.
    • Blocks at heights below 151,200 are completely unaffected.
    • Non-upgraded nodes continue to accept blocks mined by upgraded miners (they satisfy the old ruleset). Propagation to non-upgraded nodes happens naturally through normal chain gossip, so no coordinated upgrade is required beyond sufficient hashrate majority adopting the rule by the activation height.

    Test Plan

    • ./build/bin/test_bitcoin --run_test=testnet4_miner_tests -- all boundary and clamping tests pass.
    • Regression: ./build/bin/test_bitcoin --run_test=miner_tests,pow_tests,validation_tests,validation_block_tests -- no regressions.
    • Manual: pre-activation behavior on live testnet4 matches expectations (getblocktemplate returns a curtime below the prospective cap).

    Discussion

    bitcoin-dev mailing list thread [#1](/bitcoin-bitcoin/1/) bitcoin-dev mailing list thread [#2](/bitcoin-bitcoin/2/) Bitcointalk thread Supersedes hard fork proposal #34420

  2. consensus: fix min-difficulty block exploit on testnet4 c440feadf6
  3. miner: clamp block template timestamp to consensus maximum 234f417491
  4. test: add unit tests for testnet4 softfork 78689e141f
  5. Small comment correction 69a5050f74
  6. DrahtBot added the label Consensus on Apr 15, 2026
  7. DrahtBot commented at 9:35 AM on April 15, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33421 (node: add BlockTemplateCache by ismaelsadeeq)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • difficulty- adjustment -> difficulty-adjustment [The hyphenated compound word is broken with an extra space after difficulty-, which harms readability and can be momentarily confusing.]

    <sup>2026-04-16 13:27:19</sup>

  8. fjahr commented at 9:52 AM on April 15, 2026: contributor

    This makes the problem of a hashrate drop-off more severe because no matter how long a block takes to mine it can not take more than 20min per the timestamp after this. So it would take longer to get the chain unstuck and back to a normal state. This downside should be discussed in the PR description.

  9. batmanbytes commented at 9:55 AM on April 15, 2026: none

    This makes the problem of a hashrate drop-off more severe because no matter how long a block takes to mine it can not take more than 20min per the timestamp after this. So it would take longer to get the chain unstuck and back to a normal state. This downside should be discussed in the PR description.

    Correct. The result is the mismatch between real date and timestamp date shown in this post: https://bitcointalk.org/index.php?topic=5569103.msg66590279#msg66590279. For a test network, and for only ~5 months, this is really a non-issue, in my opinion.

  10. fjahr commented at 10:02 AM on April 15, 2026: contributor

    I think you misunderstood my post or what I mean with "hashrate drop-off". I meant the concern that someone points some considerable hashpower at the network to drive up the difficulty and then leaves. The network would have a much harder time to recover from that. But a table of how long it would take to get back to 10min block times from the current difficulty, like in the post, would also be good to add.

  11. batmanbytes commented at 10:18 AM on April 15, 2026: none

    I meant the concern that someone points some considerable hashpower at the network to drive up the difficulty and then leaves.

    This is only a problem when a miner increases the hashrate by more than 100% (which increases difficulty by 2x) and then leaves. For up to 100%, difficulty can adjust normally. For beyond 100%, it will adjust by -50% in the next epoch. There is already a limit on how low difficulty can adjust downwards from consensus rules (it is -75%).

    And also, as I've explained in here, there has never been a time, after block ~60k (when metrics start being meaningful), when a miner sent more than 100% of the hashrate and left.

  12. maflcko commented at 11:55 AM on April 15, 2026: member

    What is the current status of testnet4? Is there major testing happening on it, compared to signet or testnet3? Are the block storms useful for testing re-orgs, or are they disruptive?

    Depending on the answers to the above questions, there are different options:

    Also, if there is limited value in the testnet4 history, I am not sure if an additional consensus deployment on top of it is worth it. It seems fine to hard-fork testnet4 from genesis, or call it testnet5, but no strong opinion.

    Also, there has been no further reply on the mailing list in the thread: https://gnusha.org/pi/bitcoindev/9FAA7EEC-BD22-491E-B21B-732AEA15F556@sprovoost.nl/T/#u So it is a bit unclear how acceptable it is to soft/hard fork a testnet or create testnet5 ...

  13. batmanbytes commented at 12:54 PM on April 15, 2026: none

    What is the current status of testnet4? Is there major testing happening on it, compared to signet or testnet3?

    I think there's a lot of testing happening in testnet4.

    Also, if there is limited value in the testnet4 history, I am not sure if an additional consensus deployment on top of it is worth it. It seems fine to hard-fork testnet4 from genesis, or call it testnet5, but no strong opinion.

    I am against hard-forking testnet4 from genesis, because coins have already been distributed throughout the past two years, and resetting all the faucets, and waiting until coins are distributed again feels tiresome and disruptive for a network that could have not changed at all.

    I like the softfork idea, because it solves the only problem this network has, with the least disruption. So little that old clients don't even have to update, and therefore, it solves the problem even without Bitcoin Core merging it, as long as majority of hashrate points to an upgraded node, which is not a big issue, as the majority of hashrate is owned by known entities such as Foundry and Mara pool.

  14. fjahr commented at 1:10 PM on April 15, 2026: contributor

    Replace the 20-minute rule with a time larger than MAX_FUTURE_BLOCK_TIME, so that it can't be exploited, but still serves as a recovery option. E.g. 6, 12, 24, or 48 hours ...

    I like this idea

  15. Sjors commented at 2:41 PM on April 15, 2026: member

    I think it's better to discuss this on the mailing list.

    You may also find #31117 interesting.

  16. consensus: skip timestamp cap on difficulty-adjustment blocks 6b744183bd

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-16 18:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me