From 47885e97bf1a7dbcdc7ce6ec129984ed4598792e Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 11 Dec 2020 02:06:16 +0000 Subject: [PATCH] ci: tighten locking in signblock to ensure consistent main/wallet locking order --- src/wallet/rpcwallet.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ca6488e1d9..cd6ebba6c7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5166,29 +5166,31 @@ static RPCHelpMan signblock() throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); ChainstateManager& chainman = g_chainman; // FIXME avoid using this global, see #19413 - LOCK(cs_main); LegacyScriptPubKeyMan* spk_man = pwallet->GetLegacyScriptPubKeyMan(); if (!spk_man) { throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command"); } - uint256 hash = block.GetHash(); - BlockMap::iterator mi = chainman.BlockIndex().find(hash); - if (mi != chainman.BlockIndex().end()) - throw JSONRPCError(RPC_VERIFY_ERROR, "already have block"); + { + LOCK(cs_main); + uint256 hash = block.GetHash(); + BlockMap::iterator mi = chainman.BlockIndex().find(hash); + if (mi != chainman.BlockIndex().end()) + throw JSONRPCError(RPC_VERIFY_ERROR, "already have block"); - CBlockIndex* const pindexPrev = ::ChainActive().Tip(); - // TestBlockValidity only supports blocks built on the current Tip - if (block.hashPrevBlock != pindexPrev->GetBlockHash()) - throw JSONRPCError(RPC_VERIFY_ERROR, "proposal was not based on our best chain"); + CBlockIndex* const pindexPrev = ::ChainActive().Tip(); + // TestBlockValidity only supports blocks built on the current Tip + if (block.hashPrevBlock != pindexPrev->GetBlockHash()) + throw JSONRPCError(RPC_VERIFY_ERROR, "proposal was not based on our best chain"); - BlockValidationState state; - if (!TestBlockValidity(state, Params(), block, pindexPrev, false, true) || !state.IsValid()) { - std::string strRejectReason = state.GetRejectReason(); - if (strRejectReason.empty()) - throw JSONRPCError(RPC_VERIFY_ERROR, state.IsInvalid() ? "Block proposal was invalid" : "Error checking block proposal"); - throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason); + BlockValidationState state; + if (!TestBlockValidity(state, Params(), block, pindexPrev, false, true) || !state.IsValid()) { + std::string strRejectReason = state.GetRejectReason(); + if (strRejectReason.empty()) + throw JSONRPCError(RPC_VERIFY_ERROR, state.IsInvalid() ? "Block proposal was invalid" : "Error checking block proposal"); + throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason); + } } // Expose SignatureData internals in return value in lieu of "Partially Signed Bitcoin Blocks"