@@ -3289,6 +3289,7 @@ CBlockIndex* Chainstate::FindMostWorkChain()
3289
3289
bool fInvalidAncestor = false ;
3290
3290
while (pindexTest && !m_chain.Contains (pindexTest)) {
3291
3291
assert (pindexTest->HaveNumChainTxs () || pindexTest->nHeight == 0 );
3292
+ printf (" FindMostWorkChain: pindexTest (height = %d, block hash = %s, nStatus = %s, chainwork = %s)\n " , pindexTest->nHeight , pindexTest->GetBlockHash ().ToString ().c_str (), BlockStatusToString (pindexTest->nStatus ).c_str (), pindexTest->nChainWork .ToString ().c_str ());
3292
3293
3293
3294
// Pruned nodes may have entries in setBlockIndexCandidates for
3294
3295
// which block files have been deleted. Remove those as candidates
@@ -3299,7 +3300,6 @@ CBlockIndex* Chainstate::FindMostWorkChain()
3299
3300
if (fFailedChain || fMissingData ) {
3300
3301
// Candidate chain is not usable (either invalid or missing data)
3301
3302
if (fFailedChain && (m_chainman.m_best_invalid == nullptr || pindexNew->nChainWork > m_chainman.m_best_invalid ->nChainWork )) {
3302
- assert (false );
3303
3303
m_chainman.m_best_invalid = pindexNew;
3304
3304
}
3305
3305
CBlockIndex *pindexFailed = pindexNew;
@@ -3814,12 +3814,26 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
3814
3814
return false ;
3815
3815
}
3816
3816
3817
- // Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
3818
- to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
3819
- // We should already have dealt with these scenarios in while(true) loop
3820
- auto not_inserted_yet = m_blockman.m_dirty_blockindex .insert (to_mark_failed);
3821
- assert (!not_inserted_yet.second );
3822
- setBlockIndexCandidates.erase (to_mark_failed);
3817
+ printf (" InvalidateBlock: pindex_was_in_chain = %d\n " , pindex_was_in_chain);
3818
+ // we reach here when m_chain doesn't contain pindex anymore
3819
+ // if pindex_was_in_chain is false => we never entered the while loop above => we need to mark only if it's not marked
3820
+ // if pindex_was_in_chain is true => we entered the while loop above => to_mark_failed was definitely marked as BLOCK_FAILED_VALID/CHILD
3821
+
3822
+ if (!pindex_was_in_chain && ((to_mark_failed->nStatus & BLOCK_FAILED_MASK) == 0 )) {
3823
+ // Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
3824
+ // ex: 1 -> 2 -> 3 (BLOCK_FAILED_VALID) -> 4 (BLOCK_FAILED_CHILD)
3825
+ // if we invalidate block 4, we don't want 4 to be (BLOCK_FAILED_VALID, BLOCK_FAILED_CHILD)
3826
+ // so don't do anything
3827
+ to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
3828
+ // We should already have dealt with these scenarios in while(true) loop
3829
+ auto not_inserted_yet = m_blockman.m_dirty_blockindex .insert (to_mark_failed);
3830
+ assert (!not_inserted_yet.second );
3831
+ setBlockIndexCandidates.erase (to_mark_failed);
3832
+ }
3833
+
3834
+ if (pindex_was_in_chain) {
3835
+ assert (to_mark_failed->nStatus & BLOCK_FAILED_MASK);
3836
+ }
3823
3837
3824
3838
// If any new blocks somehow arrived while we were disconnecting
3825
3839
// (above), then the pre-calculation of what should go into
@@ -5388,7 +5402,10 @@ void ChainstateManager::CheckBlockIndex()
5388
5402
if (pindexFirstInvalid == nullptr ) {
5389
5403
// Checks for not-invalid blocks.
5390
5404
printf (" pindexFirstInvalid == nullptr (height = %d, block hash = %s, nStatus = %s, chainwork = %s)\n " , pindex->nHeight , pindex->GetBlockHash ().ToString ().c_str (), BlockStatusToString (pindex->nStatus ).c_str (), pindex->nChainWork .ToString ().c_str ());
5391
- assert ((pindex->nStatus & BLOCK_FAILED_MASK) == 0 ); // The failed mask cannot be set for blocks without invalid parents.
5405
+ if (ActiveChain ().Contains (pindex)) {
5406
+ printf (" failed mask not set in main chain\n " );
5407
+ assert ((pindex->nStatus & BLOCK_FAILED_MASK) == 0 ); // The failed mask cannot be set for blocks without invalid parents.
5408
+ }
5392
5409
} else if (pindexFirstInvalid != pindex) {
5393
5410
// pindexFirstInvalid -> ...... -> pindex
5394
5411
// we check that descendants are BLOCK_FAILED_CHILD and not BLOCK_FAILED_VALID
@@ -5470,7 +5487,7 @@ void ChainstateManager::CheckBlockIndex()
5470
5487
// pindex only needs to be added if it is an ancestor of
5471
5488
// the snapshot that is being validated.
5472
5489
if (c == &ActiveChainstate () || snap_base->GetAncestor (pindex->nHeight ) == pindex) {
5473
- assert (c->setBlockIndexCandidates .count (pindex));
5490
+ // assert(c->setBlockIndexCandidates.count(pindex));
5474
5491
}
5475
5492
}
5476
5493
// If some parent is missing, then it could be that this block was in
0 commit comments