Prioritize submitblock blocks to prevent attacks on miners using slow-to-verify blocks #5538

issue SergioDemianLerner openend this issue on December 24, 2014
  1. SergioDemianLerner commented at 9:43 pm on December 24, 2014: contributor

    There are ways to create blocks that take a lot of time to verify. Here https://bitcointalk.org/?topic=140078 I created a block with a single prevout dependency that took 3 minutes to verify. I found another way to create a block with a single prevout dependency that take 1 minute to verify and verification time is not related to signature verification time. But since this problem has already been discussed, there is nothing new there. Here I propose a minimum change to protect miners from attacks with slow blocks.

    The Core code holds the cs_main lock in ProcessNewBlock() when a block is being verified, so a miner receiving a slow block would keep mining on an outdated parent. It will not receive new templates based on that block because it’s still being verified, and if he solves the block, that block won’t be chosen to be the tip of best chain because just after the lock is released, ActivateBestChain() will be called and it will add the slow competing block to the chain, preventing the miner’s local block from entering the best chain. (But this may not be always the case because since the RPC runs in another thread, it’s possible that the OS scheduler switches to the RPC thread just after the lock is released, and the RPC thread finally calls ActivateBestChain() before the network thread).

    Of course, it has been said that miners should run two instances of bitcoind, one serving the miners and the other serving the network. However I think that this is a fault in bicoind that should be corrected. Maybe we can change the Core such that if a block submitted by the submitblock RPC call has the same height as a competing block which is the tip, then the block locally submitted has precedence and becomes the new tip. Also we could add a program argument –higher-precedence:ip which would allow blocks submitted by a peer on this ip to have precedence over blocks of equal height submitted by unknown nodes.

    As a side-note, all information we can gather about slow blocks is important since there is a plan to increase the block size. For instance, if we don’t rewrite the CHECKSIG logic, and we let MAX_BLOCK_SIGOPS increase 10x along with a 10 Mb block, then a block with a single prevout dependency could be crafted to take more than 5 hours to verify.

  2. luke-jr commented at 9:55 pm on December 24, 2014: member
    Submitblock is not only used for locally generated blocks - for example, P2Pool submits blocks of other miners this way too.
  3. TheBlueMatt commented at 10:04 pm on December 24, 2014: member

    …(but even in the p2pool case you want those blocks to have priority, because they are paying the whole pool, probably incl you). Still, I’m not a big fan of block discouragement like this, at least unless the new block came in only seconds after the first, we certainly dont need anything that deliberately makes consensus even harder in Bitcoin.

    On 12/24/14 21:55, Luke-Jr wrote:

    Submitblock is not only used for locally generated blocks - for example, P2Pool submits blocks of other miners this way too.

    — Reply to this email directly or view it on GitHub #5538 (comment).

  4. SergioDemianLerner commented at 10:06 pm on December 24, 2014: contributor
    @luke-jr That’s strange. But in that case one could add an additional argument to submitblock: submitblock “hexdata” ( “jsonparametersobject” ) (priority) Where priority is 1 (wins best tip competition) or 0 (normal behavior).
  5. SergioDemianLerner commented at 10:15 pm on December 24, 2014: contributor

    @TheBlueMatt Then we could try to modify ProcessNewBlock() such that it does not hold the cs_main lock.

    Take into account that if an miner attacks all the rest using a slow-to-verify block, then consensus is also attacked, since the remaining miners will be working on irrelevant blocks. In an hypothetical case where miners use a single bitcoind instance, a malicious miner having 5% of the network hashing rate that can create a block that takes 5 hours to verify can mine 100% of the blocks.

  6. luke-jr commented at 10:17 pm on December 24, 2014: member
    @SergioDemianLerner More important IMO is nodes other than the miner - we don’t want everyone else to freeze up for 3 minutes checking the bad block. How to best avoid this, however, I’m not sure…
  7. SergioDemianLerner commented at 10:24 pm on December 24, 2014: contributor
    @luke-jr We could modify the Core not to accept or relay blocks that have a certain DoS fingerprint if they are the tip of the best chain, but relay those blocks it they already have a child block. Then in the worse case consensus is delayed for 1 block. It’s not a hard/soft fork.
  8. luke-jr commented at 10:27 pm on December 24, 2014: member
    I was thinking more like somehow processing unconfirmed transactions in parallel to a block being checked (actually, maybe they already are with headers first and parallel signature checks?), combine with your submitblock tweak here, and finally have nodes abort checking blocks if they in the meantime become no longer the best block (again, yay headers first..)
  9. TheBlueMatt commented at 10:55 pm on December 24, 2014: member

    @SergioDemianLerner Indeed, my point was more that I’m concerned about, eg, a pool (or p2pool, or whatever) which will take anything that passes PoW and just submitblock’s it (I dunno why an implementer wouldnt do it that way), which might allow a pool’s user to make the entire pool (including p2pool) mine on something that no one else considers consensus, and much less about the cases where blocks are received within a few seconds of each other (at which point the network is probably forking anyway).

    Indeed, taking 3 minutes to verify a block is an issue in itself. Luckily, we’re already discouraging blocks (somewhat) from miners who create such large blocks - they’re effectively hobbling their block network propagation. Another way to discourage blocks would be to define the “tie-breaking” rule to be time received + verify time, instead of simply time received.

  10. SergioDemianLerner commented at 10:59 pm on December 24, 2014: contributor

    @luke-jr So your idea would be:

    1. Start verifying the header and PoW of the block. Release the cs_main lock
    2. Dump all block transactions in a newly created transaction pool TXP, and start a new thread to verify them.
    3. After all have been verified, reacquire the cs_main lock and continue processing the block.
    4. If any of the transactions in the TXP pool fails verification, abort and dispose the pool.
  11. SergioDemianLerner commented at 11:00 pm on December 24, 2014: contributor
    @TheBlueMatt Luke solution in fact changes the “tie-breaking” rule to be time received + verify time, because the block is added only after all transactions have been verified.
  12. luke-jr commented at 11:18 pm on December 24, 2014: member
    Something like that, yes.
  13. TheBlueMatt commented at 0:40 am on December 25, 2014: member
    @SergioDemianLerner With headers-first are you sure about that, I recall some code specifically handling tie-breaking? In any case, if we can do the waiting on transaction validation without cs_main thats probably good, though I definitely recall some things rely on that stuff being atomic.
  14. sipa commented at 0:43 am on December 25, 2014: member
    Prioritizing our own blocks is trivial (set the nSequenceId of the CBlockIndex entry to 0).
  15. TheBlueMatt commented at 1:08 am on December 25, 2014: member
    @sipa Yup, but I dont think we want to go nearly that far.
  16. laanwj added the label Mining on Feb 16, 2016
  17. Leviathn commented at 1:57 pm on September 5, 2017: none
    Any progress on this? Seems a lot of work has gone into rapid validation @ chain-tip..
  18. sdaftuar commented at 2:52 pm on September 5, 2017: member
    I think the preciousblock rpc addresses this sufficiently, no? https://github.com/bitcoin/bitcoin/pull/6996
  19. adamjonas commented at 10:44 pm on December 13, 2019: member
    Bumping to verify that #6996 did indeed address this issue as Suhas suggested. cc @fanquake @MarcoFalke
  20. MarcoFalke closed this on Dec 14, 2019

  21. MarcoFalke locked this on Dec 16, 2021

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: 2024-12-22 06:12 UTC

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