diff options
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 96 |
1 files changed, 35 insertions, 61 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index 7020b59cb8..e9c0607ced 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -198,9 +198,6 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc std::unique_ptr<CBlockTreeDB> pblocktree; -// See definition for documentation -static void FindFilesToPruneManual(ChainstateManager& chainman, std::set<int>& setFilesToPrune, int nManualPruneHeight); -static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight); bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr); static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false); static FlatFileSeq BlockFileSeq(); @@ -2299,11 +2296,11 @@ bool CChainState::FlushStateToDisk( if (nManualPruneHeight > 0) { LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune (manual)", BCLog::BENCH); - FindFilesToPruneManual(g_chainman, setFilesToPrune, nManualPruneHeight); + m_blockman.FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight, m_chain.Height()); } else { LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH); - FindFilesToPrune(g_chainman, setFilesToPrune, chainparams.PruneAfterHeight()); + m_blockman.FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight(), m_chain.Height(), IsInitialBlockDownload()); fCheckForPruning = false; } if (!setFilesToPrune.empty()) { @@ -2452,9 +2449,9 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C } bilingual_str warning_messages; + int num_unexpected_version = 0; if (!::ChainstateActive().IsInitialBlockDownload()) { - int nUpgraded = 0; const CBlockIndex* pindex = pindexNew; for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { WarningBitsConditionChecker checker(bit); @@ -2473,11 +2470,9 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C { int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus()); if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0) - ++nUpgraded; + ++num_unexpected_version; pindex = pindex->pprev; } - if (nUpgraded > 0) - AppendWarning(warning_messages, strprintf(_("%d of last 100 blocks have unexpected version"), nUpgraded)); } LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion, @@ -2485,6 +2480,10 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C FormatISO8601DateTime(pindexNew->GetBlockTime()), GuessVerificationProgress(chainParams.TxData(), pindexNew), ::ChainstateActive().CoinsTip().DynamicMemoryUsage() * (1.0 / (1<<20)), ::ChainstateActive().CoinsTip().GetCacheSize(), !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages.original) : ""); + + if (num_unexpected_version > 0) { + LogPrint(BCLog::VALIDATION, "%d of last 100 blocks have unexpected version\n", num_unexpected_version); + } } /** Disconnect m_chain's tip. @@ -3909,12 +3908,12 @@ uint64_t CalculateCurrentUsage() return retval; } -void ChainstateManager::PruneOneBlockFile(const int fileNumber) +void BlockManager::PruneOneBlockFile(const int fileNumber) { AssertLockHeld(cs_main); LOCK(cs_LastBlockFile); - for (const auto& entry : m_blockman.m_block_index) { + for (const auto& entry : m_block_index) { CBlockIndex* pindex = entry.second; if (pindex->nFile == fileNumber) { pindex->nStatus &= ~BLOCK_HAVE_DATA; @@ -3928,12 +3927,12 @@ void ChainstateManager::PruneOneBlockFile(const int fileNumber) // to be downloaded again in order to consider its chain, at which // point it would be considered as a candidate for // m_blocks_unlinked or setBlockIndexCandidates. - auto range = m_blockman.m_blocks_unlinked.equal_range(pindex->pprev); + auto range = m_blocks_unlinked.equal_range(pindex->pprev); while (range.first != range.second) { std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first; range.first++; if (_it->second == pindex) { - m_blockman.m_blocks_unlinked.erase(_it); + m_blocks_unlinked.erase(_it); } } } @@ -3954,22 +3953,23 @@ void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) } } -/* Calculate the block/rev files to delete based on height specified by user with RPC command pruneblockchain */ -static void FindFilesToPruneManual(ChainstateManager& chainman, std::set<int>& setFilesToPrune, int nManualPruneHeight) +void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height) { assert(fPruneMode && nManualPruneHeight > 0); LOCK2(cs_main, cs_LastBlockFile); - if (::ChainActive().Tip() == nullptr) + if (chain_tip_height < 0) { return; + } // last block to prune is the lesser of (user-specified height, MIN_BLOCKS_TO_KEEP from the tip) - unsigned int nLastBlockWeCanPrune = std::min((unsigned)nManualPruneHeight, ::ChainActive().Tip()->nHeight - MIN_BLOCKS_TO_KEEP); - int count=0; + unsigned int nLastBlockWeCanPrune = std::min((unsigned)nManualPruneHeight, chain_tip_height - MIN_BLOCKS_TO_KEEP); + int count = 0; for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { - if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) + if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) { continue; - chainman.PruneOneBlockFile(fileNumber); + } + PruneOneBlockFile(fileNumber); setFilesToPrune.insert(fileNumber); count++; } @@ -3987,46 +3987,31 @@ void PruneBlockFilesManual(int nManualPruneHeight) } } -/** - * Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target. - * The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new - * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex - * (which in this case means the blockchain must be re-downloaded.) - * - * Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set. - * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.) - * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 1000 on regtest). - * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip. - * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files. - * A db flag records the fact that at least some block files have been pruned. - * - * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned - */ -static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight) +void BlockManager::FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, bool is_ibd) { LOCK2(cs_main, cs_LastBlockFile); - if (::ChainActive().Tip() == nullptr || nPruneTarget == 0) { + if (chain_tip_height < 0 || nPruneTarget == 0) { return; } - if ((uint64_t)::ChainActive().Tip()->nHeight <= nPruneAfterHeight) { + if ((uint64_t)chain_tip_height <= nPruneAfterHeight) { return; } - unsigned int nLastBlockWeCanPrune = ::ChainActive().Tip()->nHeight - MIN_BLOCKS_TO_KEEP; + unsigned int nLastBlockWeCanPrune = chain_tip_height - MIN_BLOCKS_TO_KEEP; uint64_t nCurrentUsage = CalculateCurrentUsage(); // We don't check to prune until after we've allocated new space for files // So we should leave a buffer under our target to account for another allocation // before the next pruning. uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE; uint64_t nBytesToPrune; - int count=0; + int count = 0; if (nCurrentUsage + nBuffer >= nPruneTarget) { // On a prune event, the chainstate DB is flushed. // To avoid excessive prune events negating the benefit of high dbcache // values, we should not prune too rapidly. // So when pruning in IBD, increase the buffer a bit to avoid a re-prune too soon. - if (::ChainstateActive().IsInitialBlockDownload()) { + if (is_ibd) { // Since this is only relevant during IBD, we use a fixed 10% nBuffer += nPruneTarget / 10; } @@ -4034,17 +4019,20 @@ static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFile for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize; - if (vinfoBlockFile[fileNumber].nSize == 0) + if (vinfoBlockFile[fileNumber].nSize == 0) { continue; + } - if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target? + if (nCurrentUsage + nBuffer < nPruneTarget) { // are we below our target? break; + } // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning - if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) + if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) { continue; + } - chainman.PruneOneBlockFile(fileNumber); + PruneOneBlockFile(fileNumber); // Queue up the files for removal setFilesToPrune.insert(fileNumber); nCurrentUsage -= nBytesToPrune; @@ -4602,10 +4590,10 @@ void CChainState::UnloadBlockIndex() { // May NOT be used after any connections are up as much // of the peer-processing logic assumes a consistent // block index state -void UnloadBlockIndex(CTxMemPool* mempool) +void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman) { LOCK(cs_main); - g_chainman.Unload(); + chainman.Unload(); pindexBestInvalid = nullptr; pindexBestHeader = nullptr; if (mempool) mempool->clear(); @@ -5220,20 +5208,6 @@ double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pin return std::min<double>(pindex->nChainTx / fTxTotal, 1.0); } -class CMainCleanup -{ -public: - CMainCleanup() {} - ~CMainCleanup() { - // block headers - BlockMap::iterator it1 = g_chainman.BlockIndex().begin(); - for (; it1 != g_chainman.BlockIndex().end(); it1++) - delete (*it1).second; - g_chainman.BlockIndex().clear(); - } -}; -static CMainCleanup instance_of_cmaincleanup; - Optional<uint256> ChainstateManager::SnapshotBlockhash() const { if (m_active_chainstate != nullptr) { // If a snapshot chainstate exists, it will always be our active. |