Skip to content

Commit f08c9fb

Browse files
committed
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.
1 parent 2561823 commit f08c9fb

File tree

7 files changed

+31
-15
lines changed

7 files changed

+31
-15
lines changed

src/index/base.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ bool BaseIndex::Init()
6565
LOCK(cs_main);
6666
CChain& active_chain = m_chainstate->m_chain;
6767
if (locator.IsNull()) {
68-
m_best_block_index = nullptr;
68+
SetBestBlockIndex(nullptr);
6969
} else {
70-
m_best_block_index = m_chainstate->FindForkInGlobalIndex(locator);
70+
SetBestBlockIndex(m_chainstate->FindForkInGlobalIndex(locator));
7171
}
7272
m_synced = m_best_block_index.load() == active_chain.Tip();
7373
if (!m_synced) {
@@ -134,7 +134,7 @@ void BaseIndex::ThreadSync()
134134
int64_t last_locator_write_time = 0;
135135
while (true) {
136136
if (m_interrupt) {
137-
m_best_block_index = pindex;
137+
SetBestBlockIndex(pindex);
138138
// No need to handle errors in Commit. If it fails, the error will be already be
139139
// logged. The best way to recover is to continue, as index cannot be corrupted by
140140
// a missed commit to disk for an advanced index state.
@@ -146,7 +146,7 @@ void BaseIndex::ThreadSync()
146146
LOCK(cs_main);
147147
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
148148
if (!pindex_next) {
149-
m_best_block_index = pindex;
149+
SetBestBlockIndex(pindex);
150150
m_synced = true;
151151
// No need to handle errors in Commit. See rationale above.
152152
Commit();
@@ -168,7 +168,7 @@ void BaseIndex::ThreadSync()
168168
}
169169

170170
if (last_locator_write_time + SYNC_LOCATOR_WRITE_INTERVAL < current_time) {
171-
m_best_block_index = pindex;
171+
SetBestBlockIndex(pindex);
172172
last_locator_write_time = current_time;
173173
// No need to handle errors in Commit. See rationale above.
174174
Commit();
@@ -226,10 +226,10 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
226226
// out of sync may be possible but a users fault.
227227
// In case we reorg beyond the pruned depth, ReadBlockFromDisk would
228228
// throw and lead to a graceful shutdown
229-
m_best_block_index = new_tip;
229+
SetBestBlockIndex(new_tip);
230230
if (!Commit()) {
231231
// If commit fails, revert the best block index to avoid corruption.
232-
m_best_block_index = current_tip;
232+
SetBestBlockIndex(current_tip);
233233
return false;
234234
}
235235

@@ -270,7 +270,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
270270
}
271271

272272
if (WriteBlock(*block, pindex)) {
273-
m_best_block_index = pindex;
273+
SetBestBlockIndex(pindex);
274274
} else {
275275
FatalError("%s: Failed to write block %s to index",
276276
__func__, pindex->GetBlockHash().ToString());
@@ -377,3 +377,14 @@ IndexSummary BaseIndex::GetSummary() const
377377
summary.best_block_height = m_best_block_index ? m_best_block_index.load()->nHeight : 0;
378378
return summary;
379379
}
380+
381+
void BaseIndex::SetBestBlockIndex(const CBlockIndex* block) {
382+
assert(!node::fPruneMode || AllowPrune());
383+
384+
m_best_block_index = block;
385+
if (AllowPrune() && block) {
386+
node::PruneLockInfo prune_lock;
387+
prune_lock.height_first = block->nHeight;
388+
WITH_LOCK(::cs_main, m_chainstate->m_blockman.UpdatePruneLock(GetName(), prune_lock));
389+
}
390+
}

src/index/base.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class BaseIndex : public CValidationInterface
7575
/// to a chain reorganization), the index must halt until Commit succeeds or else it could end up
7676
/// getting corrupted.
7777
bool Commit();
78+
79+
virtual bool AllowPrune() const = 0;
80+
7881
protected:
7982
CChainState* m_chainstate{nullptr};
8083

@@ -103,6 +106,9 @@ class BaseIndex : public CValidationInterface
103106
/// Get the name of the index for display in logs.
104107
virtual const char* GetName() const = 0;
105108

109+
/// Update the internal best block index as well as the prune lock.
110+
void SetBestBlockIndex(const CBlockIndex* block);
111+
106112
public:
107113
/// Destructor interrupts sync thread if running and blocks until it exits.
108114
virtual ~BaseIndex();

src/index/blockfilterindex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class BlockFilterIndex final : public BaseIndex
3838
/** cache of block hash to filter header, to avoid disk access when responding to getcfcheckpt. */
3939
std::unordered_map<uint256, uint256, FilterHeaderHasher> m_headers_cache GUARDED_BY(m_cs_headers_cache);
4040

41+
bool AllowPrune() const override { return true; }
42+
4143
protected:
4244
bool Init() override;
4345

src/index/coinstatsindex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class CoinStatsIndex final : public BaseIndex
3636

3737
bool ReverseBlock(const CBlock& block, const CBlockIndex* pindex);
3838

39+
bool AllowPrune() const override { return true; }
40+
3941
protected:
4042
bool Init() override;
4143

src/index/txindex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class TxIndex final : public BaseIndex
2020
private:
2121
const std::unique_ptr<DB> m_db;
2222

23+
bool AllowPrune() const override { return false; }
24+
2325
protected:
2426
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
2527

src/validation.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include <deploymentstatus.h>
2020
#include <flatfile.h>
2121
#include <hash.h>
22-
#include <index/blockfilterindex.h>
2322
#include <logging.h>
2423
#include <logging/timer.h>
2524
#include <node/blockstorage.h>
@@ -2349,10 +2348,6 @@ bool CChainState::FlushStateToDisk(
23492348
int last_prune{m_chain.Height()}; // last height we can prune
23502349
std::optional<std::string> limiting_lock; // prune lock that actually was the limiting factor, only used for logging
23512350

2352-
ForEachBlockFilterIndex([&](BlockFilterIndex& index) {
2353-
last_prune = std::max(1, std::min(last_prune, index.GetSummary().best_block_height));
2354-
});
2355-
23562351
for (const auto& prune_lock : m_blockman.m_prune_locks) {
23572352
if (prune_lock.second.height_first == std::numeric_limits<int>::max()) continue;
23582353
// Remove the buffer and one additional block here to get actual height that is outside of the buffer

test/lint/lint-circular-dependencies.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
EXPECTED_CIRCULAR_DEPENDENCIES = (
1616
"chainparamsbase -> util/system -> chainparamsbase",
1717
"node/blockstorage -> validation -> node/blockstorage",
18-
"index/blockfilterindex -> node/blockstorage -> validation -> index/blockfilterindex",
19-
"index/base -> validation -> index/blockfilterindex -> index/base",
2018
"index/coinstatsindex -> node/coinstats -> index/coinstatsindex",
2119
"policy/fees -> txmempool -> policy/fees",
2220
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel",

0 commit comments

Comments
 (0)