Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13711440
D11145.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Subscribers
None
D11145.diff
View Options
diff --git a/src/index/base.cpp b/src/index/base.cpp
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -66,6 +66,48 @@
m_best_block_index = FindForkInGlobalIndex(::ChainActive(), locator);
}
m_synced = m_best_block_index.load() == ::ChainActive().Tip();
+ if (!m_synced) {
+ bool prune_violation = false;
+ if (!m_best_block_index) {
+ // index is not built yet
+ // make sure we have all block data back to the genesis
+ const CBlockIndex *block = ::ChainActive().Tip();
+ while (block->pprev && block->pprev->nStatus.hasData()) {
+ block = block->pprev;
+ }
+ prune_violation = block != ::ChainActive().Genesis();
+ }
+ // in case the index has a best block set and is not fully synced
+ // check if we have the required blocks to continue building the index
+ else {
+ const CBlockIndex *block_to_test = m_best_block_index.load();
+ if (!ChainActive().Contains(block_to_test)) {
+ // if the bestblock is not part of the mainchain, find the fork
+ // and make sure we have all data down to the fork
+ block_to_test = ::ChainActive().FindFork(block_to_test);
+ }
+ const CBlockIndex *block = ::ChainActive().Tip();
+ prune_violation = true;
+ // check backwards from the tip if we have all block data until we
+ // reach the indexes bestblock
+ while (block_to_test && block && block->nStatus.hasData()) {
+ if (block_to_test == block) {
+ prune_violation = false;
+ break;
+ }
+ assert(block->pprev);
+ block = block->pprev;
+ }
+ }
+ if (prune_violation) {
+ // throw error and graceful shutdown if we can't build the index
+ FatalError("%s: %s best block of the index goes beyond pruned "
+ "data. Please disable the index or reindex (which will "
+ "download the whole blockchain again)",
+ __func__, GetName());
+ return false;
+ }
+ }
return true;
}
@@ -181,6 +223,10 @@
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip);
// In the case of a reorg, ensure persisted block locator is not stale.
+ // Pruning has a minimum of 288 blocks-to-keep and getting the index
+ // out of sync may be possible but a users fault.
+ // In case we reorg beyond the pruned depth, ReadBlockFromDisk would
+ // throw and lead to a graceful shutdown
m_best_block_index = new_tip;
if (!Commit()) {
// If commit fails, revert the best block index to avoid corruption.
@@ -332,6 +378,7 @@
IndexSummary summary{};
summary.name = GetName();
summary.synced = m_synced;
- summary.best_block_height = m_best_block_index.load()->nHeight;
+ summary.best_block_height =
+ m_best_block_index ? m_best_block_index.load()->nHeight : 0;
return summary;
}
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1900,10 +1900,6 @@
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
return InitError(_("Prune mode is incompatible with -txindex."));
}
- if (!g_enabled_filter_types.empty()) {
- return InitError(
- _("Prune mode is incompatible with -blockfilterindex."));
- }
}
// -bind and -whitebind can't be set when not listening
diff --git a/src/validation.h b/src/validation.h
--- a/src/validation.h
+++ b/src/validation.h
@@ -615,7 +615,7 @@
*/
void FindFilesToPrune(std::set<int> &setFilesToPrune,
uint64_t nPruneAfterHeight, int chain_tip_height,
- bool is_ibd);
+ int prune_height, bool is_ibd);
public:
BlockMap m_block_index GUARDED_BY(cs_main);
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -21,6 +21,7 @@
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <hash.h>
+#include <index/blockfilterindex.h>
#include <index/txindex.h>
#include <logging.h>
#include <logging/timer.h>
@@ -2116,22 +2117,36 @@
{
bool fFlushForPrune = false;
bool fDoFullFlush = false;
+
CoinsCacheSizeState cache_state =
GetCoinsCacheSizeState(&m_mempool);
LOCK(cs_LastBlockFile);
if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) &&
!fReindex) {
+ // make sure we don't prune above the blockfilterindexes
+ // bestblocks
+ // pruning is height-based
+ // last height we can prune
+ int last_prune = m_chain.Height();
+ ForEachBlockFilterIndex([&](BlockFilterIndex &index) {
+ last_prune = std::max(
+ 1, std::min(last_prune,
+ index.GetSummary().best_block_height));
+ });
+
if (nManualPruneHeight > 0) {
LOG_TIME_MILLIS_WITH_CATEGORY(
"find files to prune (manual)", BCLog::BENCH);
m_blockman.FindFilesToPruneManual(
- setFilesToPrune, nManualPruneHeight, m_chain.Height());
+ setFilesToPrune,
+ std::min(last_prune, nManualPruneHeight),
+ m_chain.Height());
} else {
LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune",
BCLog::BENCH);
m_blockman.FindFilesToPrune(
setFilesToPrune, chainparams.PruneAfterHeight(),
- m_chain.Height(), IsInitialBlockDownload());
+ m_chain.Height(), last_prune, IsInitialBlockDownload());
fCheckForPruning = false;
}
if (!setFilesToPrune.empty()) {
@@ -4585,7 +4600,8 @@
void BlockManager::FindFilesToPrune(std::set<int> &setFilesToPrune,
uint64_t nPruneAfterHeight,
- int chain_tip_height, bool is_ibd) {
+ int chain_tip_height, int prune_height,
+ bool is_ibd) {
LOCK2(cs_main, cs_LastBlockFile);
if (chain_tip_height < 0 || nPruneTarget == 0) {
return;
@@ -4594,7 +4610,8 @@
return;
}
- unsigned int nLastBlockWeCanPrune = chain_tip_height - MIN_BLOCKS_TO_KEEP;
+ unsigned int nLastBlockWeCanPrune = std::min(
+ prune_height, chain_tip_height - static_cast<int>(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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 26, 12:05 (2 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5573499
Default Alt Text
D11145.diff (7 KB)
Attached To
D11145: Allow maintaining the blockfilterindex when using prune
Event Timeline
Log In to Comment