diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2725,21 +2725,25 @@ return ActivateBestChain(config, state); } +static void UnwindIndividualBlock(CBlockIndex *pindex, bool invalidate) { + // Mark the block as either invalid or parked. + if (invalidate) { + pindex->nStatus = pindex->nStatus.withFailed(true); + } else { + pindex->nStatus = pindex->nStatus.withParked(true); + } + setDirtyBlockIndex.insert(pindex); +} + static bool UnwindBlock(const Config &config, CValidationState &state, CBlockIndex *pindex, bool invalidate) { AssertLockHeld(cs_main); - - // Mark the block itself as invalid. - pindex->nStatus = - pindex->nStatus.withFailed(invalidate).withParked(!invalidate); - setDirtyBlockIndex.insert(pindex); + UnwindIndividualBlock(pindex, invalidate); DisconnectedBlockTransactions disconnectpool; while (chainActive.Contains(pindex)) { CBlockIndex *pindexWalk = chainActive.Tip(); - pindexWalk->nStatus = - pindexWalk->nStatus.withFailed(invalidate).withParked(!invalidate); - setDirtyBlockIndex.insert(pindexWalk); + UnwindIndividualBlock(pindexWalk, invalidate); // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. diff --git a/test/functional/abc-parkedchain.py b/test/functional/abc-parkedchain.py --- a/test/functional/abc-parkedchain.py +++ b/test/functional/abc-parkedchain.py @@ -16,7 +16,7 @@ def run_test(self): node = self.nodes[0] - self.log.info("test chain parking") + self.log.info("Test 1: Test chain parking") node.generate(10) tip = node.getbestblockhash() node.generate(1) @@ -33,6 +33,20 @@ node.unparkblock(parked_tip) assert_equal(node.getbestblockhash(), parked_tip) + self.log.info("Test 2: Test chain parking with invalid blocks") + node.generate(1) + tip = node.getbestblockhash() + node.generate(1) + invalid_tip = node.getbestblockhash() + + node.invalidateblock(invalid_tip) + assert_equal(node.getbestblockhash(), tip) + + # Parking and then unparking a block should not change its validity + node.parkblock(invalid_tip) + node.unparkblock(invalid_tip) + assert_equal(node.getbestblockhash(), tip) + if __name__ == '__main__': ParckedChainTest().main()