mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-19 20:20:00 +01:00
Merge #19927: validation: Reduce direct g_chainman usage
72a1d5c6f3validation: Remove review-only comments + assertions (Carl Dong)3756853b15docs: Move FindFilesToPrune{,Manual} doxygen comment (Carl Dong)485899a93cstyle: Make FindFilesToPrune{,Manual} match style guide (Carl Dong)3f5b5f3f6dvalidation: Move FindFilesToPrune{,Manual} to BlockManager (Carl Dong)f8d4975ab3validation: Move PruneOneBlockFile to BlockManager (Carl Dong)74f73c783dvalidation: Pass in chainman to UnloadBlockIndex (Carl Dong)4668ded6d6validation: Move ~CMainCleanup logic to ~BlockManager (Carl Dong) Pull request description: This PR paves the way for de-globalizing `g_chainman` entirely by removing the usage of `g_chainman` in the following functions/methods: - `~CMainCleanup` - `CChainState::FlushStateToDisk` - `UnloadBlockIndex` The remaining direct uses of `g_chainman` are as follows: 1. In initialization codepaths: - `AppTests` - `AppInitMain` - `TestingSetup::TestingSetup` 2. `::ChainstateActive` 3. `LookupBlockIndex` - Note: `LookupBlockIndex` is used extensively throughout the codebase and require a much larger set of changes, therefore I've left it out of this initial PR ACKs for top commit: MarcoFalke: re-ACK72a1d5c6f3👚 jnewbery: utACK72a1d5c6f3Tree-SHA512: 944a4fa8405eecf39706ff944375d6824373aaeea849d11473f08181eff26b12f70043a8348a5b08e6e9021b243b481842fbdfbc7c3140ca795fce3688b7f5c3
This commit is contained in:
@@ -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()) {
|
||||
@@ -3909,12 +3906,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 +3925,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 +3951,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 +3985,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 +4017,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 +4588,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 +5206,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.
|
||||
|
||||
Reference in New Issue
Block a user