Skip to content

Commit 62b7a4f

Browse files
committed
index: Ensure block locator is not stale after chain reorg.
1 parent 4368384 commit 62b7a4f

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/index/base.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ void BaseIndex::ThreadSync()
113113
Commit();
114114
break;
115115
}
116+
if (pindex_next->pprev != pindex && !Rewind(pindex, pindex_next->pprev)) {
117+
FatalError("%s: Failed to rewind index %s to a previous chain tip",
118+
__func__, GetName());
119+
return;
120+
}
116121
pindex = pindex_next;
117122
}
118123

@@ -167,6 +172,22 @@ bool BaseIndex::CommitInternal(CDBBatch& batch)
167172
return true;
168173
}
169174

175+
bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip)
176+
{
177+
assert(current_tip == m_best_block_index);
178+
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip);
179+
180+
// In the case of a reorg, ensure persisted block locator is not stale.
181+
m_best_block_index = new_tip;
182+
if (!Commit()) {
183+
// If commit fails, revert the best block index to avoid corruption.
184+
m_best_block_index = current_tip;
185+
return false;
186+
}
187+
188+
return true;
189+
}
190+
170191
void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
171192
const std::vector<CTransactionRef>& txn_conflicted)
172193
{
@@ -194,6 +215,11 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
194215
best_block_index->GetBlockHash().ToString());
195216
return;
196217
}
218+
if (best_block_index != pindex->pprev && !Rewind(best_block_index, pindex->pprev)) {
219+
FatalError("%s: Failed to rewind index %s to a previous chain tip",
220+
__func__, GetName());
221+
return;
222+
}
197223
}
198224

199225
if (WriteBlock(*block, pindex)) {

src/index/base.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ class BaseIndex : public CValidationInterface
8080
/// commit more index state.
8181
virtual bool CommitInternal(CDBBatch& batch);
8282

83+
/// Rewind index to an earlier chain tip during a chain reorg. The tip must
84+
/// be an ancestor of the current best block.
85+
virtual bool Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip);
86+
8387
virtual DB& GetDB() const = 0;
8488

8589
/// Get the name of the index for display in logs.

0 commit comments

Comments
 (0)