Skip to content

Commit 32b2696

Browse files
committed
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.
1 parent 9d6dcc5 commit 32b2696

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/validation.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4209,9 +4209,18 @@ void CChainState::EraseBlockData(CBlockIndex* index)
42094209
bool CChainState::RewindBlockIndex(const CChainParams& params)
42104210
{
42114211
LOCK(cs_main);
4212-
42134212
// Note that during -reindex-chainstate we are called with an empty chainActive!
42144213

4214+
// First erase all post-segwit blocks without witness not in the main chain,
4215+
// as this can we done without costly DisconnectTip calls. Active
4216+
// blocks will be dealt with below.
4217+
for (const auto& entry : mapBlockIndex) {
4218+
if (IsWitnessEnabled(entry.second->pprev, params.GetConsensus()) && !(entry.second->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(entry.second)) {
4219+
EraseBlockData(entry.second);
4220+
}
4221+
}
4222+
4223+
// Find what height we need to reorganize to.
42154224
int nHeight = 1;
42164225
while (nHeight <= chainActive.Height()) {
42174226
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
@@ -4226,6 +4235,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
42264235
// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
42274236
CValidationState state;
42284237
CBlockIndex* pindex = chainActive.Tip();
4238+
CBlockIndex* tip = pindex;
42294239
while (chainActive.Height() >= nHeight) {
42304240
if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
42314241
// If pruning, don't try rewinding past the HAVE_DATA point;
@@ -4248,17 +4258,16 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
42484258
// Reduce validity flag and have-data flags.
42494259
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
42504260
// to disk before writing the chainstate, resulting in a failure to continue if interrupted.
4251-
for (const auto& entry : mapBlockIndex) {
4252-
CBlockIndex* pindexIter = entry.second;
4253-
4261+
while (tip->nHeight > chainActive.Height()) {
42544262
// Note: If we encounter an insufficiently validated block that
42554263
// is on chainActive, it must be because we are a pruning node, and
42564264
// this block or some successor doesn't HAVE_DATA, so we were unable to
42574265
// rewind all the way. Blocks remaining on chainActive at this point
42584266
// must not have their validity reduced.
4259-
if (IsWitnessEnabled(pindexIter->pprev, params.GetConsensus()) && !(pindexIter->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(pindexIter)) {
4260-
EraseBlockData(pindexIter);
4267+
if (IsWitnessEnabled(tip->pprev, params.GetConsensus()) && !(tip->nStatus & BLOCK_OPT_WITNESS)) {
4268+
EraseBlockData(tip);
42614269
}
4270+
tip = tip->pprev;
42624271
}
42634272

42644273
if (chainActive.Tip() != nullptr) {

0 commit comments

Comments
 (0)