refactor: move accessing CBlockTreeDB global out of Get*Index

This commit is contained in:
Kittywhiskers Van Gogh 2024-06-28 08:17:05 +00:00
parent ee9d11214e
commit 3e0fcf471f
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
5 changed files with 79 additions and 44 deletions

View File

@ -835,7 +835,7 @@ static RPCHelpMan getblockhashes()
unsigned int low = request.params[1].get_int(); unsigned int low = request.params[1].get_int();
std::vector<uint256> blockHashes; std::vector<uint256> 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"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for block hashes");
} }

View File

@ -9,26 +9,30 @@
#include <uint256.h> #include <uint256.h>
#include <validation.h> #include <validation.h>
bool GetAddressIndex(const uint160& addressHash, const AddressType type, bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type,
std::vector<CAddressIndexEntry>& addressIndex, std::vector<CAddressIndexEntry>& addressIndex,
const int32_t start, const int32_t end) const int32_t start, const int32_t end)
{ {
AssertLockHeld(::cs_main);
if (!fAddressIndex) if (!fAddressIndex)
return error("Address index not enabled"); 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 error("Unable to get txids for address");
return true; return true;
} }
bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type,
std::vector<CAddressUnspentIndexEntry>& unspentOutputs) std::vector<CAddressUnspentIndexEntry>& unspentOutputs)
{ {
AssertLockHeld(::cs_main);
if (!fAddressIndex) if (!fAddressIndex)
return error("Address index not enabled"); 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 error("Unable to get txids for address");
return true; return true;
@ -47,26 +51,32 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool,
return true; 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) if (!fSpentIndex)
return error("Spent index not enabled"); return error("Spent index not enabled");
if (mempool.getSpentIndex(key, value)) if (mempool.getSpentIndex(key, value))
return true; return true;
if (!pblocktree->ReadSpentIndex(key, value)) if (!block_tree_db.ReadSpentIndex(key, value))
return error("Unable to get spend information"); return error("Unable to get spend information");
return true; return true;
} }
bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector<uint256>& hashes) bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low,
std::vector<uint256>& hashes)
{ {
AssertLockHeld(::cs_main);
if (!fTimestampIndex) if (!fTimestampIndex)
return error("Timestamp index not enabled"); 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 error("Unable to get hashes for timestamps");
return true; return true;

View File

@ -12,22 +12,33 @@
#include <amount.h> #include <amount.h>
#include <addressindex.h> #include <addressindex.h>
#include <spentindex.h> #include <spentindex.h>
#include <sync.h>
#include <threadsafety.h>
class CBlockTreeDB;
class CTxMemPool; class CTxMemPool;
class uint160; class uint160;
class uint256; class uint256;
enum class AddressType : uint8_t; 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<CAddressIndexEntry>& addressIndex, std::vector<CAddressIndexEntry>& addressIndex,
const int32_t start = 0, const int32_t end = 0); const int32_t start = 0, const int32_t end = 0)
bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
std::vector<CAddressUnspentIndexEntry>& unspentOutputs); bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type,
std::vector<CAddressUnspentIndexEntry>& unspentOutputs)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool,
const std::vector<CMempoolAddressDeltaKey>& addressDeltaIndex, const std::vector<CMempoolAddressDeltaKey>& addressDeltaIndex,
std::vector<CMempoolAddressDeltaEntry>& addressDeltaEntries); std::vector<CMempoolAddressDeltaEntry>& addressDeltaEntries);
bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value); bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key,
bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector<uint256>& hashes); CSpentIndexValue& value)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low,
std::vector<uint256>& hashes)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
#endif // BITCOIN_RPC_CLIENT_H #endif // BITCOIN_RPC_CLIENT_H

View File

@ -822,9 +822,12 @@ static RPCHelpMan getaddressutxos()
std::vector<CAddressUnspentIndexEntry> unspentOutputs; std::vector<CAddressUnspentIndexEntry> unspentOutputs;
for (const auto& address : addresses) { {
if (!GetAddressUnspentIndex(address.first, address.second, unspentOutputs)) { LOCK(::cs_main);
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); 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<CAddressIndexEntry> addressIndex; std::vector<CAddressIndexEntry> addressIndex;
for (const auto& address : addresses) { {
if (start > 0 && end > 0) { LOCK(::cs_main);
if (!GetAddressIndex(address.first, address.second, addressIndex, start, end)) { for (const auto& address : addresses) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); if (start > 0 && end > 0) {
} if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex, start, end)) {
} else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
if (!GetAddressIndex(address.first, address.second, addressIndex)) { }
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<CAddressIndexEntry> addressIndex; std::vector<CAddressIndexEntry> addressIndex;
for (const auto& address : addresses) { ChainstateManager& chainman = EnsureAnyChainman(request.context);
if (!GetAddressIndex(address.first, address.second, addressIndex)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); 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 = 0;
CAmount balance_spendable = 0; CAmount balance_spendable = 0;
@ -1055,14 +1066,17 @@ static RPCHelpMan getaddresstxids()
std::vector<CAddressIndexEntry> addressIndex; std::vector<CAddressIndexEntry> addressIndex;
for (const auto& address : addresses) { {
if (start > 0 && end > 0) { LOCK(::cs_main);
if (!GetAddressIndex(address.first, address.second, addressIndex, start, end)) { for (const auto& address : addresses) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); if (start > 0 && end > 0) {
} if (!GetAddressIndex(*pblocktree, address.first, address.second, addressIndex, start, end)) {
} else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
if (!GetAddressIndex(address.first, address.second, addressIndex)) { }
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; CSpentIndexValue value;
CTxMemPool& mempool = EnsureAnyMemPool(request.context); 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"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info");
} }

View File

@ -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) 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. // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
// //
// Blockchain contextual information (confirmations and blocktime) is not // 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()) { if (!tx.IsCoinBase()) {
CSpentIndexValue spentInfo; CSpentIndexValue spentInfo;
CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n);
if (GetSpentIndex(mempool, spentKey, spentInfo)) { if (GetSpentIndex(*pblocktree, mempool, spentKey, spentInfo)) {
txSpentInfo.mSpentInfo.emplace(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++) { for (unsigned int i = 0; i < tx.vout.size(); i++) {
CSpentIndexValue spentInfo; CSpentIndexValue spentInfo;
CSpentIndexKey spentKey(txid, i); CSpentIndexKey spentKey(txid, i);
if (GetSpentIndex(mempool, spentKey, spentInfo)) { if (GetSpentIndex(*pblocktree, mempool, spentKey, spentInfo)) {
txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo); txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo);
} }
} }
@ -90,8 +92,6 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo
bool chainLock = false; bool chainLock = false;
if (!hashBlock.IsNull()) { if (!hashBlock.IsNull()) {
LOCK(cs_main);
entry.pushKV("blockhash", hashBlock.GetHex()); entry.pushKV("blockhash", hashBlock.GetHex());
CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(hashBlock); CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
if (pindex) { if (pindex) {