Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,438 Lines • ▼ Show 20 Lines | LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", | ||||
log(tip->nChainWork.getdouble()) / log(2.0), | log(tip->nChainWork.getdouble()) / log(2.0), | ||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime())); | DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime())); | ||||
CheckForkWarningConditions(); | CheckForkWarningConditions(); | ||||
} | } | ||||
static void InvalidBlockFound(CBlockIndex *pindex, | static void InvalidBlockFound(CBlockIndex *pindex, | ||||
const CValidationState &state) { | const CValidationState &state) { | ||||
if (!state.CorruptionPossible()) { | if (!state.CorruptionPossible()) { | ||||
pindex->nStatus |= BLOCK_FAILED_VALID; | pindex->nStatus = pindex->nStatus.withFailed(); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
setBlockIndexCandidates.erase(pindex); | setBlockIndexCandidates.erase(pindex); | ||||
InvalidChainFound(pindex); | InvalidChainFound(pindex); | ||||
} | } | ||||
} | } | ||||
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, | void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, | ||||
CTxUndo &txundo, int nHeight) { | CTxUndo &txundo, int nHeight) { | ||||
▲ Show 20 Lines • Show All 843 Lines • ▼ Show 20 Lines | if (pindex->GetUndoPos().IsNull() || | ||||
} | } | ||||
if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), | if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), | ||||
config.GetChainParams().DiskMagic())) { | config.GetChainParams().DiskMagic())) { | ||||
return AbortNode(state, "Failed to write undo data"); | return AbortNode(state, "Failed to write undo data"); | ||||
} | } | ||||
// update nUndoPos in block index | // update nUndoPos in block index | ||||
pindex->nUndoPos = _pos.nPos; | pindex->nUndoPos = _pos.nPos; | ||||
pindex->nStatus |= BLOCK_HAVE_UNDO; | pindex->nStatus = pindex->nStatus.withUndo(); | ||||
} | } | ||||
pindex->RaiseValidity(BlockValidity::SCRIPTS); | pindex->RaiseValidity(BlockValidity::SCRIPTS); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
if (fTxIndex && !pblocktree->WriteTxIndex(vPos)) { | if (fTxIndex && !pblocktree->WriteTxIndex(vPos)) { | ||||
return AbortNode(state, "Failed to write transaction index"); | return AbortNode(state, "Failed to write transaction index"); | ||||
▲ Show 20 Lines • Show All 567 Lines • ▼ Show 20 Lines | do { | ||||
(pindexBestInvalid == nullptr || | (pindexBestInvalid == nullptr || | ||||
pindexNew->nChainWork > pindexBestInvalid->nChainWork)) { | pindexNew->nChainWork > pindexBestInvalid->nChainWork)) { | ||||
pindexBestInvalid = pindexNew; | pindexBestInvalid = pindexNew; | ||||
} | } | ||||
CBlockIndex *pindexFailed = pindexNew; | CBlockIndex *pindexFailed = pindexNew; | ||||
// Remove the entire chain from the set. | // Remove the entire chain from the set. | ||||
while (pindexTest != pindexFailed) { | while (pindexTest != pindexFailed) { | ||||
if (fInvalidChain) { | if (fInvalidChain) { | ||||
pindexFailed->nStatus |= BLOCK_FAILED_CHILD; | pindexFailed->nStatus = | ||||
pindexFailed->nStatus.withFailedParent(); | |||||
} else if (fMissingData) { | } else if (fMissingData) { | ||||
// If we're missing data, then add back to | // If we're missing data, then add back to | ||||
// mapBlocksUnlinked, so that if the block arrives in | // mapBlocksUnlinked, so that if the block arrives in | ||||
// the future we can try adding to | // the future we can try adding to | ||||
// setBlockIndexCandidates again. | // setBlockIndexCandidates again. | ||||
mapBlocksUnlinked.insert( | mapBlocksUnlinked.insert( | ||||
std::make_pair(pindexFailed->pprev, pindexFailed)); | std::make_pair(pindexFailed->pprev, pindexFailed)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | bool PreciousBlock(const Config &config, CValidationState &state, | ||||
return ActivateBestChain(config, state); | return ActivateBestChain(config, state); | ||||
} | } | ||||
bool InvalidateBlock(const Config &config, CValidationState &state, | bool InvalidateBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// Mark the block itself as invalid. | // Mark the block itself as invalid. | ||||
pindex->nStatus |= BLOCK_FAILED_VALID; | pindex->nStatus = pindex->nStatus.withFailed(); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
setBlockIndexCandidates.erase(pindex); | setBlockIndexCandidates.erase(pindex); | ||||
DisconnectedBlockTransactions disconnectpool; | DisconnectedBlockTransactions disconnectpool; | ||||
while (chainActive.Contains(pindex)) { | while (chainActive.Contains(pindex)) { | ||||
CBlockIndex *pindexWalk = chainActive.Tip(); | CBlockIndex *pindexWalk = chainActive.Tip(); | ||||
pindexWalk->nStatus |= BLOCK_FAILED_CHILD; | pindexWalk->nStatus = pindexWalk->nStatus.withFailedParent(); | ||||
setDirtyBlockIndex.insert(pindexWalk); | setDirtyBlockIndex.insert(pindexWalk); | ||||
setBlockIndexCandidates.erase(pindexWalk); | setBlockIndexCandidates.erase(pindexWalk); | ||||
// ActivateBestChain considers blocks already in chainActive | // ActivateBestChain considers blocks already in chainActive | ||||
// unconditionally valid already, so force disconnect away from it. | // unconditionally valid already, so force disconnect away from it. | ||||
if (!DisconnectTip(config, state, &disconnectpool)) { | if (!DisconnectTip(config, state, &disconnectpool)) { | ||||
// It's probably hopeless to try to make the mempool consistent | // It's probably hopeless to try to make the mempool consistent | ||||
// here if DisconnectTip failed, but we can try. | // here if DisconnectTip failed, but we can try. | ||||
UpdateMempoolForReorg(config, disconnectpool, false); | UpdateMempoolForReorg(config, disconnectpool, false); | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const CDiskBlockPos &pos) { | const CDiskBlockPos &pos) { | ||||
pindexNew->nTx = block.vtx.size(); | pindexNew->nTx = block.vtx.size(); | ||||
pindexNew->nChainTx = 0; | pindexNew->nChainTx = 0; | ||||
pindexNew->nFile = pos.nFile; | pindexNew->nFile = pos.nFile; | ||||
pindexNew->nDataPos = pos.nPos; | pindexNew->nDataPos = pos.nPos; | ||||
pindexNew->nUndoPos = 0; | pindexNew->nUndoPos = 0; | ||||
pindexNew->nStatus |= BLOCK_HAVE_DATA; | pindexNew->nStatus = pindexNew->nStatus.withData(); | ||||
pindexNew->RaiseValidity(BlockValidity::TRANSACTIONS); | pindexNew->RaiseValidity(BlockValidity::TRANSACTIONS); | ||||
setDirtyBlockIndex.insert(pindexNew); | setDirtyBlockIndex.insert(pindexNew); | ||||
if (pindexNew->pprev == nullptr || pindexNew->pprev->nChainTx) { | if (pindexNew->pprev == nullptr || pindexNew->pprev->nChainTx) { | ||||
// If pindexNew is the genesis block or all parents are | // If pindexNew is the genesis block or all parents are | ||||
// BLOCK_VALID_TRANSACTIONS. | // BLOCK_VALID_TRANSACTIONS. | ||||
std::deque<CBlockIndex *> queue; | std::deque<CBlockIndex *> queue; | ||||
queue.push_back(pindexNew); | queue.push_back(pindexNew); | ||||
▲ Show 20 Lines • Show All 630 Lines • ▼ Show 20 Lines | static bool AcceptBlock(const Config &config, | ||||
if (fNewBlock) { | if (fNewBlock) { | ||||
*fNewBlock = true; | *fNewBlock = true; | ||||
} | } | ||||
if (!CheckBlock(config, block, state) || | if (!CheckBlock(config, block, state) || | ||||
!ContextualCheckBlock(config, block, state, pindex->pprev)) { | !ContextualCheckBlock(config, block, state, pindex->pprev)) { | ||||
if (state.IsInvalid() && !state.CorruptionPossible()) { | if (state.IsInvalid() && !state.CorruptionPossible()) { | ||||
pindex->nStatus |= BLOCK_FAILED_VALID; | pindex->nStatus = pindex->nStatus.withFailed(); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
return error("%s: %s (block %s)", __func__, FormatStateMessage(state), | return error("%s: %s (block %s)", __func__, FormatStateMessage(state), | ||||
block.GetHash().ToString()); | block.GetHash().ToString()); | ||||
} | } | ||||
// Header is valid/has work and the merkle tree is good. | // Header is valid/has work and the merkle tree is good. | ||||
// Relay now, but if it does not build on our best tip, let the | // Relay now, but if it does not build on our best tip, let the | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Prune a block file (modify associated database entries) | * Prune a block file (modify associated database entries) | ||||
*/ | */ | ||||
void PruneOneBlockFile(const int fileNumber) { | void PruneOneBlockFile(const int fileNumber) { | ||||
for (const std::pair<const uint256, CBlockIndex *> &it : mapBlockIndex) { | for (const std::pair<const uint256, CBlockIndex *> &it : mapBlockIndex) { | ||||
CBlockIndex *pindex = it.second; | CBlockIndex *pindex = it.second; | ||||
if (pindex->nFile == fileNumber) { | if (pindex->nFile == fileNumber) { | ||||
pindex->nStatus &= ~BLOCK_HAVE_DATA; | pindex->nStatus = pindex->nStatus.withData(false).withUndo(false); | ||||
pindex->nStatus &= ~BLOCK_HAVE_UNDO; | |||||
pindex->nFile = 0; | pindex->nFile = 0; | ||||
pindex->nDataPos = 0; | pindex->nDataPos = 0; | ||||
pindex->nUndoPos = 0; | pindex->nUndoPos = 0; | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
// Prune from mapBlocksUnlinked -- any block we prune would have | // Prune from mapBlocksUnlinked -- any block we prune would have | ||||
// to be downloaded again in order to consider its chain, at which | // to be downloaded again in order to consider its chain, at which | ||||
// point it would be considered as a candidate for | // point it would be considered as a candidate for | ||||
▲ Show 20 Lines • Show All 1,408 Lines • Show Last 20 Lines |