Add AssertLockHeld for cs_main to ChainActive-using functions
All functions that use ChainActive but do not aquire the cs_main lock themselves, need to be called with the cs_main lock held. This commit adds assertions to all externally callable functions that use chainActive or chainMostWork. This will flag usages when built with -DDEBUG_LOCKORDER.
This commit is contained in:
parent
2f3308f2d2
commit
e07c943ce8
15
src/main.cpp
15
src/main.cpp
@ -474,6 +474,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
|
||||
|
||||
bool IsStandardTx(const CTransaction& tx, string& reason)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
|
||||
reason = "version";
|
||||
return false;
|
||||
@ -556,6 +557,7 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
|
||||
|
||||
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Time based nLockTime implemented in 0.1.6
|
||||
if (tx.nLockTime == 0)
|
||||
return true;
|
||||
@ -667,6 +669,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs)
|
||||
|
||||
int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
CBlock blockTmp;
|
||||
|
||||
if (pblock == NULL) {
|
||||
@ -813,6 +816,7 @@ int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree,
|
||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
||||
bool* pfMissingInputs, bool fRejectInsaneFee)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (pfMissingInputs)
|
||||
*pfMissingInputs = false;
|
||||
|
||||
@ -958,6 +962,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
|
||||
{
|
||||
if (hashBlock == 0 || nIndex == -1)
|
||||
return 0;
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// Find the block it claims to be in
|
||||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
|
||||
@ -981,6 +986,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
|
||||
|
||||
int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
int nResult = GetDepthInMainChainINTERNAL(pindexRet);
|
||||
if (nResult == 0 && !mempool.exists(GetHash()))
|
||||
return -1; // Not in chain, not in mempool
|
||||
@ -1304,6 +1310,7 @@ int GetNumBlocksOfPeers()
|
||||
|
||||
bool IsInitialBlockDownload()
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
|
||||
return true;
|
||||
static int64_t nLastUpdate;
|
||||
@ -1323,6 +1330,7 @@ CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
|
||||
|
||||
void CheckForkWarningConditions()
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Before we get past initial download, we cannot reliably alert about forks
|
||||
// (we assume we don't get stuck on a fork before the last checkpoint)
|
||||
if (IsInitialBlockDownload())
|
||||
@ -1368,6 +1376,7 @@ void CheckForkWarningConditions()
|
||||
|
||||
void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// If we are on a fork that is sufficiently large, set a warning flag
|
||||
CBlockIndex* pfork = pindexNewForkTip;
|
||||
CBlockIndex* plonger = chainActive.Tip();
|
||||
@ -2078,6 +2087,7 @@ void static FindMostWorkChain() {
|
||||
|
||||
// Try to activate to the most-work chain (thereby connecting it).
|
||||
bool ActivateBestChain(CValidationState &state) {
|
||||
AssertLockHeld(cs_main);
|
||||
CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||
bool fComplete = false;
|
||||
while (!fComplete) {
|
||||
@ -2126,6 +2136,7 @@ bool ActivateBestChain(CValidationState &state) {
|
||||
|
||||
bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Check for duplicate
|
||||
uint256 hash = block.GetHash();
|
||||
if (mapBlockIndex.count(hash))
|
||||
@ -2344,6 +2355,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
|
||||
|
||||
bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Check for duplicate
|
||||
uint256 hash = block.GetHash();
|
||||
if (mapBlockIndex.count(hash))
|
||||
@ -2455,6 +2467,7 @@ bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, uns
|
||||
|
||||
int64_t CBlockIndex::GetMedianTime() const
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
const CBlockIndex* pindex = this;
|
||||
for (int i = 0; i < nMedianTimeSpan/2; i++)
|
||||
{
|
||||
@ -2467,6 +2480,7 @@ int64_t CBlockIndex::GetMedianTime() const
|
||||
|
||||
void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Filter out duplicate requests
|
||||
if (pindexBegin == pnode->pindexLastGetBlocksBegin && hashEnd == pnode->hashLastGetBlocksEnd)
|
||||
return;
|
||||
@ -2983,6 +2997,7 @@ bool InitBlockIndex() {
|
||||
|
||||
void PrintBlockTree()
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// pre-compute tree structure
|
||||
map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
|
||||
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (!IsFinalTx(wtx, chainActive.Height() + 1))
|
||||
{
|
||||
if (wtx.nLockTime < LOCKTIME_THRESHOLD)
|
||||
|
@ -150,6 +150,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
||||
|
||||
void TransactionRecord::updateStatus(const CWalletTx &wtx)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Determine transaction status
|
||||
|
||||
// Find the block the tx is in
|
||||
@ -234,6 +235,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
|
||||
|
||||
bool TransactionRecord::statusUpdateNeeded()
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
return status.cur_num_blocks != chainActive.Height();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user