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

Method ReplayBlocks

src/validation.cpp:4348–4411  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4346}
4347
4348bool CChainState::ReplayBlocks(const CChainParams& params, CCoinsView* view)
4349{
4350 LOCK(cs_main);
4351
4352 CCoinsViewCache cache(view);
4353
4354 std::vector<uint256> hashHeads = view->GetHeadBlocks();
4355 if (hashHeads.empty()) return true; // We're already in a consistent state.
4356 if (hashHeads.size() != 2) return error("ReplayBlocks(): unknown inconsistent state");
4357
4358 uiInterface.ShowProgress(_("Replaying blocks..."), 0, false);
4359 LogPrintf("Replaying blocks\n");
4360
4361 const CBlockIndex* pindexOld = nullptr; // Old tip during the interrupted flush.
4362 const CBlockIndex* pindexNew; // New tip during the interrupted flush.
4363 const CBlockIndex* pindexFork = nullptr; // Latest block common to both the old and the new tip.
4364
4365 if (mapBlockIndex.count(hashHeads[0]) == 0) {
4366 return error("ReplayBlocks(): reorganization to unknown block requested");
4367 }
4368 pindexNew = mapBlockIndex[hashHeads[0]];
4369
4370 if (!hashHeads[1].IsNull()) { // The old tip is allowed to be 0, indicating it's the first flush.
4371 if (mapBlockIndex.count(hashHeads[1]) == 0) {
4372 return error("ReplayBlocks(): reorganization from unknown block requested");
4373 }
4374 pindexOld = mapBlockIndex[hashHeads[1]];
4375 pindexFork = LastCommonAncestor(pindexOld, pindexNew);
4376 assert(pindexFork != nullptr);
4377 }
4378
4379 // Rollback along the old branch.
4380 while (pindexOld != pindexFork) {
4381 if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
4382 CBlock block;
4383 if (!ReadBlockFromDisk(block, pindexOld, params.GetConsensus())) {
4384 return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
4385 }
4386 LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
4387 DisconnectResult res = DisconnectBlock(block, pindexOld, cache);
4388 if (res == DISCONNECT_FAILED) {
4389 return error("RollbackBlock(): DisconnectBlock failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
4390 }
4391 // If DISCONNECT_UNCLEAN is returned, it means a non-existing UTXO was deleted, or an existing UTXO was
4392 // overwritten. It corresponds to cases where the block-to-be-disconnect never had all its operations
4393 // applied to the UTXO set. However, as both writing a UTXO and deleting a UTXO are idempotent operations,
4394 // the result is still a version of the UTXO set with the effects of that block undone.
4395 }
4396 pindexOld = pindexOld->pprev;
4397 }
4398
4399 // Roll forward from the forking point to the new tip.
4400 int nForkHeight = pindexFork ? pindexFork->nHeight : 0;
4401 for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; ++nHeight) {
4402 const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight);
4403 LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight);
4404 if (!RollforwardBlock(pindex, cache, params)) return false;
4405 }

Callers 1

ReplayBlocksFunction · 0.80

Calls 14

errorFunction · 0.85
_Function · 0.85
LastCommonAncestorFunction · 0.85
ReadBlockFromDiskFunction · 0.85
GetAncestorMethod · 0.80
SetBestBlockMethod · 0.80
GetHeadBlocksMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45
countMethod · 0.45
IsNullMethod · 0.45
ToStringMethod · 0.45

Tested by

no test coverage detected