mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-26 17:52:13 +01:00
Index: Use prune locks for blockfilterindex
Prior to this change blocks could be pruned up to the last block before the blockfilterindex current best block.
This commit is contained in:
parent
2561823531
commit
f08c9fb0c6
@ -65,9 +65,9 @@ bool BaseIndex::Init()
|
||||
LOCK(cs_main);
|
||||
CChain& active_chain = m_chainstate->m_chain;
|
||||
if (locator.IsNull()) {
|
||||
m_best_block_index = nullptr;
|
||||
SetBestBlockIndex(nullptr);
|
||||
} else {
|
||||
m_best_block_index = m_chainstate->FindForkInGlobalIndex(locator);
|
||||
SetBestBlockIndex(m_chainstate->FindForkInGlobalIndex(locator));
|
||||
}
|
||||
m_synced = m_best_block_index.load() == active_chain.Tip();
|
||||
if (!m_synced) {
|
||||
@ -134,7 +134,7 @@ void BaseIndex::ThreadSync()
|
||||
int64_t last_locator_write_time = 0;
|
||||
while (true) {
|
||||
if (m_interrupt) {
|
||||
m_best_block_index = pindex;
|
||||
SetBestBlockIndex(pindex);
|
||||
// No need to handle errors in Commit. If it fails, the error will be already be
|
||||
// logged. The best way to recover is to continue, as index cannot be corrupted by
|
||||
// a missed commit to disk for an advanced index state.
|
||||
@ -146,7 +146,7 @@ void BaseIndex::ThreadSync()
|
||||
LOCK(cs_main);
|
||||
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
|
||||
if (!pindex_next) {
|
||||
m_best_block_index = pindex;
|
||||
SetBestBlockIndex(pindex);
|
||||
m_synced = true;
|
||||
// No need to handle errors in Commit. See rationale above.
|
||||
Commit();
|
||||
@ -168,7 +168,7 @@ void BaseIndex::ThreadSync()
|
||||
}
|
||||
|
||||
if (last_locator_write_time + SYNC_LOCATOR_WRITE_INTERVAL < current_time) {
|
||||
m_best_block_index = pindex;
|
||||
SetBestBlockIndex(pindex);
|
||||
last_locator_write_time = current_time;
|
||||
// No need to handle errors in Commit. See rationale above.
|
||||
Commit();
|
||||
@ -226,10 +226,10 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
|
||||
// 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;
|
||||
SetBestBlockIndex(new_tip);
|
||||
if (!Commit()) {
|
||||
// If commit fails, revert the best block index to avoid corruption.
|
||||
m_best_block_index = current_tip;
|
||||
SetBestBlockIndex(current_tip);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
|
||||
}
|
||||
|
||||
if (WriteBlock(*block, pindex)) {
|
||||
m_best_block_index = pindex;
|
||||
SetBestBlockIndex(pindex);
|
||||
} else {
|
||||
FatalError("%s: Failed to write block %s to index",
|
||||
__func__, pindex->GetBlockHash().ToString());
|
||||
@ -377,3 +377,14 @@ IndexSummary BaseIndex::GetSummary() const
|
||||
summary.best_block_height = m_best_block_index ? m_best_block_index.load()->nHeight : 0;
|
||||
return summary;
|
||||
}
|
||||
|
||||
void BaseIndex::SetBestBlockIndex(const CBlockIndex* block) {
|
||||
assert(!node::fPruneMode || AllowPrune());
|
||||
|
||||
m_best_block_index = block;
|
||||
if (AllowPrune() && block) {
|
||||
node::PruneLockInfo prune_lock;
|
||||
prune_lock.height_first = block->nHeight;
|
||||
WITH_LOCK(::cs_main, m_chainstate->m_blockman.UpdatePruneLock(GetName(), prune_lock));
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,9 @@ private:
|
||||
/// to a chain reorganization), the index must halt until Commit succeeds or else it could end up
|
||||
/// getting corrupted.
|
||||
bool Commit();
|
||||
|
||||
virtual bool AllowPrune() const = 0;
|
||||
|
||||
protected:
|
||||
CChainState* m_chainstate{nullptr};
|
||||
|
||||
@ -103,6 +106,9 @@ protected:
|
||||
/// Get the name of the index for display in logs.
|
||||
virtual const char* GetName() const = 0;
|
||||
|
||||
/// Update the internal best block index as well as the prune lock.
|
||||
void SetBestBlockIndex(const CBlockIndex* block);
|
||||
|
||||
public:
|
||||
/// Destructor interrupts sync thread if running and blocks until it exits.
|
||||
virtual ~BaseIndex();
|
||||
|
@ -38,6 +38,8 @@ private:
|
||||
/** cache of block hash to filter header, to avoid disk access when responding to getcfcheckpt. */
|
||||
std::unordered_map<uint256, uint256, FilterHeaderHasher> m_headers_cache GUARDED_BY(m_cs_headers_cache);
|
||||
|
||||
bool AllowPrune() const override { return true; }
|
||||
|
||||
protected:
|
||||
bool Init() override;
|
||||
|
||||
|
@ -36,6 +36,8 @@ private:
|
||||
|
||||
bool ReverseBlock(const CBlock& block, const CBlockIndex* pindex);
|
||||
|
||||
bool AllowPrune() const override { return true; }
|
||||
|
||||
protected:
|
||||
bool Init() override;
|
||||
|
||||
|
@ -20,6 +20,8 @@ protected:
|
||||
private:
|
||||
const std::unique_ptr<DB> m_db;
|
||||
|
||||
bool AllowPrune() const override { return false; }
|
||||
|
||||
protected:
|
||||
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <deploymentstatus.h>
|
||||
#include <flatfile.h>
|
||||
#include <hash.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <logging.h>
|
||||
#include <logging/timer.h>
|
||||
#include <node/blockstorage.h>
|
||||
@ -2349,10 +2348,6 @@ bool CChainState::FlushStateToDisk(
|
||||
int last_prune{m_chain.Height()}; // last height we can prune
|
||||
std::optional<std::string> limiting_lock; // prune lock that actually was the limiting factor, only used for logging
|
||||
|
||||
ForEachBlockFilterIndex([&](BlockFilterIndex& index) {
|
||||
last_prune = std::max(1, std::min(last_prune, index.GetSummary().best_block_height));
|
||||
});
|
||||
|
||||
for (const auto& prune_lock : m_blockman.m_prune_locks) {
|
||||
if (prune_lock.second.height_first == std::numeric_limits<int>::max()) continue;
|
||||
// Remove the buffer and one additional block here to get actual height that is outside of the buffer
|
||||
|
@ -15,8 +15,6 @@ import sys
|
||||
EXPECTED_CIRCULAR_DEPENDENCIES = (
|
||||
"chainparamsbase -> util/system -> chainparamsbase",
|
||||
"node/blockstorage -> validation -> node/blockstorage",
|
||||
"index/blockfilterindex -> node/blockstorage -> validation -> index/blockfilterindex",
|
||||
"index/base -> validation -> index/blockfilterindex -> index/base",
|
||||
"index/coinstatsindex -> node/coinstats -> index/coinstatsindex",
|
||||
"policy/fees -> txmempool -> policy/fees",
|
||||
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel",
|
||||
|
Loading…
x
Reference in New Issue
Block a user