Hopefully this’ll make everyone happy, and clarify some chainstate locking issues going forward.
Background
There is some amount of confusion due to my choice to conflate use of cs_main
between
- its original purpose: guarding legacy data structures related to CChainState-related data (i.e. pre-
ChainstateManager
coverage ofchainActive
), and - its new purpose: guarding pointers to the constituent CChainState instances managed by ChainstateManager, e.g.
m_ibd_chainstate
,m_active_chainstate
.
I initially thought that reusing cs_main would be a simplification, but it turned out to just be mostly confusing.
As a quick refresher, ChainstateManager manages two constituent CChainState instances (m_ibd_chainstate
, m_snapshot_chainstate
) and reveals a pointer to the one that is in active use (m_active_chainstate
) per the assumeutxo semantics. As @jnewbery has pointed out, the active pointer doesn’t need to be guarded by a mutex, but can be marked atomic
to avoid explicit locking.
Throughout the course of deglobalizing chainstate use, @dongcarl has had to embed cs_main
acquisitions in the active chainstate accessor functions (e.g. ::ChainstateActive()) to avoid the risk of unserialized access to the ChainstateManager::m_active_chainstate
state. This is suboptimal because callers are almost always already holding cs_main anyway, so we just end up recursively acquiring the lock in many cases. And fundamentally, cs_main use isn’t necessary for that once we decouple chainstate pointer management from cs_main.
These changes
- make
ChainstateManager::m_active_chainstate
atomic to avoid requiring explicit locking (per @jnewbery’s suggestion), - introduce
ChainstateManager::m_cs_chainstates
to relieve cs_main of guarding the internal chainstates managed by ChainstateManager, - remove the
cs_main
acquisitions in::ChainstateActive()
andChainstateManager::ActiveChainstate()
, which are no longer necessary, and - annotate
CChainState::m_chain
as guarded by cs_main, which was an implicit requirement that I’m just making explicit here.