From 3e0fcf471fb5847fc0368faf13e2b5caaabe8e1e Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 28 Jun 2024 08:17:05 +0000 Subject: [PATCH] refactor: move accessing CBlockTreeDB global out of Get*Index --- src/rpc/blockchain.cpp | 2 +- src/rpc/index_util.cpp | 26 +++++++++++----- src/rpc/index_util.h | 23 ++++++++++---- src/rpc/misc.cpp | 64 +++++++++++++++++++++++--------------- src/rpc/rawtransaction.cpp | 8 ++--- 5 files changed, 79 insertions(+), 44 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index bef4af863d..524736d560 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -835,7 +835,7 @@ static RPCHelpMan getblockhashes() unsigned int low = request.params[1].get_int(); std::vector blockHashes; - if (!GetTimestampIndex(high, low, blockHashes)) { + if (LOCK(::cs_main); !GetTimestampIndex(*pblocktree, high, low, blockHashes)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for block hashes"); } diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index 0680012e56..d5ba2b1669 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -9,26 +9,30 @@ #include #include -bool GetAddressIndex(const uint160& addressHash, const AddressType type, +bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, std::vector& addressIndex, const int32_t start, const int32_t end) { + AssertLockHeld(::cs_main); + if (!fAddressIndex) return error("Address index not enabled"); - if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) + if (!block_tree_db.ReadAddressIndex(addressHash, type, addressIndex, start, end)) return error("Unable to get txids for address"); return true; } -bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, +bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, std::vector& unspentOutputs) { + AssertLockHeld(::cs_main); + if (!fAddressIndex) return error("Address index not enabled"); - if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) + if (!block_tree_db.ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) return error("Unable to get txids for address"); return true; @@ -47,26 +51,32 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, return true; } -bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) +bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key, + CSpentIndexValue& value) { + AssertLockHeld(::cs_main); + if (!fSpentIndex) return error("Spent index not enabled"); if (mempool.getSpentIndex(key, value)) return true; - if (!pblocktree->ReadSpentIndex(key, value)) + if (!block_tree_db.ReadSpentIndex(key, value)) return error("Unable to get spend information"); return true; } -bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes) +bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low, + std::vector& hashes) { + AssertLockHeld(::cs_main); + if (!fTimestampIndex) return error("Timestamp index not enabled"); - if (!pblocktree->ReadTimestampIndex(high, low, hashes)) + if (!block_tree_db.ReadTimestampIndex(high, low, hashes)) return error("Unable to get hashes for timestamps"); return true; diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index 889a544786..d296721be9 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -12,22 +12,33 @@ #include #include #include +#include +#include +class CBlockTreeDB; class CTxMemPool; class uint160; class uint256; enum class AddressType : uint8_t; -bool GetAddressIndex(const uint160& addressHash, const AddressType type, +extern RecursiveMutex cs_main; + +bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, std::vector& addressIndex, - const int32_t start = 0, const int32_t end = 0); -bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, - std::vector& unspentOutputs); + const int32_t start = 0, const int32_t end = 0) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, + std::vector& unspentOutputs) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main); bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, const std::vector& addressDeltaIndex, std::vector& addressDeltaEntries); -bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value); -bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes); +bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key, + CSpentIndexValue& value) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low, + std::vector& hashes) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main); #endif // BITCOIN_RPC_CLIENT_H diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 6c2f8bd664..eec4baec66 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -822,9 +822,12 @@ static RPCHelpMan getaddressutxos() std::vector unspentOutputs; - for (const auto& address : addresses) { - if (!GetAddressUnspentIndex(address.first, address.second, unspentOutputs)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + { + LOCK(::cs_main); + for (const auto& address : addresses) { + if (!GetAddressUnspentIndex(*pblocktree, address.first, address.second, unspentOutputs)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } } } @@ -907,14 +910,17 @@ static RPCHelpMan getaddressdeltas() std::vector addressIndex; - for (const auto& address : addresses) { - if (start > 0 && end > 0) { - if (!GetAddressIndex(address.first, address.second, addressIndex, start, end)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } else { - if (!GetAddressIndex(address.first, address.second, addressIndex)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + { + LOCK(::cs_main); + for (const auto& address : addresses) { + if (start > 0 && end > 0) { + if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex, start, end)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } else { + if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } } } } @@ -976,14 +982,19 @@ static RPCHelpMan getaddressbalance() std::vector addressIndex; - for (const auto& address : addresses) { - if (!GetAddressIndex(address.first, address.second, addressIndex)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + ChainstateManager& chainman = EnsureAnyChainman(request.context); + + int nHeight; + { + LOCK(::cs_main); + for (const auto& address : addresses) { + if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } } + nHeight = chainman.ActiveChain().Height(); } - ChainstateManager& chainman = EnsureAnyChainman(request.context); - int nHeight = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); CAmount balance = 0; CAmount balance_spendable = 0; @@ -1055,14 +1066,17 @@ static RPCHelpMan getaddresstxids() std::vector addressIndex; - for (const auto& address : addresses) { - if (start > 0 && end > 0) { - if (!GetAddressIndex(address.first, address.second, addressIndex, start, end)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } else { - if (!GetAddressIndex(address.first, address.second, addressIndex)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + { + LOCK(::cs_main); + for (const auto& address : addresses) { + if (start > 0 && end > 0) { + if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex, start, end)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } else { + if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } } } } @@ -1134,7 +1148,7 @@ static RPCHelpMan getspentinfo() CSpentIndexValue value; CTxMemPool& mempool = EnsureAnyMemPool(request.context); - if (!GetSpentIndex(mempool, key, value)) { + if (LOCK(::cs_main); !GetSpentIndex(*pblocktree, mempool, key, value)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info"); } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index e28aeaf4db..da0010acc6 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -59,6 +59,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempool, CChainState& active_chainstate, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, UniValue& entry) { + LOCK(::cs_main); + // Call into TxToUniv() in bitcoin-common to decode the transaction hex. // // Blockchain contextual information (confirmations and blocktime) is not @@ -73,7 +75,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo if (!tx.IsCoinBase()) { CSpentIndexValue spentInfo; CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); - if (GetSpentIndex(mempool, spentKey, spentInfo)) { + if (GetSpentIndex(*pblocktree, mempool, spentKey, spentInfo)) { txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo); } } @@ -81,7 +83,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo for (unsigned int i = 0; i < tx.vout.size(); i++) { CSpentIndexValue spentInfo; CSpentIndexKey spentKey(txid, i); - if (GetSpentIndex(mempool, spentKey, spentInfo)) { + if (GetSpentIndex(*pblocktree, mempool, spentKey, spentInfo)) { txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo); } } @@ -90,8 +92,6 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo bool chainLock = false; if (!hashBlock.IsNull()) { - LOCK(cs_main); - entry.pushKV("blockhash", hashBlock.GetHex()); CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(hashBlock); if (pindex) {