signet: disk-space-DoS due to low mining difficulty #33266

issue 0xB10C openend this issue on August 28, 2025
  1. 0xB10C commented at 12:38 pm on August 28, 2025: contributor

    Due to low mining difficulty on Signet, an attacker can grind all possible nonces of a block header and create valid1, alternative headers for Signet blocks. Since these have the same chain work as the tip, the newly mined headers can be submitted along with the original block content via an unsolicited block P2P message. Nodes that don’t prune will store these blocks indefinitely.

    When initially reported in April 2025, on average 13208298 work (hash attempts) were required to find a valid nonce on the default Signet. Now, after the difficulty on Signet was increased2, recent signet blocks require 209338421 work on average. This results in 2^32 / 13208298 = ~325 valid headers for each block on average in April and 2^32 / 209338421 = ~20 valid headers for each block at the current Signet difficulty. An attacker can use this to fill up the disk of a Signet node.

    Assuming 144 Signet blocks per day and assuming a size of 500kB3 per block, the signet disk usage increases by about 72 MB per day. An attack could have resulted in a disk-usage increase of 325 * 72 MB = 23.4 GB per day in April. With the current difficulty, it could result in a disk-usage increase of 20 * 72 MB = 1.44 GB per day.

    A modern laptop can grind the full 2^32 nonce space in less than 30 seconds and an attacker only needs to store the nonces to build and publish the alternative blocks. This makes the attack fairly trivial to exploit.

    Credit goes to @stwenhao for initially reporting this in a fork-observer issue. The attack can be detected via getchaintips and e.g. tools like fork-observer. The alternative blocks show up as valid-headers. No reorg happens as the original block remains the active tip (since it was seen first).

    The attack is possible on all networks that require less than 2^32 work to find blocks. Pruned nodes are not affected as the alternative blocks are removed at some point. I’m opening this issue is to document this somewhere visible. I don’t think there’s action required for the default Signet at this point since the difficulty has already been increased and the attack is less effective there now. If this becomes a problem again, the best mitigation is probably to further increase the difficulty. Other public signets (e.g. Mutinynet) might want to consider increasing the mining difficulty too.


    1. Signet blocks commit to the header version, prevhash, merkleroot, and timestamp. These can’t be changed. Only the nonce can be changed to produce valid, alternative headers. ↩︎

    2. The Signet difficulty was increased at the end of April 2025 in response to a private report. ↩︎

    3. filling Signet blocks with transactions is possible for free, but blocks seem to be limited to 1 MWU. Consistently making 500 kB blocks seems to be possible for an attacker ↩︎

  2. bitcoin deleted a comment on Aug 29, 2025
  3. jsarenik commented at 12:31 pm on August 29, 2025: none

    Would such blocks mined by anyone even be considered valid on signet since they would not contain any expected valid signature?

    On signet there’s an “Additional consensus requirement that the coinbase witness commitment contains an extended signet commitment, which is a script satisfying the block script (usually a k-of-n multisig)” (see bitcoin.it documentation on Signet Differences). Maybe the in-repo documentation is not clear?

  4. 0xB10C commented at 5:42 pm on August 29, 2025: contributor

    Would such blocks mined by anyone even be considered valid on signet since they would not contain any expected valid signature?

    Yes. Just the nonce in the block header changes. The signet commitment commits to the header version, prevhash, merkleroot, and timestamp. It does not commit (and can not commit) to the nonce. The underlying block does not change. The commitment remains valid.

  5. stwenhao commented at 8:51 pm on August 30, 2025: none

    It does not commit (and can not commit) to the nonce.

    I agree, that it does not commit to the nonce. But if that would be needed, then it could. An example of a situation, where things are signed, but where nonce is included in signed commitment, is what I deployed as a Proof of Work puzzle: https://bitcointalk.org/index.php?topic=5551080.0

    Or, a similar case is recently deployed Optional Hourglass: https://bitcointalk.org/index.php?topic=5557305.0

    In that cases, the signature can sign everything (for example, nSequence and nLockTime is signed, and both can be used as nonces during mining). And also, signatures can sign less things, by using different sighashes, for example here: https://mempool.space/tx/8349df0753e80cce322322f1b76789e1d0fd6693aed2f4de4e49576423081ae7

    So, I can imagine a perfectly valid Signet challenge, where the size of the signature will be restricted somehow, where it would use different sighashes, than SIGHASH_ALL, or where miners would grind DER signatures, instead of grinding regular 80-byte block headers.

    To sum up: the current design of Signet allows attacking, by changing nonces into different values. But that attack can be trivially stopped, just by making sure, that for a given signed header, there is only one nonce, meeting a given difficulty (which means always checking all 2^32 nonces for each submitted header).

    But, future signets can use a different model, where they could entirely avoid such problems, and work with much smaller difficulty. Imagine taking this signet challenge:

    01 <pubkeyAlice> <pubkeyBob> 2 OP_CHECKMULTISIG
    

    And turning it into this instead:

    0OP_SIZE 61 70 OP_WITHIN OP_VERIFY
    1OP_CODESEPARATOR
    21 <pubkeyAlice> <pubkeyBob> 2 OP_CHECKMULTISIG
    

    Of course, because the Script from signet challenge can change the signed transaction ID, this is incompatible with currently deployed network. However, I can imagine a soft-fork on top of signet, where signatures would be required to be smaller, than they are, and where Proof of Work will be counted, by checking the signature, rather than by checking the hash in the block header. And then, block headers could have even regtest difficulty, if consensus rules would still require grinding something else (that could commit to the block header nonce, and difficulty as well).

    Edit: Also, there are many possible trivial fixes. For example, if each nonce will be restricted by consensus rules to be less than 0x00010000, then it could work, and it would be trivial, to check all 2^16 values, instead of 2^32.

  6. jsarenik commented at 4:44 am on August 31, 2025: none

    What about a safety one-liner fix which would not allow new block to have the same blockheader (except nonce) than an already mined block? Such a local-node “soft-fork” would be possible even without telling anyone network-wise.

    An attack block could come only after a new unique mined&signed block header was announced.

  7. stwenhao commented at 5:01 am on August 31, 2025: none

    What about a safety one-liner fix which would not allow new block to have the same blockheader (except nonce) than an already mined block?

    As long as you know, which block was propagated first, then you can do that. But note that signet block producers can decide to build things on top of any block, including something, which was grinded by some attacker. If you see two or more blocks with different nonces, at the same height N, then you don’t know, what block number N+1 will sign (and also, it can sign all versions, and leave it up to the miners).

    Such a local-node “soft-fork” would be possible even without telling anyone network-wise.

    Yes, but if your node joined the network recently, then you don’t know, if the block you heard from someone is the earliest one, that was broadcasted. You only know that, if something was created on top of it. Which means, that there is always a risk to see a single block being reorged, if you pick it wrong.

    Edit: Also note, that the default signet challenge is 1-of-2 multisig. Which means, that you can have for example two different nodes, making signatures for two different public keys. Both nodes can be connected to the same network, but they don’t have to maintain a direct P2P connection. Which means, that if you have one signet miner, and another signet miner, and there are some attackers in the middle, then they can capture the real block, grind it (also with ASICs, because why not), and share different headers with different nodes.


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: 2025-09-02 12:13 UTC

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