|
|
@ -2525,43 +2525,43 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c |
|
|
|
bool fContinue = true; |
|
|
|
bool fContinue = true; |
|
|
|
int nHeight = pindexFork ? pindexFork->nHeight : -1; |
|
|
|
int nHeight = pindexFork ? pindexFork->nHeight : -1; |
|
|
|
while (fContinue && nHeight != pindexMostWork->nHeight) { |
|
|
|
while (fContinue && nHeight != pindexMostWork->nHeight) { |
|
|
|
// Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
|
|
|
|
// Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
|
|
|
|
// a few blocks along the way.
|
|
|
|
// a few blocks along the way.
|
|
|
|
int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); |
|
|
|
int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); |
|
|
|
vpindexToConnect.clear(); |
|
|
|
vpindexToConnect.clear(); |
|
|
|
vpindexToConnect.reserve(nTargetHeight - nHeight); |
|
|
|
vpindexToConnect.reserve(nTargetHeight - nHeight); |
|
|
|
CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); |
|
|
|
CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); |
|
|
|
while (pindexIter && pindexIter->nHeight != nHeight) { |
|
|
|
while (pindexIter && pindexIter->nHeight != nHeight) { |
|
|
|
vpindexToConnect.push_back(pindexIter); |
|
|
|
vpindexToConnect.push_back(pindexIter); |
|
|
|
pindexIter = pindexIter->pprev; |
|
|
|
pindexIter = pindexIter->pprev; |
|
|
|
} |
|
|
|
} |
|
|
|
nHeight = nTargetHeight; |
|
|
|
nHeight = nTargetHeight; |
|
|
|
|
|
|
|
|
|
|
|
// Connect new blocks.
|
|
|
|
// Connect new blocks.
|
|
|
|
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
|
|
|
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
|
|
|
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { |
|
|
|
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { |
|
|
|
if (state.IsInvalid()) { |
|
|
|
if (state.IsInvalid()) { |
|
|
|
// The block violates a consensus rule.
|
|
|
|
// The block violates a consensus rule.
|
|
|
|
if (!state.CorruptionPossible()) |
|
|
|
if (!state.CorruptionPossible()) |
|
|
|
InvalidChainFound(vpindexToConnect.back()); |
|
|
|
InvalidChainFound(vpindexToConnect.back()); |
|
|
|
state = CValidationState(); |
|
|
|
state = CValidationState(); |
|
|
|
fInvalidFound = true; |
|
|
|
fInvalidFound = true; |
|
|
|
fContinue = false; |
|
|
|
fContinue = false; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// A system error occurred (disk space, database error, ...).
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// A system error occurred (disk space, database error, ...).
|
|
|
|
PruneBlockIndexCandidates(); |
|
|
|
return false; |
|
|
|
if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { |
|
|
|
} |
|
|
|
// We're in a better position than we were. Return temporarily to release the lock.
|
|
|
|
} else { |
|
|
|
fContinue = false; |
|
|
|
PruneBlockIndexCandidates(); |
|
|
|
break; |
|
|
|
if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { |
|
|
|
} |
|
|
|
// We're in a better position than we were. Return temporarily to release the lock.
|
|
|
|
|
|
|
|
fContinue = false; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fBlocksDisconnected) |
|
|
|
if (fBlocksDisconnected) |
|
|
|
mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); |
|
|
|
mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); |
|
|
|