Skip to content

Commit 73220fc

Browse files
committed
Merge bitcoin/bitcoin#33212: index: Don't commit state in BaseIndex::Rewind
a602f6f test: index with an unclean restart after a reorg (Martin Zumsande) 01b95ac index: don't commit state in BaseIndex::Rewind (Martin Zumsande) Pull request description: The committed state of an index should never be ahead of the flushed chainstate. Otherwise, in the case of an unclean shutdown, the blocks necessary to revert from the prematurely committed state are not be available, which would corrupt the coinstatsindex in particular. Instead, the index state will be committed with the next ChainStateFlushed notification. Fixes #33208 ACKs for top commit: achow101: ACK a602f6f stickies-v: re-ACK a602f6f Tree-SHA512: 2559ea3fe066caf746a54ad7daac5031332f3976848e937c3dc8b35fa2ce925674115d8742458bf3703b3916f04f851c26523b6b94aeb1da651ba5a1b167a419
2 parents 2c223de + a602f6f commit 73220fc

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

src/index/base.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -299,18 +299,13 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
299299
}
300300
}
301301

302-
// In the case of a reorg, ensure persisted block locator is not stale.
302+
// Don't commit here - the committed index state must never be ahead of the
303+
// flushed chainstate, otherwise unclean restarts would lead to index corruption.
303304
// Pruning has a minimum of 288 blocks-to-keep and getting the index
304305
// out of sync may be possible but a users fault.
305306
// In case we reorg beyond the pruned depth, ReadBlock would
306307
// throw and lead to a graceful shutdown
307308
SetBestBlockIndex(new_tip);
308-
if (!Commit()) {
309-
// If commit fails, revert the best block index to avoid corruption.
310-
SetBestBlockIndex(current_tip);
311-
return false;
312-
}
313-
314309
return true;
315310
}
316311

test/functional/feature_coinstatsindex.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,21 @@ def _test_init_index_after_reorg(self):
321321
res1 = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=None, use_index=True)
322322
assert_equal(res["muhash"], res1["muhash"])
323323

324+
self.log.info("Test index with an unclean restart after a reorg")
325+
self.restart_node(1, extra_args=self.extra_args[1])
326+
committed_height = index_node.getblockcount()
327+
self.generate(index_node, 2, sync_fun=self.no_op)
328+
self.sync_index_node()
329+
block2 = index_node.getbestblockhash()
330+
index_node.invalidateblock(block2)
331+
self.generatetoaddress(index_node, 1, getnewdestination()[2], sync_fun=self.no_op)
332+
self.sync_index_node()
333+
index_node.kill_process()
334+
self.start_node(1, extra_args=self.extra_args[1])
335+
self.sync_index_node()
336+
# Because of the unclean shutdown above, indexes reset to the point we last committed them to disk.
337+
assert_equal(index_node.getindexinfo()['coinstatsindex']['best_block_height'], committed_height)
338+
324339

325340
if __name__ == '__main__':
326341
CoinStatsIndexTest(__file__).main()

0 commit comments

Comments
 (0)