MCPcopy Create free account
hub / github.com/BTCGPU/BTCGPU / RewindBlockIndex

Method RewindBlockIndex

src/validation.cpp:4417–4506  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4415}
4416
4417bool CChainState::RewindBlockIndex(const CChainParams& params)
4418{
4419 LOCK(cs_main);
4420
4421 // Note that during -reindex-chainstate we are called with an empty chainActive!
4422
4423 int nHeight = 1;
4424 while (nHeight <= chainActive.Height()) {
4425 // Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
4426 // blocks in ConnectBlock, we don't need to go back and
4427 // re-download/re-verify blocks from before segwit actually activated.
4428 if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus()) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) {
4429 break;
4430 }
4431 nHeight++;
4432 }
4433
4434 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
4435 CValidationState state;
4436 CBlockIndex* pindex = chainActive.Tip();
4437 while (chainActive.Height() >= nHeight) {
4438 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
4439 // If pruning, don't try rewinding past the HAVE_DATA point;
4440 // since older blocks can't be served anyway, there's
4441 // no need to walk further, and trying to DisconnectTip()
4442 // will fail (and require a needless reindex/redownload
4443 // of the blockchain).
4444 break;
4445 }
4446 if (!DisconnectTip(state, params, nullptr)) {
4447 return error("RewindBlockIndex: unable to disconnect block at height %i (%s)", pindex->nHeight, FormatStateMessage(state));
4448 }
4449 // Occasionally flush state to disk.
4450 if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC)) {
4451 LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
4452 return false;
4453 }
4454 }
4455
4456 // Reduce validity flag and have-data flags.
4457 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
4458 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
4459 for (const auto& entry : mapBlockIndex) {
4460 CBlockIndex* pindexIter = entry.second;
4461
4462 // Note: If we encounter an insufficiently validated block that
4463 // is on chainActive, it must be because we are a pruning node, and
4464 // this block or some successor doesn't HAVE_DATA, so we were unable to
4465 // rewind all the way. Blocks remaining on chainActive at this point
4466 // must not have their validity reduced.
4467 if (IsWitnessEnabled(pindexIter->pprev, params.GetConsensus()) && !(pindexIter->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(pindexIter)) {
4468 // Reduce validity
4469 pindexIter->nStatus = std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) | (pindexIter->nStatus & ~BLOCK_VALID_MASK);
4470 // Remove have-data flags.
4471 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
4472 // Remove storage location.
4473 pindexIter->nFile = 0;
4474 pindexIter->nDataPos = 0;

Callers 1

RewindBlockIndexFunction · 0.80

Calls 10

IsWitnessEnabledFunction · 0.85
errorFunction · 0.85
FormatStateMessageFunction · 0.85
FlushStateToDiskFunction · 0.85
HeightMethod · 0.80
TipMethod · 0.45
ContainsMethod · 0.45
insertMethod · 0.45
eraseMethod · 0.45
IsValidMethod · 0.45

Tested by

no test coverage detected