diff --git a/src/chain.cpp b/src/chain.cpp index 157669bc15..113bc1d3cd 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -56,7 +56,8 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { return CBlockLocator(vHave); } -void CBlockIndex::untrim() { +void CBlockIndex::untrim() EXCLUSIVE_LOCKS_REQUIRED(::cs_main){ + AssertLockHeld(::cs_main); if (!trimmed()) return; CBlockIndex tmp; @@ -70,12 +71,10 @@ void CBlockIndex::untrim() { m_pcontext->chainman->m_blockman.m_dirty_blockindex.insert(this); } -const CBlockIndex *CBlockIndex::untrim_to(CBlockIndex *pindexNew) const +const CBlockIndex *CBlockIndex::untrim_to(CBlockIndex *pindexNew) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { - if (m_pcontext) { - return m_pcontext->chainman->m_blockman.m_block_tree_db->RegenerateFullIndex(this, pindexNew); - } - return nullptr; + AssertLockHeld(::cs_main); + return m_pcontext->chainman->m_blockman.m_block_tree_db->RegenerateFullIndex(this, pindexNew); } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { diff --git a/src/dynafed.cpp b/src/dynafed.cpp index 29a2029483..60f1cbbc4c 100644 --- a/src/dynafed.cpp +++ b/src/dynafed.cpp @@ -16,7 +16,10 @@ bool NextBlockIsParameterTransition(const CBlockIndex* pindexPrev, const Consens for (int32_t height = next_height - 1; height >= (int32_t)(next_height - consensus.dynamic_epoch_length); --height) { const CBlockIndex* p_epoch_walk = pindexPrev->GetAncestor(height); assert(p_epoch_walk); - ForceUntrimHeader(p_epoch_walk); + { + LOCK(cs_main); + ForceUntrimHeader(p_epoch_walk); + } const DynaFedParamEntry& proposal = p_epoch_walk->dynafed_params().m_proposed; const uint256 proposal_root = proposal.CalculateRoot(); vote_tally[proposal_root]++; @@ -62,7 +65,10 @@ DynaFedParamEntry ComputeNextBlockFullCurrentParameters(const CBlockIndex* pinde // may be pre-dynafed params const CBlockIndex* p_epoch_start = pindexPrev->GetAncestor(epoch_start_height); assert(p_epoch_start); - ForceUntrimHeader(p_epoch_start); + { + LOCK(cs_main); + ForceUntrimHeader(p_epoch_start); + } if (p_epoch_start->dynafed_params().IsNull()) { // We need to construct the "full" current parameters of pre-dynafed // consensus @@ -96,7 +102,10 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre { assert(pindexPrev); - ForceUntrimHeader(pindexPrev); + { + LOCK(cs_main); + ForceUntrimHeader(pindexPrev); + } DynaFedParamEntry entry = ComputeNextBlockFullCurrentParameters(pindexPrev, consensus); uint32_t next_height = pindexPrev->nHeight+1; diff --git a/src/pegins.cpp b/src/pegins.cpp index 60e3b3f4b1..c5e2794dc7 100644 --- a/src/pegins.cpp +++ b/src/pegins.cpp @@ -489,7 +489,10 @@ std::vector> GetValidFedpegScripts(const CBlockIndex break; } - ForceUntrimHeader(p_epoch_start); + { + LOCK(cs_main); + ForceUntrimHeader(p_epoch_start); + } if (!p_epoch_start->dynafed_params().IsNull()) { fedpegscripts.push_back(std::make_pair(p_epoch_start->dynafed_params().m_current.m_fedpeg_program, p_epoch_start->dynafed_params().m_current.m_fedpegscript)); } else { diff --git a/src/rest.cpp b/src/rest.cpp index 6f79834dcd..f7376e814d 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -232,6 +232,7 @@ static bool rest_headers(const std::any& context, case RetFormat::BINARY: { CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); for (const CBlockIndex *pindex : headers) { + LOCK(cs_main); CBlockIndex tmpBlockIndexFull; const CBlockIndex* pindexfull=pindex->untrim_to(&tmpBlockIndexFull); ssHeader << pindexfull->GetBlockHeader(); @@ -246,6 +247,7 @@ static bool rest_headers(const std::any& context, case RetFormat::HEX: { CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); for (const CBlockIndex *pindex : headers) { + LOCK(cs_main); CBlockIndex tmpBlockIndexFull; const CBlockIndex* pindexfull=pindex->untrim_to(&tmpBlockIndexFull); ssHeader << pindexfull->GetBlockHeader(); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 37691ec51d..a7a60dbddd 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -199,7 +199,11 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex AssertLockNotHeld(cs_main); // For performance reasons CBlockIndex tmpBlockIndexFull; - const CBlockIndex* blockindex=blockindex_->untrim_to(&tmpBlockIndexFull); + const CBlockIndex* blockindex; + { + LOCK(cs_main); + blockindex = blockindex_->untrim_to(&tmpBlockIndexFull); + } UniValue result(UniValue::VOBJ); result.pushKV("hash", blockindex->GetBlockHash().GetHex()); @@ -1020,6 +1024,7 @@ static RPCHelpMan getblockheader() if (!fVerbose) { + LOCK(cs_main); CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); CBlockIndex tmpBlockIndexFull; const CBlockIndex* pblockindexfull=pblockindex->untrim_to(&tmpBlockIndexFull); diff --git a/src/txdb.cpp b/src/txdb.cpp index 0b7af3787e..d1fe0394cb 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -333,15 +333,14 @@ bool CBlockTreeDB::WritePAKList(const std::vector >& const CBlockIndex *CBlockTreeDB::RegenerateFullIndex(const CBlockIndex *pindexTrimmed, CBlockIndex *pindexNew) const { + LOCK(cs_main); + if(!pindexTrimmed->trimmed()) { return pindexTrimmed; } CBlockHeader tmp; bool BlockRead = false; { - // At this point we can either be locked or unlocked depending on where we're being called - // but cs_main is a RecursiveMutex, so it doesn't matter - LOCK(cs_main); // In unpruned nodes, same data could be read from blocks using ReadBlockFromDisk, but that turned out to // be about 6x slower than reading from the index std::pair key(DB_BLOCK_INDEX, pindexTrimmed->GetBlockHash()); diff --git a/src/validation.cpp b/src/validation.cpp index 9702071a3b..b6fc6d4fd7 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2717,13 +2717,14 @@ static void UpdateTipLog( !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages) : ""); } -void ForceUntrimHeader(const CBlockIndex *pindex_) +void ForceUntrimHeader(const CBlockIndex *pindex_) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(cs_main); + assert(pindex_); if (!pindex_->trimmed()) { return; } - AssertLockHeld(cs_main); CBlockIndex *pindex=const_cast(pindex_); pindex->untrim(); }