Skip to content

Commit 7878f97

Browse files
committed
indexes, refactor: Remove CChainState use in index CommitInternal method
Replace CommitInternal method with CustomCommit and use interfaces::Chain instead of CChainState to generate block locator. This commit does not change behavior in any way, except in the (m_best_block_index == nullptr) case, which was added recently in bitcoin/bitcoin#24117 as part of an ongoing attempt to prevent index corruption if bitcoind is interrupted during startup. New behavior in that case should be slightly better than the old behavior (skipping the entire custom+base commit now vs only skipping the base commit previously) and this might avoid more cases of corruption.
1 parent ee3a079 commit 7878f97

File tree

8 files changed

+31
-20
lines changed

8 files changed

+31
-20
lines changed

src/index/base.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ static void FatalError(const char* fmt, const Args&... args)
3434
StartShutdown();
3535
}
3636

37+
CBlockLocator GetLocator(interfaces::Chain& chain, const uint256& block_hash)
38+
{
39+
CBlockLocator locator;
40+
bool found = chain.findBlock(block_hash, interfaces::FoundBlock().locator(locator));
41+
assert(found);
42+
assert(!locator.IsNull());
43+
return locator;
44+
}
45+
3746
BaseIndex::DB::DB(const fs::path& path, size_t n_cache_size, bool f_memory, bool f_wipe, bool f_obfuscate) :
3847
CDBWrapper(path, n_cache_size, f_memory, f_wipe, f_obfuscate)
3948
{}
@@ -206,22 +215,20 @@ void BaseIndex::ThreadSync()
206215

207216
bool BaseIndex::Commit()
208217
{
209-
CDBBatch batch(GetDB());
210-
if (!CommitInternal(batch) || !GetDB().WriteBatch(batch)) {
211-
return error("%s: Failed to commit latest %s state", __func__, GetName());
212-
}
213-
return true;
214-
}
215-
216-
bool BaseIndex::CommitInternal(CDBBatch& batch)
217-
{
218-
LOCK(cs_main);
219218
// Don't commit anything if we haven't indexed any block yet
220219
// (this could happen if init is interrupted).
221-
if (m_best_block_index == nullptr) {
222-
return false;
220+
bool ok = m_best_block_index != nullptr;
221+
if (ok) {
222+
CDBBatch batch(GetDB());
223+
ok = CustomCommit(batch);
224+
if (ok) {
225+
GetDB().WriteBestBlock(batch, GetLocator(*m_chain, m_best_block_index.load()->GetBlockHash()));
226+
ok = GetDB().WriteBatch(batch);
227+
}
228+
}
229+
if (!ok) {
230+
return error("%s: Failed to commit latest %s state", __func__, GetName());
223231
}
224-
GetDB().WriteBestBlock(batch, m_chainstate->m_chain.GetLocator(m_best_block_index));
225232
return true;
226233
}
227234

src/index/base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class BaseIndex : public CValidationInterface
104104

105105
/// Virtual method called internally by Commit that can be overridden to atomically
106106
/// commit more index state.
107-
virtual bool CommitInternal(CDBBatch& batch);
107+
virtual bool CustomCommit(CDBBatch& batch) { return true; }
108108

109109
/// Rewind index to an earlier chain tip during a chain reorg. The tip must
110110
/// be an ancestor of the current best block.

src/index/blockfilterindex.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ bool BlockFilterIndex::CustomInit(const std::optional<interfaces::BlockKey>& blo
128128
return true;
129129
}
130130

131-
bool BlockFilterIndex::CommitInternal(CDBBatch& batch)
131+
bool BlockFilterIndex::CustomCommit(CDBBatch& batch)
132132
{
133133
const FlatFilePos& pos = m_next_filter_pos;
134134

@@ -142,7 +142,7 @@ bool BlockFilterIndex::CommitInternal(CDBBatch& batch)
142142
}
143143

144144
batch.Write(DB_FILTER_POS, pos);
145-
return BaseIndex::CommitInternal(batch);
145+
return true;
146146
}
147147

148148
bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, const uint256& hash, BlockFilter& filter) const

src/index/blockfilterindex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class BlockFilterIndex final : public BaseIndex
4343
protected:
4444
bool CustomInit(const std::optional<interfaces::BlockKey>& block) override;
4545

46-
bool CommitInternal(CDBBatch& batch) override;
46+
bool CustomCommit(CDBBatch& batch) override;
4747

4848
bool CustomAppend(const interfaces::BlockInfo& block) override;
4949

src/index/coinstatsindex.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,12 @@ bool CoinStatsIndex::CustomInit(const std::optional<interfaces::BlockKey>& block
391391
return true;
392392
}
393393

394-
bool CoinStatsIndex::CommitInternal(CDBBatch& batch)
394+
bool CoinStatsIndex::CustomCommit(CDBBatch& batch)
395395
{
396396
// DB_MUHASH should always be committed in a batch together with DB_BEST_BLOCK
397397
// to prevent an inconsistent state of the DB.
398398
batch.Write(DB_MUHASH, m_muhash);
399-
return BaseIndex::CommitInternal(batch);
399+
return true;
400400
}
401401

402402
// Reverse a single block as part of a reorg

src/index/coinstatsindex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CoinStatsIndex final : public BaseIndex
4141
protected:
4242
bool CustomInit(const std::optional<interfaces::BlockKey>& block) override;
4343

44-
bool CommitInternal(CDBBatch& batch) override;
44+
bool CustomCommit(CDBBatch& batch) override;
4545

4646
bool CustomAppend(const interfaces::BlockInfo& block) override;
4747

src/interfaces/chain.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class FoundBlock
5757
FoundBlock& mtpTime(int64_t& mtp_time) { m_mtp_time = &mtp_time; return *this; }
5858
//! Return whether block is in the active (most-work) chain.
5959
FoundBlock& inActiveChain(bool& in_active_chain) { m_in_active_chain = &in_active_chain; return *this; }
60+
//! Return locator if block is in the active chain.
61+
FoundBlock& locator(CBlockLocator& locator) { m_locator = &locator; return *this; }
6062
//! Return next block in the active chain if current block is in the active chain.
6163
FoundBlock& nextBlock(const FoundBlock& next_block) { m_next_block = &next_block; return *this; }
6264
//! Read block data from disk. If the block exists but doesn't have data
@@ -69,6 +71,7 @@ class FoundBlock
6971
int64_t* m_max_time = nullptr;
7072
int64_t* m_mtp_time = nullptr;
7173
bool* m_in_active_chain = nullptr;
74+
CBlockLocator* m_locator = nullptr;
7275
const FoundBlock* m_next_block = nullptr;
7376
CBlock* m_data = nullptr;
7477
mutable bool found = false;

src/node/interfaces.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<Rec
402402
if (block.m_max_time) *block.m_max_time = index->GetBlockTimeMax();
403403
if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast();
404404
if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index;
405+
if (block.m_locator) { *block.m_locator = active.GetLocator(index); }
405406
if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active);
406407
if (block.m_data) {
407408
REVERSE_LOCK(lock);

0 commit comments

Comments
 (0)