aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
authorSjors Provoost <sjors@sprovoost.nl>2018-09-04 10:50:19 +0200
committerSjors Provoost <sjors@sprovoost.nl>2018-09-04 10:50:19 +0200
commit66e15e8f9759b827732865e5686c0203ce7dc1d4 (patch)
tree6edb1f1e7abeaa1c13a2217b200ba055e736c24e /src/validation.cpp
parentf66e1c793eda7a6143fd03400c98512a9b6f00c7 (diff)
downloadbitcoin-66e15e8f9759b827732865e5686c0203ce7dc1d4.tar.xz
Explain GetAncestor check for m_failed_blocks in AcceptBlockHeader
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index fceb135854..af42f6d22b 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -3383,10 +3383,30 @@ bool CChainState::AcceptBlockHeader(const CBlockHeader& block, CValidationState&
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
- // If the previous block index isn't valid, determine if it descends from any block which
- // has been found invalid (m_failed_blocks), then mark pindexPrev and any blocks
- // between them as failed.
+ /* Determine if this block descends from any block which has been found
+ * invalid (m_failed_blocks), then mark pindexPrev and any blocks between
+ * them as failed. For example:
+ *
+ * D3
+ * /
+ * B2 - C2
+ * / \
+ * A D2 - E2 - F2
+ * \
+ * B1 - C1 - D1 - E1
+ *
+ * In the case that we attempted to reorg from E1 to F2, only to find
+ * C2 to be invalid, we would mark D2, E2, and F2 as BLOCK_FAILED_CHILD
+ * but NOT D3 (it was not in any of our candidate sets at the time).
+ *
+ * In any case D3 will also be marked as BLOCK_FAILED_CHILD at restart
+ * in LoadBlockIndex.
+ */
if (!pindexPrev->IsValid(BLOCK_VALID_SCRIPTS)) {
+ // The above does not mean "invalid": it checks if the previous block
+ // hasn't been validated up to BLOCK_VALID_SCRIPTS. This is a performance
+ // optimization, in the common case of adding a new block to the tip,
+ // we don't need to iterate over the failed blocks list.
for (const CBlockIndex* failedit : m_failed_blocks) {
if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) {
assert(failedit->nStatus & BLOCK_FAILED_VALID);