Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 225 Lines • ▼ Show 20 Lines | private: | ||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const FlatFilePos &pos) | const FlatFilePos &pos) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | ||||
const Consensus::Params ¶ms) | const Consensus::Params ¶ms) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
//! Mark a block as not having block data | |||||
void EraseBlockData(CBlockIndex *index) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
} g_chainstate; | } g_chainstate; | ||||
/** | /** | ||||
* Global state | * Global state | ||||
* | * | ||||
* Mutex to guard access to validation specific variables, such as reading | * Mutex to guard access to validation specific variables, such as reading | ||||
* or changing the chainstate. | * or changing the chainstate. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 4,695 Lines • ▼ Show 20 Lines | bool CChainState::ReplayBlocks(const Consensus::Params ¶ms, | ||||
uiInterface.ShowProgress("", 100, false); | uiInterface.ShowProgress("", 100, false); | ||||
return true; | return true; | ||||
} | } | ||||
bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view) { | bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view) { | ||||
return g_chainstate.ReplayBlocks(params, view); | return g_chainstate.ReplayBlocks(params, view); | ||||
} | } | ||||
//! Helper for CChainState::RewindBlockIndex | |||||
void CChainState::EraseBlockData(CBlockIndex *index) { | |||||
AssertLockHeld(cs_main); | |||||
assert(!chainActive.Contains(index)); // Make sure this block isn't active | |||||
// Reduce validity | |||||
index->nStatus = index->nStatus.withValidity( | |||||
std::min(index->nStatus.getValidity(), BlockValidity::TREE)); | |||||
// Remove have-data flags. | |||||
index->nStatus = index->nStatus.withData(false).withUndo(false); | |||||
// Remove storage location. | |||||
index->nFile = 0; | |||||
index->nDataPos = 0; | |||||
index->nUndoPos = 0; | |||||
// Remove various other things | |||||
index->nTx = 0; | |||||
index->nChainTx = 0; | |||||
index->nSequenceId = 0; | |||||
// Make sure it gets written. | |||||
setDirtyBlockIndex.insert(index); | |||||
// Update indexes | |||||
setBlockIndexCandidates.erase(index); | |||||
std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator, | |||||
std::multimap<CBlockIndex *, CBlockIndex *>::iterator> | |||||
ret = mapBlocksUnlinked.equal_range(index->pprev); | |||||
while (ret.first != ret.second) { | |||||
if (ret.first->second == index) { | |||||
mapBlocksUnlinked.erase(ret.first++); | |||||
} else { | |||||
++ret.first; | |||||
} | |||||
} | |||||
// Mark parent as eligible for main chain again | |||||
if (index->pprev && index->pprev->IsValid(BlockValidity::TRANSACTIONS) && | |||||
index->pprev->HaveTxsDownloaded()) { | |||||
setBlockIndexCandidates.insert(index->pprev); | |||||
} | |||||
} | |||||
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; | ||||
// nHeight is now the height of the first insufficiently-validated block, or | // nHeight is now the height of the first insufficiently-validated block, or | ||||
// tipheight + 1 | // tipheight + 1 | ||||
Show All 23 Lines | bool CChainState::RewindBlockIndex(const Config &config) { | ||||
} | } | ||||
// Reduce validity flag and have-data flags. | // Reduce validity flag and have-data flags. | ||||
// We do this after actual disconnecting, otherwise we'll end up writing the | // We do this after actual disconnecting, otherwise we'll end up writing the | ||||
// lack of data to disk before writing the chainstate, resulting in a | // lack of data to disk before writing the chainstate, resulting in a | ||||
// failure to continue if interrupted. | // failure to continue if interrupted. | ||||
for (const auto &entry : mapBlockIndex) { | for (const auto &entry : mapBlockIndex) { | ||||
CBlockIndex *pindexIter = entry.second; | CBlockIndex *pindexIter = entry.second; | ||||
if (pindexIter->IsValid(BlockValidity::TRANSACTIONS) && | |||||
pindexIter->HaveTxsDownloaded()) { | // Note: If we encounter an insufficiently validated block that | ||||
setBlockIndexCandidates.insert(pindexIter); | // is on chainActive, it must be because we are a pruning node, and | ||||
// this block or some successor doesn't HAVE_DATA, so we were unable to | |||||
// rewind all the way. Blocks remaining on chainActive at this point | |||||
// must not have their validity reduced. | |||||
if (!chainActive.Contains(pindexIter)) { | |||||
EraseBlockData(pindexIter); | |||||
deadalnix: Why would you erase the block data of every blocks that is not in the chain active? That… | |||||
} | } | ||||
} | } | ||||
if (chainActive.Tip() != nullptr) { | if (chainActive.Tip() != nullptr) { | ||||
// We can't prune block index candidates based on our tip if we have | // We can't prune block index candidates based on our tip if we have | ||||
// no tip due to chainActive being empty! | // no tip due to chainActive being empty! | ||||
PruneBlockIndexCandidates(); | PruneBlockIndexCandidates(); | ||||
▲ Show 20 Lines • Show All 803 Lines • Show Last 20 Lines |
Why would you erase the block data of every blocks that is not in the chain active? That doesn't seems to make any sense to me, and I strongly suspect this has something to do with the test suite being broken. However, I was unable to figure any of the teamcity shit out so idk what's actually broken.