Consensus: Decouple ContextualCheckBlockHeader from checkpoints #5975

pull jtimon wants to merge 1 commits into bitcoin:master from jtimon:consensus_checkpoints changing 1 files +19 −16
  1. jtimon commented at 4:08 pm on April 6, 2015: contributor

    By separating a new CheckIndexAgainstCheckpoint() from ContextualCheckBlockHeader(). @theuni you will probably be interested in this since you were doing some work on the checkpoints. I hope it doesn’t conflict with what you’ve done.

    The checkpoints shouldn’t be used to check a new block header. Instead, they should be used to check the index (the chain) that it’s going to be used to check new block header.

  2. laanwj added the label Improvement on Apr 7, 2015
  3. jtimon commented at 1:26 pm on April 8, 2015: contributor
    fixed after a discussion with @theuni on IRC Now CheckIndexAgainstCheckpoint() takes CChainParams instead of uint256& hashGenesisBlock as parameter to avoid conflicts with work that he is doing in parallel related to checkpoints. Ready for squash. #5968 and #5970 probably need to be adapted to CheckIndexAgainstCheckpoint depending on CChainParams.
  4. in src/main.cpp: in 7461d64d85 outdated
    2641@@ -2640,6 +2642,8 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
    2642         if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
    2643             return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
    2644     }
    2645+    if (!CheckIndexAgainstCheckpoint(pindexPrev, state, params, mapBlockIndex))
    


    theuni commented at 4:35 pm on April 8, 2015:
    Shouldn’t these just return false? state is already set in CheckIndexAgainstCheckpoint().
  5. jtimon commented at 5:12 pm on April 8, 2015: contributor
    2 more fixes, ready to squash
  6. jtimon force-pushed on Apr 8, 2015
  7. jtimon force-pushed on Apr 8, 2015
  8. jtimon force-pushed on Apr 9, 2015
  9. jtimon force-pushed on Apr 9, 2015
  10. jtimon force-pushed on Apr 15, 2015
  11. jtimon commented at 12:00 pm on April 15, 2015: contributor
    Needed rebase.
  12. jtimon force-pushed on Apr 19, 2015
  13. jtimon commented at 9:35 pm on April 19, 2015: contributor
    Somehow I missed this one. Renamed params to chainparams like everywhere else.
  14. jtimon commented at 10:01 am on April 22, 2015: contributor
    ping @theuni
  15. in src/main.cpp: in e55ad48336 outdated
    2539@@ -2540,19 +2540,30 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
    2540     return true;
    2541 }
    2542 
    2543-bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
    2544+static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const BlockMap& mapBlockIndex)
    


    theuni commented at 10:28 pm on April 22, 2015:
    nit: mapBlockIndex shadows the global, will be confusing when it’s used.
  16. theuni commented at 11:14 pm on April 22, 2015: member
    ut ack other than the nit
  17. jtimon force-pushed on Apr 22, 2015
  18. jtimon commented at 11:32 pm on April 22, 2015: contributor
    nit solved
  19. theuni commented at 9:06 pm on April 23, 2015: member
    Thanks, looks good.
  20. in src/main.cpp: in b00583b134 outdated
    2547-    uint256 hash = block.GetHash();
    2548-    if (hash == consensusParams.hashGenesisBlock)
    2549-        return true;
    2550-
    2551     assert(pindexPrev);
    2552+    if (*pindexPrev->phashBlock == chainparams.GetConsensus().hashGenesisBlock)
    


    sipa commented at 10:11 am on April 24, 2015:
    I’d rather keep comparisons with the genesis block out of the “checkpoints” logic. That’s purely philosophical, but we may get rid of checkpoints at some point, though the genesis block will always remain part of consensus.

    jtimon commented at 10:11 am on April 25, 2015:

    Well, the question is, should we validate the genesis block? I don’t think so, the genesis block is hardcoded, no need to check it redundantly from many computers. So this is more moving that check out of consensus than “moving it to the checkpoints logic”.

    But of course, if your the tip of the chain index you’re using (your pindexPrev) is the genesis block (that is, if you’re validating the second block), you can skip the other checkpoint tests.

    What you want to check is that your chain index contains the genesis block. Or with checkpoints, you may even want to just check that your chain index contains the previous checkpoint (you have to be certain that all your checkpoints contain the genesis block when your hardcode them). In that sense you can see the genesis block just as the oldest checkpoint possible.

    But thanks for bringing this up, this is the only change in logic and what needs discussion.

  21. jtimon force-pushed on May 6, 2015
  22. jtimon commented at 10:45 am on May 6, 2015: contributor
    Needed rebase
  23. jtimon force-pushed on May 6, 2015
  24. jtimon force-pushed on May 6, 2015
  25. theuni commented at 4:29 pm on May 6, 2015: member

    @jtimon I think #6055 was a big improvement in readability for the checkpoint functions because it moved the “what if checkpoints aren’t enabled” case out of the actual checkpoint logic. This would undo some of that.

    How about removing the early return from CheckIndexAgainstCheckpoint() and instead calling into it like if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(...)) ?

  26. jtimon commented at 4:52 pm on May 6, 2015: contributor
    I disagree that this undoes part of #6055 but I’m ok with your proposed alternative. I thought about it too but I didn’t wanted to take the assert(pindexPrev); out of the function as well.
  27. theuni commented at 5:09 pm on May 6, 2015: member

    Sorry, that was poorly worded. It wouldn’t undo any of #6055, but it would negate one of the beneficial side-effects of it.

    As for not removing the assert, I don’t follow. pindexPrev is used whether checkpoints are enabled or not, so relying on the assert in CheckIndexAgainstCheckpoint() even if checkpoints are disabled makes no sense to me.

  28. jtimon commented at 5:15 pm on May 6, 2015: contributor

    I still disagree that it is removing one of the beneficial side effects of it, I don’t think the negated condition is less readable…

    Anyway, what I mean is that if I want to maintain it almost equivalent (is not completely equivalent functionally because I’m changing the genesis check as discussed in the outdated comment by @sipa), I can’t do just

    0if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(...))
    

    It would need to be something like

    0assert(pindexPrev);
    1if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(...))
    

    because pindexPrev shouldn’t arrive NULL to ContextualCheckBlockHeader. But I’m fine with that, should I change it to that, then?

  29. theuni commented at 5:27 pm on May 6, 2015: member
    Yes, that looks good. Thanks.
  30. jtimon force-pushed on May 6, 2015
  31. jtimon commented at 5:44 pm on May 6, 2015: contributor
    Done, changed as suggested by @theuni
  32. in src/main.cpp: in 102b09bff5 outdated
    2711@@ -2715,6 +2712,9 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
    2712         if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
    2713             return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
    2714     }
    2715+    assert(pindexPrev);
    


    sipa commented at 11:10 pm on May 7, 2015:

    Any reason why the checkpoints check is moved?

    I think it’s harmless to do so, but I was wondering if there is a reason.


    jtimon commented at 10:28 am on May 8, 2015:
    Apparently having the check of the global boolean outside of the function is more readable according to @theuni.

    theuni commented at 7:39 pm on May 9, 2015:
    @sipa if you’re referring to fCheckpointsEnabled moving out of CheckIndexAgainstCheckpoint(), I requested that to reduce the side-effects of CheckIndexAgainstCheckpoint(). Imo if possible the checkpoint functions should be side-effect free so that we know it’s consensus-safe to simply not call them at all.

    sipa commented at 11:30 pm on May 9, 2015:
    I’m referring to the fCheckpointsEnabled conditional. Just to the fact that the checkpoints-checking point in this function moving.

    jtimon commented at 12:45 pm on May 10, 2015:
    @sipa I’m still not sure what you mean. The checkpoints checks are moved out of ContextualCheckBlockHeader to keep them out of consensus. Then is moved up in the functions, because you should have your index checked before checking a new block, maybe they can be moved upper (and earlier in time) later. I suspect the index is checked in this way redundantly. If this is an issue I can maintain the calls to CheckIndexAgainstCheckpoint right before the calls to ContextualCheckBlockHeader.

    sipa commented at 8:39 pm on May 10, 2015:
    Sorry, I missed this was in AcceptBlockHeader already, and not in ContextualCheckBlockHeader anymore. Looks good.
  33. in src/main.cpp: in 102b09bff5 outdated
    2823@@ -2824,8 +2824,11 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
    2824 
    2825 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
    2826 {
    2827+    const CChainParams& chainparams = Params();
    2828     AssertLockHeld(cs_main);
    2829-    assert(pindexPrev == chainActive.Tip());
    2830+    assert(pindexPrev && pindexPrev == chainActive.Tip());
    2831+    if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, block.GetHash(), mapBlockIndex))
    2832+        return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str());
    


    sipa commented at 3:07 am on May 8, 2015:

    No need to print an error in this case; it’s perfectly legitimate that this fails.

    EDIT: Hmm, the rest of the checks prints stuff too. Never mind then, but I think we should fix that independently (there are probably already issues about that).


    jtimon commented at 10:32 am on May 8, 2015:
    Yes I’m trying to move the errors up (because logging errrors shouldnt be done in consensus, but one step at a time. That is the kind of change that is better done after the moveonly, hopefully, one day…
  34. jtimon commented at 10:34 am on May 8, 2015: contributor
    @sipa I answered to your worries on checking the genesis block. You never answered back so I assume you were satisfied by my answer.
  35. sipa commented at 9:30 pm on May 10, 2015: member
    Untested ACK
  36. jtimon force-pushed on May 27, 2015
  37. jtimon commented at 1:45 pm on May 27, 2015: contributor
    Updated without the unused blockIndexMap parameter. It may take long until it gets used so better to just introduce it at that point.
  38. laanwj commented at 8:42 am on June 10, 2015: member
    Sorry: needs rebase after #5927, will merge after that.
  39. Consensus: Separate CheckIndexAgainstCheckpoint() from ContextualCheckBlockHeader 425c3a87ff
  40. jtimon force-pushed on Jun 10, 2015
  41. jtimon commented at 11:13 am on June 10, 2015: contributor
    No worries, it was an easy rebase.
  42. laanwj merged this on Jun 10, 2015
  43. laanwj closed this on Jun 10, 2015

  44. laanwj referenced this in commit 1fea667216 on Jun 10, 2015
  45. sdaftuar commented at 6:56 pm on June 16, 2015: member
    This appears to have broken running bitcoind with -reindex(!); it appears the assert(pindexPrev) in AcceptBlockHeader can be reached when processing the genesis block from disk. Can be reproduced by running qa/rpc-tests/reindex.py.
  46. jtimon referenced this in commit 460c57e049 on Jun 17, 2015
  47. jtimon commented at 7:30 pm on June 17, 2015: contributor
    @sdaftuar created #6299 to fix the bug.
  48. jtimon referenced this in commit b6e00e8f13 on Jun 18, 2015
  49. jtimon referenced this in commit 36c97b4e5d on Jun 20, 2015
  50. zkbot referenced this in commit df07f9ad23 on Feb 15, 2017
  51. MarcoFalke 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: 2024-12-18 18:12 UTC

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