diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 00e0a487d..bf16d76b3 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -165,8 +165,8 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering) // to make sure that eventually we process the full chain - do it here for (auto block : blocks) { if (block->vtx.size() == 1) { - bool processed = ProcessNewBlock(Params(), block, true, &ignored, false); - assert(processed); + ProcessNewBlock(Params(), block, true, &ignored, false); + assert(!ignored); } } }); diff --git a/src/validation.cpp b/src/validation.cpp index faedb3746..8d7c122db 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2600,8 +2600,8 @@ bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainPar { AssertLockHeld(cs_main); - const CBlockIndex *pindexOldTip = chainActive.Tip(); - const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); + auto pindexOldTip = chainActive.Tip(); + auto pindexFork = chainActive.FindFork(pindexMostWork); // Disconnect active blocks which are no longer in the best chain. bool fBlocksDisconnected = false; @@ -2616,6 +2616,23 @@ bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainPar fBlocksDisconnected = true; } + // Now mark the blocks we just disconnected as descendants invalid + // (note this may not be all descendants). + if (fBlocksDisconnected) { + auto invalid_walk_tip = pindexOldTip; + while (invalid_walk_tip != pindexFork) { + auto prev = invalid_walk_tip->pprev; + if (prev == pindexFork) { + InvalidBlockFound(invalid_walk_tip, state); + break; + } + invalid_walk_tip->nStatus |= BLOCK_FAILED_CHILD; + setDirtyBlockIndex.insert(invalid_walk_tip); + setBlockIndexCandidates.erase(invalid_walk_tip); + invalid_walk_tip = prev; + } + } + // Build list of new blocks to connect. std::vector vpindexToConnect; bool fContinue = true;