Skip to content

Commit 4175c33

Browse files
committed
Merge bitcoin#26215: index: Improve BaseIndex::BlockUntilSyncedToCurrentChain reliability
8891949 index: Improve BaseIndex::BlockUntilSyncedToCurrentChain reliability (Ryan Ofsky) Pull request description: Since commit f08c9fb from PR bitcoin#21726, index `BlockUntilSyncedToCurrentChain` behavior has been less reliable, and there has also been a race condition in the `coinstatsindex_initial_sync` unit test. It seems better for `BlockUntilSyncedToCurrentChain` to actually wait for the last connected block to be fully processed, than to be able to return before prune locks are set, so this switches the order of `m_best_block_index = block;` and `UpdatePruneLock` statements in `SetBestBlockIndex` to make it more reliable. Also since commit f08c9fb, there has been a race condition in the `coinstatsindex_initial_sync` test. Before that commit, the atomic index best block pointer `m_best_block_index` was updated as the last step of `BaseIndex::BlockConnected`, so `BlockUntilSyncedToCurrentChain` could safely be used in tests to wait for the last `BlockConnected` notification to be finished before stopping and destroying the index. But after that commit, calling `BlockUntilSyncedToCurrentChain` is no longer sufficient, and there is a race between the test shutdown code which destroys the index object and the new code introduced in that commit calling `AllowPrune()` and `GetName()` on the index object. Reproducibility instructions for this are in bitcoin#25365 (comment) This commit fixes the `coinstatsindex_initial_sync` race condition, even though it will require an additional change to silence TSAN false positives, bitcoin#26188, after it is fixed. So this partially addresses but does not resolve the bug reporting TSAN errors bitcoin#25365. There is no known race condition outside of test code currently, because the bitcoind `Shutdown` function calls `FlushBackgroundCallbacks` not `BlockUntilSyncedToCurrentChain` to safely shut down. Co-authored-by: vasild Co-authored-by: MarcoFalke ACKs for top commit: mzumsande: re-ACK 8891949 Tree-SHA512: 52e29e3772a0c92873c54e5ffb31dd66a909b68a2031b7585713cd1d976811289c98bd9bb41679a8689062f03be4f97bb8368696e789caa4607c2fd8b1fe289b
2 parents cf3db7c + 8891949 commit 4175c33

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/index/base.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,10 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
298298
}
299299
interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex, block.get());
300300
if (CustomAppend(block_info)) {
301+
// Setting the best block index is intentionally the last step of this
302+
// function, so BlockUntilSyncedToCurrentChain callers waiting for the
303+
// best block index to be updated can rely on the block being fully
304+
// processed, and the index object being safe to delete.
301305
SetBestBlockIndex(pindex);
302306
} else {
303307
FatalError("%s: Failed to write block %s to index",
@@ -414,10 +418,17 @@ IndexSummary BaseIndex::GetSummary() const
414418
void BaseIndex::SetBestBlockIndex(const CBlockIndex* block) {
415419
assert(!node::fPruneMode || AllowPrune());
416420

417-
m_best_block_index = block;
418421
if (AllowPrune() && block) {
419422
node::PruneLockInfo prune_lock;
420423
prune_lock.height_first = block->nHeight;
421424
WITH_LOCK(::cs_main, m_chainstate->m_blockman.UpdatePruneLock(GetName(), prune_lock));
422425
}
426+
427+
// Intentionally set m_best_block_index as the last step in this function,
428+
// after updating prune locks above, and after making any other references
429+
// to *this, so the BlockUntilSyncedToCurrentChain function (which checks
430+
// m_best_block_index as an optimization) can be used to wait for the last
431+
// BlockConnected notification and safely assume that prune locks are
432+
// updated and that the index object is safe to delete.
433+
m_best_block_index = block;
423434
}

0 commit comments

Comments
 (0)