Fix IsInitialBlockDownload for testnet #7514

pull jmacwhyte wants to merge 1 commits into bitcoin:master from jmacwhyte:fixisinitialblock changing 1 files +1 −1
  1. jmacwhyte commented at 9:07 AM on February 11, 2016: contributor

    Problem: When running in testnet, a node can get stuck in IsInitialBlockDownload mode which will prevent it from responding to any GETHEADERS requests. This can make testing difficult! This problem does not happen on mainnet.

    Theory: Testnet is a little wonky with the 20-minute difficulty reset condition. The nChainWork calculation can cause pindexBestHeader to be set with an old block that has more work than chainActive.Tip(). If that block is more than nMaxTipAge old, IsInitialBlockDownload will always return true.

    Suggested solution: The current code works fine for mainnet, so I added a check to see if we are using testnet, and if so use chainActive.Tip() instead of pindexBestHeader when checking to see how far along we are with the block download. It's my thought that if the current tip is less than one day old (the nMaxTipAge default), it's probably safe to release IsInitialBlockDownload regardless of the age of pindexBestHeader.

    [Edit: As per the comments below, I removed the check for testnet and instead used the greater of chainActive or BestHeader.]

  2. laanwj added the label P2P on Feb 11, 2016
  3. laanwj commented at 9:11 AM on February 11, 2016: member

    Are we sure this condition cannot happen on mainnet?

    Introducing testnet-specific behavior is bad, as it makes testnet less useful as a proxy for testing mainnet. Also comparing strings here isn't acceptable - if you really need to do this it should be a flag on CChainParams. But I hope we can come up with a general solution.

  4. jmacwhyte commented at 9:58 PM on February 11, 2016: contributor

    Thanks for the feedback. I agree, testnet-specific behavior should be avoided if at all possible, but the testnet-specific difficulty rules seem to be what is causing the problem. Maybe another solution would be to have the code that resets testnet difficulty after 20 minutes also reset the work value for pindexBestHeader so a new block with less work is able to replace it. I'm not sure where that happens, though, so I haven't been able to test it out.

    It's also possible my theory isn't exactly correct. Currently, my pindexBestHash is set to a block with a height 2000 below the current tip, but the nChainWork is greater than the current tip. It doesn't show on any block explorers, so maybe it was set to a very high difficulty then orphaned.

    In theory the same thing could happen on mainnet, but with the amount of mining power out there I can't imagine someone mining an orphaned block that still has more POW than the main chain 2000 blocks later.

    Thoughts?

  5. gmaxwell commented at 10:01 PM on February 11, 2016: contributor

    It's certainly possible for mainnet to have a chain with more blocks but lower total work.

  6. jmacwhyte commented at 10:12 PM on February 11, 2016: contributor

    If that were the case, wouldn't the chain with more work be chosen as the active chain?

  7. gmaxwell commented at 10:14 PM on February 11, 2016: contributor

    Yes, and that should be true for testnet too.

  8. jmacwhyte commented at 10:34 PM on February 11, 2016: contributor

    Can we therefore assume chainActive is what we always believe to the be the "correct" chain? If so, can we just check to see if chainActive is within 24 hours of us when doing the IsInitialBlockDownload check (instead of pindexBestHeader)? That's another solution I had thought of, but didn't know if it would have other implications on mainnet.

  9. sipa commented at 10:39 PM on February 11, 2016: member

    chainActive is the currently best fully validated chain, always.

    I think this issue can be fixed by using std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) instead of just pindexBestHeader->GetBlockTime().

  10. Fix IsInitialBlockDownload to play nice with testnet 8aa722609d
  11. jmacwhyte force-pushed on Feb 12, 2016
  12. jmacwhyte commented at 2:06 AM on February 12, 2016: contributor

    I think that's a great idea. As long as it only triggers until the node thinks it's close to finishing the initial block download, this method will accomplish its purpose. Either using the active chain or the best header should work.

    I have updated the pull request.

  13. luke-jr commented at 2:49 AM on February 13, 2016: member

    The nChainWork calculation can cause pindexBestHeader to be set with an old block that has more work than chainActive.Tip().

    If it's an old block (ie, presumably one we have), shouldn't it be the active tip???

  14. jmacwhyte commented at 7:07 AM on February 13, 2016: contributor

    It should be, but for some reason my node's BestHeader wasn't even in the active chain. Where is the 20-minute difficulty reset rule defined? Is it possible something in there is facilitating high-POW orphans?

    On Fri, Feb 12, 2016 at 6:49 PM Luke-Jr notifications@github.com wrote:

    The nChainWork calculation can cause pindexBestHeader to be set with an old block that has more work than chainActive.Tip().

    If it's an old block (ie, presumably one we have), shouldn't it be the active tip???

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

  15. sipa commented at 4:19 PM on February 13, 2016: member

    That can only be the case while we're still catching up on the more-work chain (so we know about its headers, but haven't validated the blocks).

  16. laanwj commented at 11:47 AM on February 16, 2016: member

    Needs ACKs before merge

  17. jmacwhyte commented at 12:43 AM on February 23, 2016: contributor

    I will do some more research on the deeper problem and present what I can find, if anything.

  18. jmacwhyte renamed this:
    Fix IsInitialBlockDownload for testnet
    [WIP] Fix IsInitialBlockDownload for testnet
    on Feb 23, 2016
  19. dcousens commented at 2:21 PM on February 24, 2016: contributor

    utACK

  20. sipa commented at 9:38 PM on March 5, 2016: member

    I'm not convinced the current code is sufficient to solve all problems related to the wonkyness of testnet mining, but it won't hurt. utACK.

  21. jmacwhyte commented at 12:14 AM on March 11, 2016: contributor

    I'm no longer able to reproduce the problem, as my node's chain tip and best header are now in sync. I agree there is probably a deeper problem here, but I think the proposed changes are acceptable because they help testnet nodes act more like mainnet in some fringe cases without affecting anything other than isInitialBlockDownload (which should only matter when nodes are first getting started).

    I have been running my node with the proposed changes and haven't noticed any adverse effects. Can I ACK my own proposal? :)

  22. laanwj renamed this:
    [WIP] Fix IsInitialBlockDownload for testnet
    Fix IsInitialBlockDownload for testnet
    on Apr 28, 2016
  23. laanwj merged this on Apr 28, 2016
  24. laanwj closed this on Apr 28, 2016

  25. laanwj referenced this in commit d9594bfe0c on Apr 28, 2016
  26. sickpig referenced this in commit dd2b76c9a4 on Feb 25, 2017
  27. sickpig referenced this in commit 5ec065b616 on Feb 25, 2017
  28. sickpig referenced this in commit 783f0e9dc6 on Feb 25, 2017
  29. sickpig referenced this in commit f942da52ad on Feb 25, 2017
  30. sickpig referenced this in commit 7114cd2e1e on Feb 27, 2017
  31. sickpig referenced this in commit 1fc2cf9f37 on Feb 27, 2017
  32. sickpig referenced this in commit f038c7a406 on Feb 27, 2017
  33. gandrewstone referenced this in commit 905170c7e8 on Mar 1, 2017
  34. DrahtBot locked this on Sep 8, 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: 2026-05-02 12:15 UTC

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