Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | private: | ||||
* The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for | * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for | ||||
* itself and all ancestors) and | * itself and all ancestors) and | ||||
* as good as our current tip or better. Entries may be failed, though, and | * as good as our current tip or better. Entries may be failed, though, and | ||||
* pruning nodes may be | * pruning nodes may be | ||||
* missing the data for the block. | * missing the data for the block. | ||||
*/ | */ | ||||
std::set<CBlockIndex *, CBlockIndexWorkComparator> setBlockIndexCandidates; | std::set<CBlockIndex *, CBlockIndexWorkComparator> setBlockIndexCandidates; | ||||
/** | |||||
* Every received block is assigned a unique and increasing identifier, so | |||||
* we | |||||
* know which one to give priority in case of a fork. | |||||
*/ | |||||
CCriticalSection cs_nBlockSequenceId; | |||||
/** Blocks loaded from disk are assigned id 0, so start the counter at 1. */ | |||||
int32_t nBlockSequenceId = 1; | |||||
/** Decreasing counter (used by subsequent preciousblock calls). */ | |||||
int32_t nBlockReverseSequenceId = -1; | |||||
/** chainwork for the last block that preciousblock has been applied to. */ | |||||
arith_uint256 nLastPreciousChainwork = 0; | |||||
/** In order to efficiently track invalidity of headers, we keep the set of | |||||
* blocks which we tried to connect and found to be invalid here (ie which | |||||
* were set to BLOCK_FAILED_VALID since the last restart). We can then | |||||
* walk this set and check if a new header is a descendant of something in | |||||
* this set, preventing us from having to walk mapBlockIndex when we try | |||||
* to connect a bad block and fail. | |||||
* | |||||
* While this is more complicated than marking everything which descends | |||||
* from an invalid block as invalid at the time we discover it to be | |||||
* invalid, doing so would require walking all of mapBlockIndex to find all | |||||
* descendants. Since this case should be very rare, keeping track of all | |||||
* BLOCK_FAILED_VALID blocks in a set should be just fine and work just as | |||||
* well. | |||||
* | |||||
* Because we already walk mapBlockIndex in height-order at startup, we go | |||||
* ahead and mark descendants of invalid blocks as FAILED_CHILD at that | |||||
* time, | |||||
* instead of putting things in this set. | |||||
*/ | |||||
std::set<CBlockIndex *> g_failed_blocks; | |||||
public: | public: | ||||
CChain chainActive; | CChain chainActive; | ||||
BlockMap mapBlockIndex; | BlockMap mapBlockIndex; | ||||
std::multimap<CBlockIndex *, CBlockIndex *> mapBlocksUnlinked; | std::multimap<CBlockIndex *, CBlockIndex *> mapBlocksUnlinked; | ||||
CBlockIndex *pindexBestInvalid = nullptr; | CBlockIndex *pindexBestInvalid = nullptr; | ||||
CBlockIndex *pindexBestParked = nullptr; | CBlockIndex *pindexBestParked = nullptr; | ||||
bool LoadBlockIndex(const Config &config, CBlockTreeDB &blocktree); | bool LoadBlockIndex(const Config &config, CBlockTreeDB &blocktree); | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
std::vector<CBlockFileInfo> vinfoBlockFile; | std::vector<CBlockFileInfo> vinfoBlockFile; | ||||
int nLastBlockFile = 0; | int nLastBlockFile = 0; | ||||
/** Global flag to indicate we should check to see if there are | /** Global flag to indicate we should check to see if there are | ||||
* block/undo files that should be deleted. Set on startup | * block/undo files that should be deleted. Set on startup | ||||
* or if we allocate more file space when we're in prune mode | * or if we allocate more file space when we're in prune mode | ||||
*/ | */ | ||||
bool fCheckForPruning = false; | bool fCheckForPruning = false; | ||||
/** | |||||
* Every received block is assigned a unique and increasing identifier, so we | |||||
* know which one to give priority in case of a fork. | |||||
*/ | |||||
CCriticalSection cs_nBlockSequenceId; | |||||
/** Blocks loaded from disk are assigned id 0, so start the counter at 1. */ | |||||
int32_t nBlockSequenceId = 1; | |||||
/** Decreasing counter (used by subsequent preciousblock calls). */ | |||||
int32_t nBlockReverseSequenceId = -1; | |||||
/** chainwork for the last block that preciousblock has been applied to. */ | |||||
arith_uint256 nLastPreciousChainwork = 0; | |||||
/** In order to efficiently track invalidity of headers, we keep the set of | |||||
* blocks which we tried to connect and found to be invalid here (ie which | |||||
* were set to BLOCK_FAILED_VALID since the last restart). We can then | |||||
* walk this set and check if a new header is a descendant of something in | |||||
* this set, preventing us from having to walk mapBlockIndex when we try | |||||
* to connect a bad block and fail. | |||||
* | |||||
* While this is more complicated than marking everything which descends | |||||
* from an invalid block as invalid at the time we discover it to be | |||||
* invalid, doing so would require walking all of mapBlockIndex to find all | |||||
* descendants. Since this case should be very rare, keeping track of all | |||||
* BLOCK_FAILED_VALID blocks in a set should be just fine and work just as | |||||
* well. | |||||
* | |||||
* Because we already walk mapBlockIndex in height-order at startup, we go | |||||
* ahead and mark descendants of invalid blocks as FAILED_CHILD at that time, | |||||
* instead of putting things in this set. | |||||
*/ | |||||
std::set<CBlockIndex *> g_failed_blocks; | |||||
/** Dirty block index entries. */ | /** Dirty block index entries. */ | ||||
std::set<CBlockIndex *> setDirtyBlockIndex; | std::set<CBlockIndex *> setDirtyBlockIndex; | ||||
/** Dirty block file entries. */ | /** Dirty block file entries. */ | ||||
std::set<int> setDirtyFileInfo; | std::set<int> setDirtyFileInfo; | ||||
} // anon namespace | } // anon namespace | ||||
CBlockIndex *FindForkInGlobalIndex(const CChain &chain, | CBlockIndex *FindForkInGlobalIndex(const CChain &chain, | ||||
▲ Show 20 Lines • Show All 4,451 Lines • ▼ Show 20 Lines | bool RewindBlockIndex(const Config &config) { | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
// May NOT be used after any connections are up as much of the peer-processing | // May NOT be used after any connections are up as much of the peer-processing | ||||
// logic assumes a consistent block index state | // logic assumes a consistent block index state | ||||
void CChainState::UnloadBlockIndex() { | void CChainState::UnloadBlockIndex() { | ||||
nBlockSequenceId = 1; | |||||
g_failed_blocks.clear(); | |||||
setBlockIndexCandidates.clear(); | setBlockIndexCandidates.clear(); | ||||
} | } | ||||
// May NOT be used after any connections are up as much | // May NOT be used after any connections are up as much | ||||
// of the peer-processing logic assumes a consistent | // of the peer-processing logic assumes a consistent | ||||
// block index state | // block index state | ||||
void UnloadBlockIndex() { | void UnloadBlockIndex() { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
chainActive.SetTip(nullptr); | chainActive.SetTip(nullptr); | ||||
pindexBestInvalid = nullptr; | pindexBestInvalid = nullptr; | ||||
pindexBestParked = nullptr; | pindexBestParked = nullptr; | ||||
pindexBestHeader = nullptr; | pindexBestHeader = nullptr; | ||||
mempool.clear(); | mempool.clear(); | ||||
mapBlocksUnlinked.clear(); | mapBlocksUnlinked.clear(); | ||||
vinfoBlockFile.clear(); | vinfoBlockFile.clear(); | ||||
nLastBlockFile = 0; | nLastBlockFile = 0; | ||||
nBlockSequenceId = 1; | |||||
setDirtyBlockIndex.clear(); | setDirtyBlockIndex.clear(); | ||||
setDirtyFileInfo.clear(); | setDirtyFileInfo.clear(); | ||||
versionbitscache.Clear(); | versionbitscache.Clear(); | ||||
for (BlockMap::value_type &entry : mapBlockIndex) { | for (BlockMap::value_type &entry : mapBlockIndex) { | ||||
delete entry.second; | delete entry.second; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 683 Lines • ▼ Show 20 Lines | try { | ||||
LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", | LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", | ||||
(mid - start) * 0.000001, (last - mid) * 0.000001); | (mid - start) * 0.000001, (last - mid) * 0.000001); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what()); | LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what()); | ||||
} | } | ||||
} | } | ||||
//! Guess how far we are in the verification process at the given block index | //! Guess how far we are in the verification process at the given block index | ||||
double GuessVerificationProgress(const ChainTxData &data, CBlockIndex *pindex) { | double GuessVerificationProgress(const ChainTxData &data, | ||||
const CBlockIndex *pindex) { | |||||
if (pindex == nullptr) { | if (pindex == nullptr) { | ||||
return 0.0; | return 0.0; | ||||
} | } | ||||
int64_t nNow = time(nullptr); | int64_t nNow = time(nullptr); | ||||
double fTxTotal; | double fTxTotal; | ||||
if (pindex->nChainTx <= data.nTxCount) { | if (pindex->nChainTx <= data.nTxCount) { | ||||
Show All 21 Lines |