diff --git a/src/chain.h b/src/chain.h index fbc033281ff..8b03e66a96f 100644 --- a/src/chain.h +++ b/src/chain.h @@ -164,13 +164,13 @@ public: int nHeight{0}; //! Which # file this block is stored in (blk?????.dat) - int nFile{0}; + int nFile GUARDED_BY(::cs_main){0}; //! Byte offset within blk?????.dat where this block's data is stored - unsigned int nDataPos{0}; + unsigned int nDataPos GUARDED_BY(::cs_main){0}; //! Byte offset within rev?????.dat where this block's undo data is stored - unsigned int nUndoPos{0}; + unsigned int nUndoPos GUARDED_BY(::cs_main){0}; //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block arith_uint256 nChainWork{}; @@ -198,7 +198,7 @@ public: //! load to avoid the block index being spuriously rewound. //! @sa NeedsRedownload //! @sa ActivateSnapshot - uint32_t nStatus{0}; + uint32_t nStatus GUARDED_BY(::cs_main){0}; //! block header int32_t nVersion{0}; @@ -382,6 +382,7 @@ public: SERIALIZE_METHODS(CDiskBlockIndex, obj) { + LOCK(::cs_main); int _nVersion = s.GetVersion(); if (!(s.GetType() & SER_GETHASH)) READWRITE(VARINT_MODE(_nVersion, VarIntMode::NONNEGATIVE_SIGNED)); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 8df0aac2033..c5697983d51 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -818,7 +818,8 @@ static RPCHelpMan getblockfrompeer() throw JSONRPCError(RPC_MISC_ERROR, "Block header missing"); } - if (index->nStatus & BLOCK_HAVE_DATA) { + const bool block_has_data = WITH_LOCK(::cs_main, return index->nStatus & BLOCK_HAVE_DATA); + if (block_has_data) { throw JSONRPCError(RPC_MISC_ERROR, "Block already downloaded"); } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index f227fde0f70..e7d9f434f45 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -240,7 +240,8 @@ static RPCHelpMan getrawtransaction() if (!tx) { std::string errmsg; if (blockindex) { - if (!(blockindex->nStatus & BLOCK_HAVE_DATA)) { + const bool block_has_data = WITH_LOCK(::cs_main, return blockindex->nStatus & BLOCK_HAVE_DATA); + if (!block_has_data) { throw JSONRPCError(RPC_MISC_ERROR, "Block not available"); } errmsg = "No such transaction found in the provided block"; diff --git a/src/test/interfaces_tests.cpp b/src/test/interfaces_tests.cpp index f4bf6ff8c9d..49b7d2003b4 100644 --- a/src/test/interfaces_tests.cpp +++ b/src/test/interfaces_tests.cpp @@ -123,6 +123,7 @@ BOOST_AUTO_TEST_CASE(findCommonAncestor) BOOST_AUTO_TEST_CASE(hasBlocks) { + LOCK(::cs_main); auto& chain = m_node.chain; const CChain& active = Assert(m_node.chainman)->ActiveChain(); diff --git a/src/txdb.cpp b/src/txdb.cpp index 85eea888cc5..e2aed1da7c7 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -311,19 +311,23 @@ bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, CBlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash()); pindexNew->pprev = insertBlockIndex(diskindex.hashPrev); pindexNew->nHeight = diskindex.nHeight; - pindexNew->nFile = diskindex.nFile; - pindexNew->nDataPos = diskindex.nDataPos; - pindexNew->nUndoPos = diskindex.nUndoPos; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; - pindexNew->nStatus = diskindex.nStatus; pindexNew->nTx = diskindex.nTx; + { + LOCK(::cs_main); + pindexNew->nFile = diskindex.nFile; + pindexNew->nDataPos = diskindex.nDataPos; + pindexNew->nUndoPos = diskindex.nUndoPos; + pindexNew->nStatus = diskindex.nStatus; + } - if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams)) + if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams)) { return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString()); + } pcursor->Next(); } else {