diff --git a/src/rest.cpp b/src/rest.cpp --- a/src/rest.cpp +++ b/src/rest.cpp @@ -213,12 +213,12 @@ std::vector headers; headers.reserve(count); { - LOCK(cs_main); ChainstateManager *maybe_chainman = GetChainman(context, req); if (!maybe_chainman) { return false; } ChainstateManager &chainman = *maybe_chainman; + LOCK(cs_main); CChain &active_chain = chainman.ActiveChain(); tip = active_chain.Tip(); const CBlockIndex *pindex = chainman.m_blockman.LookupBlockIndex(hash); @@ -294,12 +294,12 @@ CBlockIndex *pblockindex = nullptr; CBlockIndex *tip = nullptr; { - LOCK(cs_main); ChainstateManager *maybe_chainman = GetChainman(context, req); if (!maybe_chainman) { return false; } ChainstateManager &chainman = *maybe_chainman; + LOCK(cs_main); tip = chainman.ActiveTip(); pblockindex = chainman.m_blockman.LookupBlockIndex(hash); if (!pblockindex) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -179,8 +179,9 @@ HelpExampleRpc("getblockcount", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - return EnsureAnyChainman(request.context).ActiveHeight(); + return chainman.ActiveHeight(); }, }; } @@ -196,11 +197,9 @@ HelpExampleRpc("getbestblockhash", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - return EnsureAnyChainman(request.context) - .ActiveTip() - ->GetBlockHash() - .GetHex(); + return chainman.ActiveTip()->GetBlockHash().GetHex(); }, }; } @@ -215,9 +214,9 @@ HelpExampleRpc("getfinalizedblockhash", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - CChainState &active_chainstate = - EnsureAnyChainman(request.context).ActiveChainstate(); + CChainState &active_chainstate = chainman.ActiveChainstate(); const CBlockIndex *blockIndexFinalized = active_chainstate.GetFinalizedBlock(); if (blockIndexFinalized) { @@ -446,9 +445,9 @@ HelpExampleRpc("getdifficulty", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - return GetDifficulty( - EnsureAnyChainman(request.context).ActiveTip()); + return GetDifficulty(chainman.ActiveTip()); }, }; } @@ -875,9 +874,9 @@ HelpExampleRpc("getblockhash", "1000")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - const CChain &active_chain = - EnsureAnyChainman(request.context).ActiveChain(); + const CChain &active_chain = chainman.ActiveChain(); int nHeight = request.params[0].get_int(); if (nHeight < 0 || nHeight > active_chain.Height()) { @@ -963,9 +962,9 @@ const CBlockIndex *pblockindex; const CBlockIndex *tip; { - LOCK(cs_main); ChainstateManager &chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); pblockindex = chainman.m_blockman.LookupBlockIndex(hash); tip = chainman.ActiveTip(); } @@ -1125,9 +1124,9 @@ const CBlockIndex *pblockindex; const CBlockIndex *tip; { - LOCK(cs_main); ChainstateManager &chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); pblockindex = chainman.m_blockman.LookupBlockIndex(hash); tip = chainman.ActiveTip(); @@ -1176,8 +1175,8 @@ "Cannot prune blocks because node is not in prune mode."); } - LOCK(cs_main); ChainstateManager &chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); int heightParam = request.params[0].get_int(); if (heightParam < 0) { @@ -1286,8 +1285,9 @@ UniValue ret(UniValue::VOBJ); CCoinsStats stats; - CChainState &active_chainstate = - EnsureAnyChainman(request.context).ActiveChainstate(); + NodeContext &node = EnsureAnyNodeContext(request.context); + ChainstateManager &chainman = EnsureChainman(node); + CChainState &active_chainstate = chainman.ActiveChainstate(); active_chainstate.ForceFlushStateToDisk(); const CoinStatsHashType hash_type{ @@ -1302,7 +1302,6 @@ coins_view = &active_chainstate.CoinsDB(); blockman = &active_chainstate.m_blockman; } - NodeContext &node = EnsureAnyNodeContext(request.context); if (GetUTXOStats(coins_view, *blockman, stats, hash_type, node.rpc_interruption_point)) { ret.pushKV("height", int64_t(stats.nHeight)); @@ -1380,6 +1379,8 @@ HelpExampleRpc("gettxout", "\"txid\", 1")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + NodeContext &node = EnsureAnyNodeContext(request.context); + ChainstateManager &chainman = EnsureChainman(node); LOCK(cs_main); UniValue ret(UniValue::VOBJ); @@ -1393,12 +1394,11 @@ } Coin coin; - CChainState &active_chainstate = - EnsureAnyChainman(request.context).ActiveChainstate(); + CChainState &active_chainstate = chainman.ActiveChainstate(); CCoinsViewCache *coins_view = &active_chainstate.CoinsTip(); if (fMempool) { - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); LOCK(mempool.cs); CCoinsViewMemPool view(coins_view, mempool); if (!view.GetCoin(out, coin) || mempool.isSpent(out)) { @@ -1456,10 +1456,10 @@ ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()}; + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - CChainState &active_chainstate = - EnsureAnyChainman(request.context).ActiveChainstate(); + CChainState &active_chainstate = chainman.ActiveChainstate(); return CVerifyDB().VerifyDB(active_chainstate, config, active_chainstate.CoinsTip(), check_level, check_depth); @@ -1646,11 +1646,10 @@ HelpExampleRpc("getblockchaininfo", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { - LOCK(cs_main); - const CChainParams &chainparams = config.GetChainParams(); ChainstateManager &chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); const CBlockIndex *tip = chainman.ActiveTip(); CHECK_NONFATAL(tip); @@ -2387,8 +2386,8 @@ R"(1000, ["minfeerate","avgfeerate"])")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { - LOCK(cs_main); ChainstateManager &chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); CBlockIndex *pindex; if (request.params[0].isNum()) { @@ -2870,10 +2869,10 @@ int64_t count = 0; std::unique_ptr pcursor; CBlockIndex *tip; + NodeContext &node = EnsureAnyNodeContext(request.context); { + ChainstateManager &chainman = EnsureChainman(node); LOCK(cs_main); - ChainstateManager &chainman = - EnsureAnyChainman(request.context); chainman.ActiveChainstate().ForceFlushStateToDisk(); pcursor = std::unique_ptr( chainman.ActiveChainstate().CoinsDB().Cursor()); @@ -2881,7 +2880,6 @@ tip = chainman.ActiveTip(); CHECK_NONFATAL(tip); } - NodeContext &node = EnsureAnyNodeContext(request.context); bool res = FindScriptPubKey( g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins, node.rpc_interruption_point); @@ -2968,9 +2966,10 @@ const CBlockIndex *block_index; bool block_was_connected; { + ChainstateManager &chainman = + EnsureAnyChainman(request.context); LOCK(cs_main); - block_index = EnsureAnyChainman(request.context) - .m_blockman.LookupBlockIndex(block_hash); + block_index = chainman.m_blockman.LookupBlockIndex(block_hash); if (!block_index) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -112,13 +112,12 @@ HelpExampleRpc("getnetworkhashps", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + ChainstateManager &chainman = EnsureAnyChainman(request.context); LOCK(cs_main); - const CChain &active_chain = - EnsureAnyChainman(request.context).ActiveChain(); return GetNetworkHashPS( !request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1, - active_chain); + chainman.ActiveChain()); }, }; } @@ -281,8 +280,9 @@ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); } - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); - ChainstateManager &chainman = EnsureAnyChainman(request.context); + NodeContext &node = EnsureAnyNodeContext(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); + ChainstateManager &chainman = EnsureChainman(node); return generateBlocks(config, chainman, mempool, coinbase_script, num_blocks, max_tries); @@ -344,8 +344,9 @@ "Error: Invalid address"); } - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); - ChainstateManager &chainman = EnsureAnyChainman(request.context); + NodeContext &node = EnsureAnyNodeContext(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); + ChainstateManager &chainman = EnsureChainman(node); CScript coinbase_script = GetScriptForDestination(destination); @@ -411,7 +412,8 @@ coinbase_script = GetScriptForDestination(destination); } - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); + NodeContext &node = EnsureAnyNodeContext(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); std::vector txs; const auto raw_txs_or_txids = request.params[1].get_array(); @@ -441,7 +443,7 @@ CBlock block; - ChainstateManager &chainman = EnsureAnyChainman(request.context); + ChainstateManager &chainman = EnsureChainman(node); { LOCK(cs_main); @@ -527,10 +529,11 @@ HelpExampleRpc("getmininginfo", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + NodeContext &node = EnsureAnyNodeContext(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); + ChainstateManager &chainman = EnsureChainman(node); LOCK(cs_main); - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); - const CChain &active_chain = - EnsureAnyChainman(request.context).ActiveChain(); + const CChain &active_chain = chainman.ActiveChain(); UniValue obj(UniValue::VOBJ); obj.pushKV("blocks", int(active_chain.Height())); @@ -791,8 +794,9 @@ HelpExampleRpc("getblocktemplate", "")}, [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { + NodeContext &node = EnsureAnyNodeContext(request.context); + ChainstateManager &chainman = EnsureChainman(node); LOCK(cs_main); - ChainstateManager &chainman = EnsureAnyChainman(request.context); const CChainParams &chainparams = config.GetChainParams(); @@ -859,7 +863,6 @@ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); } - NodeContext &node = EnsureAnyNodeContext(request.context); if (!node.connman) { throw JSONRPCError( RPC_CLIENT_P2P_DISABLED, @@ -878,7 +881,7 @@ } static unsigned int nTransactionsUpdatedLast; - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -194,7 +194,7 @@ [&](const RPCHelpMan &self, const Config &config, const JSONRPCRequest &request) -> UniValue { const NodeContext &node = EnsureAnyNodeContext(request.context); - ChainstateManager &chainman = EnsureAnyChainman(request.context); + ChainstateManager &chainman = EnsureChainman(node); bool in_active_chain = true; TxId txid = TxId(ParseHashV(request.params[0], "parameter 1")); @@ -446,9 +446,8 @@ return res; } - LOCK(cs_main); - ChainstateManager &chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); const CBlockIndex *pindex = chainman.m_blockman.LookupBlockIndex( merkleBlock.header.GetHash()); @@ -783,12 +782,12 @@ CCoinsView viewDummy; CCoinsViewCache view(&viewDummy); { - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); - LOCK(cs_main); - LOCK(mempool.cs); - CCoinsViewCache &viewChain = EnsureAnyChainman(request.context) - .ActiveChainstate() - .CoinsTip(); + NodeContext &node = EnsureAnyNodeContext(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); + ChainstateManager &chainman = EnsureChainman(node); + LOCK2(cs_main, mempool.cs); + CCoinsViewCache &viewChain = + chainman.ActiveChainstate().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, mempool); // temporarily switch cache backend to db+mempool view view.SetBackend(viewMempool); @@ -1145,7 +1144,9 @@ ? DEFAULT_MAX_RAW_TX_FEE_RATE : CFeeRate(AmountFromValue(request.params[1])); - CTxMemPool &mempool = EnsureAnyMemPool(request.context); + NodeContext &node = EnsureAnyNodeContext(request.context); + + CTxMemPool &mempool = EnsureMemPool(node); int64_t virtual_size = GetVirtualTransactionSize(*tx); Amount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size); @@ -1156,13 +1157,13 @@ TxValidationState state; bool test_accept_res; Amount fee = Amount::zero(); - { - LOCK(cs_main); - test_accept_res = AcceptToMemoryPool( - EnsureAnyChainman(request.context).ActiveChainstate(), - config, mempool, state, std::move(tx), - false /* bypass_limits */, true /* test_accept */, &fee); - } + ChainstateManager &chainman = EnsureChainman(node); + + test_accept_res = WITH_LOCK( + cs_main, return AcceptToMemoryPool( + chainman.ActiveChainstate(), config, mempool, + state, std::move(tx), false /* bypass_limits */, + true /* test_accept */, &fee)); // Check that fee does not exceed maximum fee if (test_accept_res && max_raw_tx_fee != Amount::zero() && @@ -1914,11 +1915,12 @@ CCoinsView viewDummy; CCoinsViewCache view(&viewDummy); { - const CTxMemPool &mempool = EnsureAnyMemPool(request.context); + NodeContext &node = EnsureAnyNodeContext(request.context); + const CTxMemPool &mempool = EnsureMemPool(node); + ChainstateManager &chainman = EnsureChainman(node); LOCK2(cs_main, mempool.cs); - CCoinsViewCache &viewChain = EnsureAnyChainman(request.context) - .ActiveChainstate() - .CoinsTip(); + CCoinsViewCache &viewChain = + chainman.ActiveChainstate().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, mempool); // temporarily switch cache backend to db+mempool view view.SetBackend(viewMempool);