@@ -170,7 +170,8 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn
170170 case TxVerbosity::SHOW_DETAILS:
171171 case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
172172 CBlockUndo blockUndo;
173- const bool have_undo{WITH_LOCK (::cs_main, return !blockman.IsBlockPruned (blockindex) && UndoReadFromDisk (blockUndo, blockindex))};
173+ const bool is_not_pruned{WITH_LOCK (::cs_main, return !blockman.IsBlockPruned (blockindex))};
174+ const bool have_undo{is_not_pruned && UndoReadFromDisk (blockUndo, blockindex)};
174175
175176 for (size_t i = 0 ; i < block.vtx .size (); ++i) {
176177 const CTransactionRef& tx = block.vtx .at (i);
@@ -762,34 +763,38 @@ static RPCHelpMan getblockheaders()
762763 };
763764}
764765
765- static CBlock GetBlockChecked (BlockManager& blockman, const CBlockIndex* pblockindex) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
766+ static CBlock GetBlockChecked (BlockManager& blockman, const CBlockIndex* pblockindex)
766767{
767- AssertLockHeld (::cs_main);
768768 CBlock block;
769- if (blockman.IsBlockPruned (pblockindex)) {
770- throw JSONRPCError (RPC_MISC_ERROR, " Block not available (pruned data)" );
769+ {
770+ LOCK (cs_main);
771+ if (blockman.IsBlockPruned (pblockindex)) {
772+ throw JSONRPCError (RPC_MISC_ERROR, " Block not available (pruned data)" );
773+ }
771774 }
772775
773776 if (!ReadBlockFromDisk (block, pblockindex, Params ().GetConsensus ())) {
774777 // Block not found on disk. This could be because we have the block
775778 // header in our index but not yet have the block or did not accept the
776- // block.
779+ // block. Or if the block was pruned right after we released the lock above.
777780 throw JSONRPCError (RPC_MISC_ERROR, " Block not found on disk" );
778781 }
779782
780783 return block;
781784}
782785
783- static CBlockUndo GetUndoChecked (BlockManager& blockman, const CBlockIndex* pblockindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
786+ static CBlockUndo GetUndoChecked (BlockManager& blockman, const CBlockIndex* pblockindex)
784787{
785- AssertLockHeld (::cs_main);
786788 CBlockUndo blockUndo;
787789
788790 // The Genesis block does not have undo data
789791 if (pblockindex->nHeight == 0 ) return blockUndo;
790792
791- if (blockman.IsBlockPruned (pblockindex)) {
792- throw JSONRPCError (RPC_MISC_ERROR, " Undo data not available (pruned data)" );
793+ {
794+ LOCK (cs_main);
795+ if (blockman.IsBlockPruned (pblockindex)) {
796+ throw JSONRPCError (RPC_MISC_ERROR, " Undo data not available (pruned data)" );
797+ }
793798 }
794799
795800 if (!UndoReadFromDisk (blockUndo, pblockindex)) {
@@ -982,7 +987,6 @@ static RPCHelpMan getblock()
982987
983988 const NodeContext& node = EnsureAnyNodeContext (request.context );
984989
985- CBlock block;
986990 const CBlockIndex* pblockindex;
987991 const CBlockIndex* tip;
988992 ChainstateManager& chainman = EnsureChainman (node);
@@ -994,10 +998,10 @@ static RPCHelpMan getblock()
994998 if (!pblockindex) {
995999 throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Block not found" );
9961000 }
997-
998- block = GetBlockChecked (chainman.m_blockman , pblockindex);
9991001 }
10001002
1003+ const CBlock block{GetBlockChecked (chainman.m_blockman , pblockindex)};
1004+
10011005 if (verbosity <= 0 )
10021006 {
10031007 CDataStream ssBlock (SER_NETWORK, PROTOCOL_VERSION);
@@ -2023,7 +2027,6 @@ static RPCHelpMan getblockstats()
20232027 }
20242028
20252029 ChainstateManager& chainman = EnsureAnyChainman (request.context );
2026- LOCK (cs_main);
20272030 const CBlockIndex& pindex{*CHECK_NONFATAL (ParseHashOrHeight (request.params [0 ], chainman))};
20282031
20292032 std::set<std::string> stats;
0 commit comments