@@ -113,6 +113,11 @@ void BaseIndex::ThreadSync()
113
113
Commit ();
114
114
break ;
115
115
}
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
+ }
116
121
pindex = pindex_next;
117
122
}
118
123
@@ -167,6 +172,22 @@ bool BaseIndex::CommitInternal(CDBBatch& batch)
167
172
return true ;
168
173
}
169
174
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
+
170
191
void BaseIndex::BlockConnected (const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
171
192
const std::vector<CTransactionRef>& txn_conflicted)
172
193
{
@@ -194,6 +215,11 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
194
215
best_block_index->GetBlockHash ().ToString ());
195
216
return ;
196
217
}
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
+ }
197
223
}
198
224
199
225
if (WriteBlock (*block, pindex)) {
0 commit comments