Skip to content

Commit fa5c346

Browse files
author
MarcoFalke
committed
doc: Add comment to cs_main and mempool::cs
1 parent fafe941 commit fa5c346

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

src/txmempool.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,43 @@ class CTxMemPool
485485
>
486486
> indexed_transaction_set;
487487

488-
mutable CCriticalSection cs;
488+
/**
489+
* This mutex needs to be locked when accessing `mapTx` or other members
490+
* that are guarded by it.
491+
*
492+
* @par Consistency guarantees
493+
*
494+
* By design, it is guaranteed that:
495+
*
496+
* 1. Locking both `cs_main` and `mempool.cs` will give a view of mempool
497+
* that is consistent with current chain tip (`chainActive` and
498+
* `pcoinsTip`) and is fully populated. Fully populated means that if the
499+
* current active chain is missing transactions that were present in a
500+
* previously active chain, all the missing transactions will have been
501+
* re-added to the mempool and should be present if they meet size and
502+
* consistency constraints.
503+
*
504+
* 2. Locking `mempool.cs` without `cs_main` will give a view of a mempool
505+
* consistent with some chain that was active since `cs_main` was last
506+
* locked, and that is fully populated as described above. It is ok for
507+
* code that only needs to query or remove transactions from the mempool
508+
* to lock just `mempool.cs` without `cs_main`.
509+
*
510+
* To provide these guarantees, it is necessary to lock both `cs_main` and
511+
* `mempool.cs` whenever adding transactions to the mempool and whenever
512+
* changing the chain tip. It's necessary to keep both mutexes locked until
513+
* the mempool is consistent with the new chain tip and fully populated.
514+
*
515+
* @par Consistency bug
516+
*
517+
* The second guarantee above is not currently enforced, but
518+
* https://github.com/bitcoin/bitcoin/pull/14193 will fix it. No known code
519+
* in bitcoin currently depends on second guarantee, but it is important to
520+
* fix for third party code that needs be able to frequently poll the
521+
* mempool without locking `cs_main` and without encountering missing
522+
* transactions during reorgs.
523+
*/
524+
mutable RecursiveMutex cs;
489525
indexed_transaction_set mapTx GUARDED_BY(cs);
490526

491527
using txiter = indexed_transaction_set::nth_index<0>::type::const_iterator;

src/validation.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,17 @@ class CChainState {
210210
bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
211211
} g_chainstate;
212212

213-
214-
215-
CCriticalSection cs_main;
213+
/**
214+
* Mutex to guard access to validation specific variables, such as reading
215+
* or changing the chainstate.
216+
*
217+
* This may also need to be locked when updating the transaction pool, e.g. on
218+
* AcceptToMemoryPool. See CTxMemPool::cs comment for details.
219+
*
220+
* The transaction pool has a separate lock to allow reading from it and the
221+
* chainstate at the same time.
222+
*/
223+
RecursiveMutex cs_main;
216224

217225
BlockMap& mapBlockIndex = g_chainstate.mapBlockIndex;
218226
CChain& chainActive = g_chainstate.chainActive;

0 commit comments

Comments
 (0)