Move erasure of non-active blocks to a separate loop in RewindBlockIndex
This lets us simplify the iteration to just walking back in the chain, rather than looping over all of mapBlockIndex.
This commit is contained in:
parent
9d6dcc52c6
commit
32b2696ab4
1 changed files with 15 additions and 6 deletions
|
@ -4209,9 +4209,18 @@ void CChainState::EraseBlockData(CBlockIndex* index)
|
||||||
bool CChainState::RewindBlockIndex(const CChainParams& params)
|
bool CChainState::RewindBlockIndex(const CChainParams& params)
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
// Note that during -reindex-chainstate we are called with an empty chainActive!
|
// Note that during -reindex-chainstate we are called with an empty chainActive!
|
||||||
|
|
||||||
|
// First erase all post-segwit blocks without witness not in the main chain,
|
||||||
|
// as this can we done without costly DisconnectTip calls. Active
|
||||||
|
// blocks will be dealt with below.
|
||||||
|
for (const auto& entry : mapBlockIndex) {
|
||||||
|
if (IsWitnessEnabled(entry.second->pprev, params.GetConsensus()) && !(entry.second->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(entry.second)) {
|
||||||
|
EraseBlockData(entry.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find what height we need to reorganize to.
|
||||||
int nHeight = 1;
|
int nHeight = 1;
|
||||||
while (nHeight <= chainActive.Height()) {
|
while (nHeight <= chainActive.Height()) {
|
||||||
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
|
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
|
||||||
|
@ -4226,6 +4235,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
|
||||||
// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
|
// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
CBlockIndex* pindex = chainActive.Tip();
|
CBlockIndex* pindex = chainActive.Tip();
|
||||||
|
CBlockIndex* tip = pindex;
|
||||||
while (chainActive.Height() >= nHeight) {
|
while (chainActive.Height() >= nHeight) {
|
||||||
if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
|
if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
|
||||||
// If pruning, don't try rewinding past the HAVE_DATA point;
|
// If pruning, don't try rewinding past the HAVE_DATA point;
|
||||||
|
@ -4248,17 +4258,16 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
|
||||||
// Reduce validity flag and have-data flags.
|
// Reduce validity flag and have-data flags.
|
||||||
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
|
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
|
||||||
// to disk before writing the chainstate, resulting in a failure to continue if interrupted.
|
// to disk before writing the chainstate, resulting in a failure to continue if interrupted.
|
||||||
for (const auto& entry : mapBlockIndex) {
|
while (tip->nHeight > chainActive.Height()) {
|
||||||
CBlockIndex* pindexIter = entry.second;
|
|
||||||
|
|
||||||
// Note: If we encounter an insufficiently validated block that
|
// Note: If we encounter an insufficiently validated block that
|
||||||
// is on chainActive, it must be because we are a pruning node, and
|
// is on chainActive, it must be because we are a pruning node, and
|
||||||
// this block or some successor doesn't HAVE_DATA, so we were unable to
|
// this block or some successor doesn't HAVE_DATA, so we were unable to
|
||||||
// rewind all the way. Blocks remaining on chainActive at this point
|
// rewind all the way. Blocks remaining on chainActive at this point
|
||||||
// must not have their validity reduced.
|
// must not have their validity reduced.
|
||||||
if (IsWitnessEnabled(pindexIter->pprev, params.GetConsensus()) && !(pindexIter->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(pindexIter)) {
|
if (IsWitnessEnabled(tip->pprev, params.GetConsensus()) && !(tip->nStatus & BLOCK_OPT_WITNESS)) {
|
||||||
EraseBlockData(pindexIter);
|
EraseBlockData(tip);
|
||||||
}
|
}
|
||||||
|
tip = tip->pprev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chainActive.Tip() != nullptr) {
|
if (chainActive.Tip() != nullptr) {
|
||||||
|
|
Loading…
Reference in a new issue