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