Skip to content

Commit

Permalink
index: race fix, lock cs_main while 'm_synced' is subject to change
Browse files Browse the repository at this point in the history
This ensures that the index does not miss any 'new block' signals
occurring in-between reading the 'next block' and setting 'm_synced'.
Because, if this were to happen, the ignored blocks would never be
indexed, thus stalling the index forever.

Github-Pull: bitcoin#29867
Rebased-From: 65951e0
  • Loading branch information
ryanofsky authored and glozow committed Apr 29, 2024
1 parent bf5b6fc commit 4388b7e
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,25 @@ void BaseIndex::ThreadSync()
}

{
LOCK(cs_main);
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
const CBlockIndex* pindex_next = WITH_LOCK(cs_main, return NextSyncBlock(pindex, m_chainstate->m_chain));
// If pindex_next is null, it means pindex is the chain tip, so
// commit data indexed so far.
if (!pindex_next) {
SetBestBlockIndex(pindex);
m_synced = true;
// No need to handle errors in Commit. See rationale above.
Commit();
break;

// If pindex is still the chain tip after committing, exit the
// sync loop. It is important for cs_main to be locked while
// setting m_synced = true, otherwise a new block could be
// attached while m_synced is still false, and it would not be
// indexed.
LOCK(::cs_main);
pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
if (!pindex_next) {
m_synced = true;
break;
}
}
if (pindex_next->pprev != pindex && !Rewind(pindex, pindex_next->pprev)) {
FatalErrorf("%s: Failed to rewind index %s to a previous chain tip",
Expand Down

0 comments on commit 4388b7e

Please sign in to comment.