Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | public: | ||||
template <typename F> | template <typename F> | ||||
void UpdateFlagsForBlock(CBlockIndex *pindexBase, CBlockIndex *pindex, F f); | void UpdateFlagsForBlock(CBlockIndex *pindexBase, CBlockIndex *pindex, F f); | ||||
template <typename F, typename C> | template <typename F, typename C> | ||||
void UpdateFlags(CBlockIndex *pindex, F f, C fchild); | void UpdateFlags(CBlockIndex *pindex, F f, C fchild); | ||||
template <typename F> void UpdateFlags(CBlockIndex *pindex, F f); | template <typename F> void UpdateFlags(CBlockIndex *pindex, F f); | ||||
/** Remove parked status from a block and its descendants. */ | /** Remove parked status from a block and its descendants. */ | ||||
bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren); | bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren); | ||||
bool ReplayBlocks(const Config &config, CCoinsView *view); | bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view); | ||||
bool RewindBlockIndex(const Config &config); | bool RewindBlockIndex(const Config &config); | ||||
bool LoadGenesisBlock(const CChainParams &chainparams); | bool LoadGenesisBlock(const CChainParams &chainparams); | ||||
void PruneBlockIndexCandidates(); | void PruneBlockIndexCandidates(); | ||||
void UnloadBlockIndex(); | void UnloadBlockIndex(); | ||||
private: | private: | ||||
Show All 14 Lines | private: | ||||
void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state); | void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state); | ||||
CBlockIndex *FindMostWorkChain(); | CBlockIndex *FindMostWorkChain(); | ||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const FlatFilePos &pos); | const FlatFilePos &pos); | ||||
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | ||||
const Config &config); | const Consensus::Params ¶ms); | ||||
} g_chainstate; | } g_chainstate; | ||||
/** | /** | ||||
* Global state | * Global state | ||||
*/ | */ | ||||
CCriticalSection cs_main; | CCriticalSection cs_main; | ||||
BlockMap &mapBlockIndex = g_chainstate.mapBlockIndex; | BlockMap &mapBlockIndex = g_chainstate.mapBlockIndex; | ||||
▲ Show 20 Lines • Show All 640 Lines • ▼ Show 20 Lines | return AcceptToMemoryPoolWithTime( | ||||
fOverrideMempoolLimit, nAbsurdFee, test_accept); | fOverrideMempoolLimit, nAbsurdFee, test_accept); | ||||
} | } | ||||
/** | /** | ||||
* Return transaction in txOut, and if it was found inside a block, its hash is | * Return transaction in txOut, and if it was found inside a block, its hash is | ||||
* placed in hashBlock. If blockIndex is provided, the transaction is fetched | * placed in hashBlock. If blockIndex is provided, the transaction is fetched | ||||
* from the corresponding block. | * from the corresponding block. | ||||
*/ | */ | ||||
bool GetTransaction(const Config &config, const TxId &txid, | bool GetTransaction(const Consensus::Params ¶ms, const TxId &txid, | ||||
CTransactionRef &txOut, uint256 &hashBlock, bool fAllowSlow, | CTransactionRef &txOut, uint256 &hashBlock, bool fAllowSlow, | ||||
CBlockIndex *blockIndex) { | CBlockIndex *blockIndex) { | ||||
CBlockIndex *pindexSlow = blockIndex; | CBlockIndex *pindexSlow = blockIndex; | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (!blockIndex) { | if (!blockIndex) { | ||||
CTransactionRef ptx = g_mempool.get(txid); | CTransactionRef ptx = g_mempool.get(txid); | ||||
Show All 13 Lines | if (!blockIndex) { | ||||
if (!coin.IsSpent()) { | if (!coin.IsSpent()) { | ||||
pindexSlow = chainActive[coin.GetHeight()]; | pindexSlow = chainActive[coin.GetHeight()]; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (pindexSlow) { | if (pindexSlow) { | ||||
CBlock block; | CBlock block; | ||||
if (ReadBlockFromDisk(block, pindexSlow, config)) { | if (ReadBlockFromDisk(block, pindexSlow, params)) { | ||||
for (const auto &tx : block.vtx) { | for (const auto &tx : block.vtx) { | ||||
if (tx->GetId() == txid) { | if (tx->GetId() == txid) { | ||||
txOut = tx; | txOut = tx; | ||||
hashBlock = pindexSlow->GetBlockHash(); | hashBlock = pindexSlow->GetBlockHash(); | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
Show All 27 Lines | static bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, | ||||
pos.nPos = (unsigned int)fileOutPos; | pos.nPos = (unsigned int)fileOutPos; | ||||
fileout << block; | fileout << block; | ||||
return true; | return true; | ||||
} | } | ||||
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, | bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, | ||||
const Config &config) { | const Consensus::Params ¶ms) { | ||||
block.SetNull(); | block.SetNull(); | ||||
// Open history file to read | // Open history file to read | ||||
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); | CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); | ||||
if (filein.IsNull()) { | if (filein.IsNull()) { | ||||
return error("ReadBlockFromDisk: OpenBlockFile failed for %s", | return error("ReadBlockFromDisk: OpenBlockFile failed for %s", | ||||
pos.ToString()); | pos.ToString()); | ||||
} | } | ||||
// Read block | // Read block | ||||
try { | try { | ||||
filein >> block; | filein >> block; | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
return error("%s: Deserialize or I/O error - %s at %s", __func__, | return error("%s: Deserialize or I/O error - %s at %s", __func__, | ||||
e.what(), pos.ToString()); | e.what(), pos.ToString()); | ||||
} | } | ||||
// Check the header | // Check the header | ||||
if (!CheckProofOfWork(block.GetHash(), block.nBits, | if (!CheckProofOfWork(block.GetHash(), block.nBits, params)) { | ||||
config.GetChainParams().GetConsensus())) { | |||||
return error("ReadBlockFromDisk: Errors in block header at %s", | return error("ReadBlockFromDisk: Errors in block header at %s", | ||||
pos.ToString()); | pos.ToString()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool ReadBlockFromDisk(CBlock &block, const CBlockIndex *pindex, | bool ReadBlockFromDisk(CBlock &block, const CBlockIndex *pindex, | ||||
const Config &config) { | const Consensus::Params ¶ms) { | ||||
FlatFilePos blockPos; | FlatFilePos blockPos; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
blockPos = pindex->GetBlockPos(); | blockPos = pindex->GetBlockPos(); | ||||
} | } | ||||
if (!ReadBlockFromDisk(block, blockPos, config)) { | if (!ReadBlockFromDisk(block, blockPos, params)) { | ||||
return false; | return false; | ||||
} | } | ||||
if (block.GetHash() != pindex->GetBlockHash()) { | if (block.GetHash() != pindex->GetBlockHash()) { | ||||
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() " | return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() " | ||||
"doesn't match index for %s at %s", | "doesn't match index for %s at %s", | ||||
pindex->ToString(), pindex->GetBlockPos().ToString()); | pindex->ToString(), pindex->GetBlockPos().ToString()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,213 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* If disconnectpool is nullptr, then no disconnected transactions are added to | * If disconnectpool is nullptr, then no disconnected transactions are added to | ||||
* disconnectpool (note that the caller is responsible for mempool consistency | * disconnectpool (note that the caller is responsible for mempool consistency | ||||
* in any case). | * in any case). | ||||
*/ | */ | ||||
bool CChainState::DisconnectTip(const Config &config, CValidationState &state, | bool CChainState::DisconnectTip(const Config &config, CValidationState &state, | ||||
DisconnectedBlockTransactions *disconnectpool) { | DisconnectedBlockTransactions *disconnectpool) { | ||||
CBlockIndex *pindexDelete = chainActive.Tip(); | CBlockIndex *pindexDelete = chainActive.Tip(); | ||||
const Consensus::Params &consensusParams = | |||||
config.GetChainParams().GetConsensus(); | |||||
assert(pindexDelete); | assert(pindexDelete); | ||||
// Read block from disk. | // Read block from disk. | ||||
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); | std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); | ||||
CBlock &block = *pblock; | CBlock &block = *pblock; | ||||
if (!ReadBlockFromDisk(block, pindexDelete, config)) { | if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) { | ||||
return AbortNode(state, "Failed to read block"); | return AbortNode(state, "Failed to read block"); | ||||
} | } | ||||
// Apply the block atomically to the chain state. | // Apply the block atomically to the chain state. | ||||
int64_t nStart = GetTimeMicros(); | int64_t nStart = GetTimeMicros(); | ||||
{ | { | ||||
CCoinsViewCache view(pcoinsTip.get()); | CCoinsViewCache view(pcoinsTip.get()); | ||||
assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); | assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); | ||||
Show All 10 Lines | LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", | ||||
(GetTimeMicros() - nStart) * MILLI); | (GetTimeMicros() - nStart) * MILLI); | ||||
// Write the chain state to disk, if necessary. | // Write the chain state to disk, if necessary. | ||||
if (!FlushStateToDisk(config.GetChainParams(), state, | if (!FlushStateToDisk(config.GetChainParams(), state, | ||||
FlushStateMode::IF_NEEDED)) { | FlushStateMode::IF_NEEDED)) { | ||||
return false; | return false; | ||||
} | } | ||||
const Consensus::Params &consensusParams = | |||||
config.GetChainParams().GetConsensus(); | |||||
// If this block is deactivating a fork, we move all mempool transactions | // If this block is deactivating a fork, we move all mempool transactions | ||||
// in front of disconnectpool for reprocessing in a future | // in front of disconnectpool for reprocessing in a future | ||||
// updateMempoolForReorg call | // updateMempoolForReorg call | ||||
if (pindexDelete->pprev != nullptr && | if (pindexDelete->pprev != nullptr && | ||||
GetNextBlockScriptFlags(consensusParams, pindexDelete) != | GetNextBlockScriptFlags(consensusParams, pindexDelete) != | ||||
GetNextBlockScriptFlags(consensusParams, pindexDelete->pprev)) { | GetNextBlockScriptFlags(consensusParams, pindexDelete->pprev)) { | ||||
LogPrint(BCLog::MEMPOOL, | LogPrint(BCLog::MEMPOOL, | ||||
"Disconnecting mempool due to rewind of upgrade block\n"); | "Disconnecting mempool due to rewind of upgrade block\n"); | ||||
▲ Show 20 Lines • Show All 188 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
bool CChainState::ConnectTip(const Config &config, CValidationState &state, | bool CChainState::ConnectTip(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
ConnectTrace &connectTrace, | ConnectTrace &connectTrace, | ||||
DisconnectedBlockTransactions &disconnectpool) { | DisconnectedBlockTransactions &disconnectpool) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const Consensus::Params &consensusParams = | |||||
config.GetChainParams().GetConsensus(); | |||||
assert(pindexNew->pprev == chainActive.Tip()); | assert(pindexNew->pprev == chainActive.Tip()); | ||||
// Read block from disk. | // Read block from disk. | ||||
int64_t nTime1 = GetTimeMicros(); | int64_t nTime1 = GetTimeMicros(); | ||||
std::shared_ptr<const CBlock> pthisBlock; | std::shared_ptr<const CBlock> pthisBlock; | ||||
if (!pblock) { | if (!pblock) { | ||||
std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); | std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); | ||||
if (!ReadBlockFromDisk(*pblockNew, pindexNew, config)) { | if (!ReadBlockFromDisk(*pblockNew, pindexNew, consensusParams)) { | ||||
return AbortNode(state, "Failed to read block"); | return AbortNode(state, "Failed to read block"); | ||||
} | } | ||||
pthisBlock = pblockNew; | pthisBlock = pblockNew; | ||||
} else { | } else { | ||||
pthisBlock = pblock; | pthisBlock = pblock; | ||||
} | } | ||||
const CBlock &blockConnecting = *pthisBlock; | const CBlock &blockConnecting = *pthisBlock; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | LogPrint(BCLog::BENCH, | ||||
" - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", | " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", | ||||
(nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, | (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, | ||||
nTimeChainState * MILLI / nBlocksTotal); | nTimeChainState * MILLI / nBlocksTotal); | ||||
// Remove conflicting transactions from the mempool.; | // Remove conflicting transactions from the mempool.; | ||||
g_mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight); | g_mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight); | ||||
disconnectpool.removeForBlock(blockConnecting.vtx); | disconnectpool.removeForBlock(blockConnecting.vtx); | ||||
const Consensus::Params &consensusParams = | |||||
config.GetChainParams().GetConsensus(); | |||||
// If this block is activating a fork, we move all mempool transactions | // If this block is activating a fork, we move all mempool transactions | ||||
// in front of disconnectpool for reprocessing in a future | // in front of disconnectpool for reprocessing in a future | ||||
// updateMempoolForReorg call | // updateMempoolForReorg call | ||||
if (pindexNew->pprev != nullptr && | if (pindexNew->pprev != nullptr && | ||||
GetNextBlockScriptFlags(consensusParams, pindexNew) != | GetNextBlockScriptFlags(consensusParams, pindexNew) != | ||||
GetNextBlockScriptFlags(consensusParams, pindexNew->pprev)) { | GetNextBlockScriptFlags(consensusParams, pindexNew->pprev)) { | ||||
LogPrint(BCLog::MEMPOOL, | LogPrint(BCLog::MEMPOOL, | ||||
"Disconnecting mempool due to acceptance of upgrade block\n"); | "Disconnecting mempool due to acceptance of upgrade block\n"); | ||||
▲ Show 20 Lines • Show All 2,045 Lines • ▼ Show 20 Lines | |||||
CVerifyDB::~CVerifyDB() { | CVerifyDB::~CVerifyDB() { | ||||
uiInterface.ShowProgress("", 100, false); | uiInterface.ShowProgress("", 100, false); | ||||
} | } | ||||
bool CVerifyDB::VerifyDB(const Config &config, CCoinsView *coinsview, | bool CVerifyDB::VerifyDB(const Config &config, CCoinsView *coinsview, | ||||
int nCheckLevel, int nCheckDepth) { | int nCheckLevel, int nCheckDepth) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const Consensus::Params &consensusParams = | |||||
config.GetChainParams().GetConsensus(); | |||||
if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr) { | if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr) { | ||||
return true; | return true; | ||||
} | } | ||||
// Verify blocks in the best chain | // Verify blocks in the best chain | ||||
if (nCheckDepth <= 0 || nCheckDepth > chainActive.Height()) { | if (nCheckDepth <= 0 || nCheckDepth > chainActive.Height()) { | ||||
nCheckDepth = chainActive.Height(); | nCheckDepth = chainActive.Height(); | ||||
} | } | ||||
Show All 36 Lines | for (CBlockIndex *pindex = chainActive.Tip(); pindex && pindex->pprev; | ||||
"(pruning, no data)\n", | "(pruning, no data)\n", | ||||
pindex->nHeight); | pindex->nHeight); | ||||
break; | break; | ||||
} | } | ||||
CBlock block; | CBlock block; | ||||
// check level 0: read from disk | // check level 0: read from disk | ||||
if (!ReadBlockFromDisk(block, pindex, config)) { | if (!ReadBlockFromDisk(block, pindex, consensusParams)) { | ||||
return error( | return error( | ||||
"VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", | "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
} | } | ||||
// check level 1: verify block validity | // check level 1: verify block validity | ||||
if (nCheckLevel >= 1 && !CheckBlock(config, block, state)) { | if (nCheckLevel >= 1 && !CheckBlock(config, block, state)) { | ||||
return error("%s: *** found bad block at %d, hash=%s (%s)\n", | return error("%s: *** found bad block at %d, hash=%s (%s)\n", | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | if (nCheckLevel >= 4) { | ||||
_("Verifying blocks..."), | _("Verifying blocks..."), | ||||
std::max( | std::max( | ||||
1, std::min(99, 100 - (int)(((double)(chainActive.Height() - | 1, std::min(99, 100 - (int)(((double)(chainActive.Height() - | ||||
pindex->nHeight)) / | pindex->nHeight)) / | ||||
(double)nCheckDepth * 50))), | (double)nCheckDepth * 50))), | ||||
false); | false); | ||||
pindex = chainActive.Next(pindex); | pindex = chainActive.Next(pindex); | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pindex, config)) { | if (!ReadBlockFromDisk(block, pindex, consensusParams)) { | ||||
return error( | return error( | ||||
"VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", | "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
} | } | ||||
if (!g_chainstate.ConnectBlock(config, block, state, pindex, | if (!g_chainstate.ConnectBlock(config, block, state, pindex, | ||||
coins)) { | coins)) { | ||||
return error("VerifyDB(): *** found unconnectable block at %d, " | return error("VerifyDB(): *** found unconnectable block at %d, " | ||||
"hash=%s (%s)", | "hash=%s (%s)", | ||||
Show All 12 Lines | |||||
} | } | ||||
/** | /** | ||||
* Apply the effects of a block on the utxo cache, ignoring that it may already | * Apply the effects of a block on the utxo cache, ignoring that it may already | ||||
* have been applied. | * have been applied. | ||||
*/ | */ | ||||
bool CChainState::RollforwardBlock(const CBlockIndex *pindex, | bool CChainState::RollforwardBlock(const CBlockIndex *pindex, | ||||
CCoinsViewCache &view, | CCoinsViewCache &view, | ||||
const Config &config) { | const Consensus::Params ¶ms) { | ||||
// TODO: merge with ConnectBlock | // TODO: merge with ConnectBlock | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pindex, config)) { | if (!ReadBlockFromDisk(block, pindex, params)) { | ||||
return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", | return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", | ||||
pindex->nHeight, pindex->GetBlockHash().ToString()); | pindex->nHeight, pindex->GetBlockHash().ToString()); | ||||
} | } | ||||
for (const CTransactionRef &tx : block.vtx) { | for (const CTransactionRef &tx : block.vtx) { | ||||
// Pass check = true as every addition may be an overwrite. | // Pass check = true as every addition may be an overwrite. | ||||
AddCoins(view, *tx, pindex->nHeight, true); | AddCoins(view, *tx, pindex->nHeight, true); | ||||
} | } | ||||
for (const CTransactionRef &tx : block.vtx) { | for (const CTransactionRef &tx : block.vtx) { | ||||
if (tx->IsCoinBase()) { | if (tx->IsCoinBase()) { | ||||
continue; | continue; | ||||
} | } | ||||
for (const CTxIn &txin : tx->vin) { | for (const CTxIn &txin : tx->vin) { | ||||
view.SpendCoin(txin.prevout); | view.SpendCoin(txin.prevout); | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CChainState::ReplayBlocks(const Config &config, CCoinsView *view) { | bool CChainState::ReplayBlocks(const Consensus::Params ¶ms, | ||||
CCoinsView *view) { | |||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CCoinsViewCache cache(view); | CCoinsViewCache cache(view); | ||||
std::vector<uint256> hashHeads = view->GetHeadBlocks(); | std::vector<uint256> hashHeads = view->GetHeadBlocks(); | ||||
if (hashHeads.empty()) { | if (hashHeads.empty()) { | ||||
// We're already in a consistent state. | // We're already in a consistent state. | ||||
return true; | return true; | ||||
Show All 32 Lines | if (!hashHeads[1].IsNull()) { | ||||
assert(pindexFork != nullptr); | assert(pindexFork != nullptr); | ||||
} | } | ||||
// Rollback along the old branch. | // Rollback along the old branch. | ||||
while (pindexOld != pindexFork) { | while (pindexOld != pindexFork) { | ||||
if (pindexOld->nHeight > 0) { | if (pindexOld->nHeight > 0) { | ||||
// Never disconnect the genesis block. | // Never disconnect the genesis block. | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pindexOld, config)) { | if (!ReadBlockFromDisk(block, pindexOld, params)) { | ||||
return error("RollbackBlock(): ReadBlockFromDisk() failed at " | return error("RollbackBlock(): ReadBlockFromDisk() failed at " | ||||
"%d, hash=%s", | "%d, hash=%s", | ||||
pindexOld->nHeight, | pindexOld->nHeight, | ||||
pindexOld->GetBlockHash().ToString()); | pindexOld->GetBlockHash().ToString()); | ||||
} | } | ||||
LogPrintf("Rolling back %s (%i)\n", | LogPrintf("Rolling back %s (%i)\n", | ||||
pindexOld->GetBlockHash().ToString(), pindexOld->nHeight); | pindexOld->GetBlockHash().ToString(), pindexOld->nHeight); | ||||
Show All 17 Lines | bool CChainState::ReplayBlocks(const Consensus::Params ¶ms, | ||||
// Roll forward from the forking point to the new tip. | // Roll forward from the forking point to the new tip. | ||||
int nForkHeight = pindexFork ? pindexFork->nHeight : 0; | int nForkHeight = pindexFork ? pindexFork->nHeight : 0; | ||||
for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; | for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; | ||||
++nHeight) { | ++nHeight) { | ||||
const CBlockIndex *pindex = pindexNew->GetAncestor(nHeight); | const CBlockIndex *pindex = pindexNew->GetAncestor(nHeight); | ||||
LogPrintf("Rolling forward %s (%i)\n", | LogPrintf("Rolling forward %s (%i)\n", | ||||
pindex->GetBlockHash().ToString(), nHeight); | pindex->GetBlockHash().ToString(), nHeight); | ||||
if (!RollforwardBlock(pindex, cache, config)) { | if (!RollforwardBlock(pindex, cache, params)) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
cache.SetBestBlock(pindexNew->GetBlockHash()); | cache.SetBestBlock(pindexNew->GetBlockHash()); | ||||
cache.Flush(); | cache.Flush(); | ||||
uiInterface.ShowProgress("", 100, false); | uiInterface.ShowProgress("", 100, false); | ||||
return true; | return true; | ||||
} | } | ||||
bool ReplayBlocks(const Config &config, CCoinsView *view) { | bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view) { | ||||
return g_chainstate.ReplayBlocks(config, view); | return g_chainstate.ReplayBlocks(params, view); | ||||
} | } | ||||
bool CChainState::RewindBlockIndex(const Config &config) { | bool CChainState::RewindBlockIndex(const Config &config) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CChainParams ¶ms = config.GetChainParams(); | const CChainParams ¶ms = config.GetChainParams(); | ||||
int nHeight = chainActive.Height() + 1; | int nHeight = chainActive.Height() + 1; | ||||
▲ Show 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | try { | ||||
std::multimap<uint256, FlatFilePos>::iterator> | std::multimap<uint256, FlatFilePos>::iterator> | ||||
range = mapBlocksUnknownParent.equal_range(head); | range = mapBlocksUnknownParent.equal_range(head); | ||||
while (range.first != range.second) { | while (range.first != range.second) { | ||||
std::multimap<uint256, FlatFilePos>::iterator it = | std::multimap<uint256, FlatFilePos>::iterator it = | ||||
range.first; | range.first; | ||||
std::shared_ptr<CBlock> pblockrecursive = | std::shared_ptr<CBlock> pblockrecursive = | ||||
std::make_shared<CBlock>(); | std::make_shared<CBlock>(); | ||||
if (ReadBlockFromDisk(*pblockrecursive, it->second, | if (ReadBlockFromDisk(*pblockrecursive, it->second, | ||||
config)) { | chainparams.GetConsensus())) { | ||||
LogPrint( | LogPrint( | ||||
BCLog::REINDEX, | BCLog::REINDEX, | ||||
"%s: Processing out of order child %s of %s\n", | "%s: Processing out of order child %s of %s\n", | ||||
__func__, pblockrecursive->GetHash().ToString(), | __func__, pblockrecursive->GetHash().ToString(), | ||||
head.ToString()); | head.ToString()); | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CValidationState dummy; | CValidationState dummy; | ||||
if (g_chainstate.AcceptBlock( | if (g_chainstate.AcceptBlock( | ||||
▲ Show 20 Lines • Show All 534 Lines • Show Last 20 Lines |