@@ -270,6 +270,10 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
270
270
}
271
271
272
272
if (WriteBlock (*block, pindex)) {
273
+ // Setting the best block index is intentionally the last step of this
274
+ // function, so BlockUntilSyncedToCurrentChain callers waiting for the
275
+ // best block index to be updated can rely on the block being fully
276
+ // processed, and the index object being safe to delete.
273
277
SetBestBlockIndex (pindex);
274
278
} else {
275
279
FatalError (" %s: Failed to write block %s to index" ,
@@ -381,10 +385,17 @@ IndexSummary BaseIndex::GetSummary() const
381
385
void BaseIndex::SetBestBlockIndex (const CBlockIndex* block) {
382
386
assert (!fPruneMode || AllowPrune ());
383
387
384
- m_best_block_index = block;
385
388
if (AllowPrune () && block) {
386
389
PruneLockInfo prune_lock;
387
390
prune_lock.height_first = block->nHeight ;
388
391
WITH_LOCK (::cs_main, m_chainstate->m_blockman .UpdatePruneLock (GetName (), prune_lock));
389
392
}
393
+
394
+ // Intentionally set m_best_block_index as the last step in this function,
395
+ // after updating prune locks above, and after making any other references
396
+ // to *this, so the BlockUntilSyncedToCurrentChain function (which checks
397
+ // m_best_block_index as an optimization) can be used to wait for the last
398
+ // BlockConnected notification and safely assume that prune locks are
399
+ // updated and that the index object is safe to delete.
400
+ m_best_block_index = block;
390
401
}
0 commit comments