Skip to content

Commit 20677ff

Browse files
committed
validation: Guard all chainstates with cs_main
Since these chainstates are: 1. Also vulnerable to the race condition described in the previous commit 2. Documented as having similar semantics as m_active_chainstate we should also protect them with ::cs_main.
1 parent f72d80b commit 20677ff

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

src/validation.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5159,7 +5159,7 @@ double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pin
51595159
}
51605160

51615161
Optional<uint256> ChainstateManager::SnapshotBlockhash() const {
5162-
LOCK(::cs_main); // for m_active_chainstate access
5162+
LOCK(::cs_main);
51635163
if (m_active_chainstate != nullptr) {
51645164
// If a snapshot chainstate exists, it will always be our active.
51655165
return m_active_chainstate->m_from_snapshot_blockhash;
@@ -5169,6 +5169,7 @@ Optional<uint256> ChainstateManager::SnapshotBlockhash() const {
51695169

51705170
std::vector<CChainState*> ChainstateManager::GetAll()
51715171
{
5172+
LOCK(::cs_main);
51725173
std::vector<CChainState*> out;
51735174

51745175
if (!IsSnapshotValidated() && m_ibd_chainstate) {
@@ -5213,11 +5214,13 @@ CChainState& ChainstateManager::ActiveChainstate() const
52135214

52145215
bool ChainstateManager::IsSnapshotActive() const
52155216
{
5216-
return m_snapshot_chainstate && WITH_LOCK(::cs_main, return m_active_chainstate) == m_snapshot_chainstate.get();
5217+
LOCK(::cs_main);
5218+
return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get();
52175219
}
52185220

52195221
CChainState& ChainstateManager::ValidatedChainstate() const
52205222
{
5223+
LOCK(::cs_main);
52215224
if (m_snapshot_chainstate && IsSnapshotValidated()) {
52225225
return *m_snapshot_chainstate.get();
52235226
}
@@ -5227,6 +5230,7 @@ CChainState& ChainstateManager::ValidatedChainstate() const
52275230

52285231
bool ChainstateManager::IsBackgroundIBD(CChainState* chainstate) const
52295232
{
5233+
LOCK(::cs_main);
52305234
return (m_snapshot_chainstate && chainstate == m_ibd_chainstate.get());
52315235
}
52325236

@@ -5242,12 +5246,10 @@ void ChainstateManager::Unload()
52425246

52435247
void ChainstateManager::Reset()
52445248
{
5249+
LOCK(::cs_main);
52455250
m_ibd_chainstate.reset();
52465251
m_snapshot_chainstate.reset();
5247-
{
5248-
LOCK(::cs_main);
5249-
m_active_chainstate = nullptr;
5250-
}
5252+
m_active_chainstate = nullptr;
52515253
m_snapshot_validated = false;
52525254
}
52535255

src/validation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ class ChainstateManager
802802
//! This is especially important when, e.g., calling ActivateBestChain()
803803
//! on all chainstates because we are not able to hold ::cs_main going into
804804
//! that call.
805-
std::unique_ptr<CChainState> m_ibd_chainstate;
805+
std::unique_ptr<CChainState> m_ibd_chainstate GUARDED_BY(::cs_main);
806806

807807
//! A chainstate initialized on the basis of a UTXO snapshot. If this is
808808
//! non-null, it is always our active chainstate.
@@ -815,7 +815,7 @@ class ChainstateManager
815815
//! This is especially important when, e.g., calling ActivateBestChain()
816816
//! on all chainstates because we are not able to hold ::cs_main going into
817817
//! that call.
818-
std::unique_ptr<CChainState> m_snapshot_chainstate;
818+
std::unique_ptr<CChainState> m_snapshot_chainstate GUARDED_BY(::cs_main);
819819

820820
//! Points to either the ibd or snapshot chainstate; indicates our
821821
//! most-work chain.

0 commit comments

Comments
 (0)