Skip to content

Commit 2bbecc8

Browse files
committed
Merge pull request #4058
55a1db4 Solve chainActive-related locking issues (Wladimir J. van der Laan) e07c943 Add AssertLockHeld for cs_main to ChainActive-using functions (Wladimir J. van der Laan)
2 parents e2bff7d + 55a1db4 commit 2bbecc8

File tree

8 files changed

+267
-252
lines changed

8 files changed

+267
-252
lines changed

src/main.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
474474

475475
bool IsStandardTx(const CTransaction& tx, string& reason)
476476
{
477+
AssertLockHeld(cs_main);
477478
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
478479
reason = "version";
479480
return false;
@@ -556,6 +557,7 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
556557

557558
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
558559
{
560+
AssertLockHeld(cs_main);
559561
// Time based nLockTime implemented in 0.1.6
560562
if (tx.nLockTime == 0)
561563
return true;
@@ -667,6 +669,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs)
667669

668670
int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
669671
{
672+
AssertLockHeld(cs_main);
670673
CBlock blockTmp;
671674

672675
if (pblock == NULL) {
@@ -813,6 +816,7 @@ int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree,
813816
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
814817
bool* pfMissingInputs, bool fRejectInsaneFee)
815818
{
819+
AssertLockHeld(cs_main);
816820
if (pfMissingInputs)
817821
*pfMissingInputs = false;
818822

@@ -958,6 +962,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
958962
{
959963
if (hashBlock == 0 || nIndex == -1)
960964
return 0;
965+
AssertLockHeld(cs_main);
961966

962967
// Find the block it claims to be in
963968
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
@@ -981,6 +986,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
981986

982987
int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
983988
{
989+
AssertLockHeld(cs_main);
984990
int nResult = GetDepthInMainChainINTERNAL(pindexRet);
985991
if (nResult == 0 && !mempool.exists(GetHash()))
986992
return -1; // Not in chain, not in mempool
@@ -1304,6 +1310,7 @@ int GetNumBlocksOfPeers()
13041310

13051311
bool IsInitialBlockDownload()
13061312
{
1313+
LOCK(cs_main);
13071314
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
13081315
return true;
13091316
static int64_t nLastUpdate;
@@ -1323,6 +1330,7 @@ CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
13231330

13241331
void CheckForkWarningConditions()
13251332
{
1333+
AssertLockHeld(cs_main);
13261334
// Before we get past initial download, we cannot reliably alert about forks
13271335
// (we assume we don't get stuck on a fork before the last checkpoint)
13281336
if (IsInitialBlockDownload())
@@ -1368,6 +1376,7 @@ void CheckForkWarningConditions()
13681376

13691377
void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
13701378
{
1379+
AssertLockHeld(cs_main);
13711380
// If we are on a fork that is sufficiently large, set a warning flag
13721381
CBlockIndex* pfork = pindexNewForkTip;
13731382
CBlockIndex* plonger = chainActive.Tip();
@@ -2078,6 +2087,7 @@ void static FindMostWorkChain() {
20782087

20792088
// Try to activate to the most-work chain (thereby connecting it).
20802089
bool ActivateBestChain(CValidationState &state) {
2090+
LOCK(cs_main);
20812091
CBlockIndex *pindexOldTip = chainActive.Tip();
20822092
bool fComplete = false;
20832093
while (!fComplete) {
@@ -2162,6 +2172,7 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos
21622172
if (!ActivateBestChain(state))
21632173
return false;
21642174

2175+
LOCK(cs_main);
21652176
if (pindexNew == chainActive.Tip())
21662177
{
21672178
// Clear fork warning if its no longer applicable
@@ -2344,6 +2355,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
23442355

23452356
bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
23462357
{
2358+
AssertLockHeld(cs_main);
23472359
// Check for duplicate
23482360
uint256 hash = block.GetHash();
23492361
if (mapBlockIndex.count(hash))
@@ -2455,6 +2467,7 @@ bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, uns
24552467

24562468
int64_t CBlockIndex::GetMedianTime() const
24572469
{
2470+
AssertLockHeld(cs_main);
24582471
const CBlockIndex* pindex = this;
24592472
for (int i = 0; i < nMedianTimeSpan/2; i++)
24602473
{
@@ -2467,6 +2480,7 @@ int64_t CBlockIndex::GetMedianTime() const
24672480

24682481
void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
24692482
{
2483+
AssertLockHeld(cs_main);
24702484
// Filter out duplicate requests
24712485
if (pindexBegin == pnode->pindexLastGetBlocksBegin && hashEnd == pnode->hashLastGetBlocksEnd)
24722486
return;
@@ -2948,6 +2962,7 @@ bool LoadBlockIndex()
29482962

29492963

29502964
bool InitBlockIndex() {
2965+
LOCK(cs_main);
29512966
// Check whether we're already initialized
29522967
if (chainActive.Genesis() != NULL)
29532968
return true;
@@ -2983,6 +2998,7 @@ bool InitBlockIndex() {
29832998

29842999
void PrintBlockTree()
29853000
{
3001+
AssertLockHeld(cs_main);
29863002
// pre-compute tree structure
29873003
map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
29883004
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
@@ -4186,6 +4202,10 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
41864202
}
41874203
}
41884204

4205+
TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
4206+
if (!lockMain)
4207+
return true;
4208+
41894209
// Address refresh broadcast
41904210
static int64_t nLastRebroadcast;
41914211
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
@@ -4236,10 +4256,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
42364256
pto->PushMessage("addr", vAddr);
42374257
}
42384258

4239-
TRY_LOCK(cs_main, lockMain);
4240-
if (!lockMain)
4241-
return true;
4242-
42434259
CNodeState &state = *State(pto->GetId());
42444260
if (state.fShouldBan) {
42454261
if (pto->addr.IsLocal())

src/qt/clientmodel.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ int ClientModel::getNumConnections(unsigned int flags) const
5555

5656
int ClientModel::getNumBlocks() const
5757
{
58+
LOCK(cs_main);
5859
return chainActive.Height();
5960
}
6061

@@ -76,6 +77,7 @@ quint64 ClientModel::getTotalBytesSent() const
7677

7778
QDateTime ClientModel::getLastBlockDate() const
7879
{
80+
LOCK(cs_main);
7981
if (chainActive.Tip())
8082
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
8183
else
@@ -84,6 +86,7 @@ QDateTime ClientModel::getLastBlockDate() const
8486

8587
double ClientModel::getVerificationProgress() const
8688
{
89+
LOCK(cs_main);
8790
return Checkpoints::GuessVerificationProgress(chainActive.Tip());
8891
}
8992

0 commit comments

Comments
 (0)