diff options
author | James O'Beirne <james.obeirne@gmail.com> | 2019-09-16 16:34:45 -0400 |
---|---|---|
committer | James O'Beirne <james.obeirne@pm.me> | 2023-09-30 06:40:16 -0400 |
commit | 1019c399825b0d512c1fd751c376d46fed4992b9 (patch) | |
tree | 08bdf7a2324e191ee721417b531094b359629e14 /src/validation.cpp | |
parent | 373cf91531b84bfdd06fdf8abf4dca228029ce6b (diff) |
validation: pruning for multiple chainstates
Introduces ChainstateManager::GetPruneRange().
The prune budget is split evenly between the number of chainstates,
however the prune budget may be exceeded if the resulting shares are
beneath `MIN_DISK_SPACE_FOR_BLOCK_FILES`.
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index 00da4a1c9e..ad135994ec 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -69,6 +69,7 @@ #include <optional> #include <string> #include <utility> +#include <tuple> using kernel::CCoinsStats; using kernel::CoinStatsHashType; @@ -2552,11 +2553,14 @@ bool Chainstate::FlushStateToDisk( if (nManualPruneHeight > 0) { LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune (manual)", BCLog::BENCH); - m_blockman.FindFilesToPruneManual(setFilesToPrune, std::min(last_prune, nManualPruneHeight), m_chain.Height()); + m_blockman.FindFilesToPruneManual( + setFilesToPrune, + std::min(last_prune, nManualPruneHeight), + *this, m_chainman); } else { LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH); - m_blockman.FindFilesToPrune(setFilesToPrune, m_chainman.GetParams().PruneAfterHeight(), m_chain.Height(), last_prune, m_chainman.IsInitialBlockDownload()); + m_blockman.FindFilesToPrune(setFilesToPrune, last_prune, *this, m_chainman); m_blockman.m_check_for_pruning = false; } if (!setFilesToPrune.empty()) { @@ -5939,3 +5943,30 @@ Chainstate& ChainstateManager::GetChainstateForIndexing() // indexed. return (this->GetAll().size() > 1) ? *m_ibd_chainstate : *m_active_chainstate; } + +std::pair<int, int> ChainstateManager::GetPruneRange(const Chainstate& chainstate, int last_height_can_prune) +{ + if (chainstate.m_chain.Height() <= 0) { + return {0, 0}; + } + int prune_start{0}; + + if (this->GetAll().size() > 1 && m_snapshot_chainstate.get() == &chainstate) { + // Leave the blocks in the background IBD chain alone if we're pruning + // the snapshot chain. + prune_start = *Assert(GetSnapshotBaseHeight()) + 1; + } + + int max_prune = std::max<int>( + 0, chainstate.m_chain.Height() - static_cast<int>(MIN_BLOCKS_TO_KEEP)); + + // last block to prune is the lesser of (caller-specified height, MIN_BLOCKS_TO_KEEP from the tip) + // + // While you might be tempted to prune the background chainstate more + // aggressively (i.e. fewer MIN_BLOCKS_TO_KEEP), this won't work with index + // building - specifically blockfilterindex requires undo data, and if + // we don't maintain this trailing window, we hit indexing failures. + int prune_end = std::min(last_height_can_prune, max_prune); + + return {prune_start, prune_end}; +} |