@@ -4209,9 +4209,18 @@ void CChainState::EraseBlockData(CBlockIndex* index)
4209
4209
bool CChainState::RewindBlockIndex (const CChainParams& params)
4210
4210
{
4211
4211
LOCK (cs_main);
4212
-
4213
4212
// Note that during -reindex-chainstate we are called with an empty chainActive!
4214
4213
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.
4215
4224
int nHeight = 1 ;
4216
4225
while (nHeight <= chainActive.Height ()) {
4217
4226
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
@@ -4226,6 +4235,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
4226
4235
// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
4227
4236
CValidationState state;
4228
4237
CBlockIndex* pindex = chainActive.Tip ();
4238
+ CBlockIndex* tip = pindex;
4229
4239
while (chainActive.Height () >= nHeight) {
4230
4240
if (fPruneMode && !(chainActive.Tip ()->nStatus & BLOCK_HAVE_DATA)) {
4231
4241
// If pruning, don't try rewinding past the HAVE_DATA point;
@@ -4248,17 +4258,16 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
4248
4258
// Reduce validity flag and have-data flags.
4249
4259
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
4250
4260
// 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 ()) {
4254
4262
// Note: If we encounter an insufficiently validated block that
4255
4263
// is on chainActive, it must be because we are a pruning node, and
4256
4264
// this block or some successor doesn't HAVE_DATA, so we were unable to
4257
4265
// rewind all the way. Blocks remaining on chainActive at this point
4258
4266
// 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 );
4261
4269
}
4270
+ tip = tip->pprev ;
4262
4271
}
4263
4272
4264
4273
if (chainActive.Tip () != nullptr ) {
0 commit comments