From 5ad49ad66890665bddce2eaa8a8b671693e445fe Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:19:26 +0000 Subject: [PATCH 1/8] refactor: move Get{Address*, Timestamp, Spent}Index out of validation With bonus const'ing of CTxMemPool::get*Index --- src/Makefile.am | 2 ++ src/rpc/blockchain.cpp | 1 + src/rpc/index_util.cpp | 59 ++++++++++++++++++++++++++++++++++++++ src/rpc/index_util.h | 33 +++++++++++++++++++++ src/rpc/misc.cpp | 3 +- src/rpc/rawtransaction.cpp | 1 + src/validation.cpp | 50 -------------------------------- src/validation.h | 8 ------ 8 files changed, 98 insertions(+), 59 deletions(-) create mode 100644 src/rpc/index_util.cpp create mode 100644 src/rpc/index_util.h diff --git a/src/Makefile.am b/src/Makefile.am index c5d69a6c0a..f1a3cda67d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -286,6 +286,7 @@ BITCOIN_CORE_H = \ reverse_iterator.h \ rpc/blockchain.h \ rpc/client.h \ + rpc/index_util.h \ rpc/mining.h \ rpc/protocol.h \ rpc/rawtransaction_util.h \ @@ -502,6 +503,7 @@ libbitcoin_server_a_SOURCES = \ rpc/blockchain.cpp \ rpc/coinjoin.cpp \ rpc/evo.cpp \ + rpc/index_util.cpp \ rpc/masternode.cpp \ rpc/governance.cpp \ rpc/mining.cpp \ diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 3b2874b910..bef4af863d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp new file mode 100644 index 0000000000..65ddf3e49b --- /dev/null +++ b/src/rpc/index_util.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2016 BitPay, Inc. +// Copyright (c) 2024 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include + +bool GetAddressIndex(uint160 addressHash, AddressType type, + std::vector>& addressIndex, int32_t start, int32_t end) +{ + if (!fAddressIndex) + return error("address index not enabled"); + + if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) + return error("unable to get txids for address"); + + return true; +} + +bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, + std::vector>& unspentOutputs) +{ + if (!fAddressIndex) + return error("address index not enabled"); + + if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) + return error("unable to get txids for address"); + + return true; +} + +bool GetSpentIndex(CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value) +{ + if (!fSpentIndex) + return false; + + if (mempool.getSpentIndex(key, value)) + return true; + + if (!pblocktree->ReadSpentIndex(key, value)) + return false; + + return true; +} + +bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes) +{ + if (!fTimestampIndex) + return error("Timestamp index not enabled"); + + if (!pblocktree->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 new file mode 100644 index 0000000000..af01cadf9c --- /dev/null +++ b/src/rpc/index_util.h @@ -0,0 +1,33 @@ +// Copyright (c) 2016 BitPay, Inc. +// Copyright (c) 2024 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPC_INDEX_UTIL_H +#define BITCOIN_RPC_INDEX_UTIL_H + +#include +#include + +#include + +class CTxMemPool; +class uint160; +class uint256; +struct CAddressIndexKey; +struct CAddressUnspentKey; +struct CAddressUnspentValue; +struct CSpentIndexKey; +struct CSpentIndexValue; + +enum class AddressType : uint8_t; + +bool GetAddressIndex(uint160 addressHash, AddressType type, + std::vector>& addressIndex, + int32_t start = 0, int32_t end = 0); +bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, + std::vector>& unspentOutputs); +bool GetSpentIndex(CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value); +bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes); + +#endif // BITCOIN_RPC_CLIENT_H diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 44a18f6341..9a4a078a32 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -823,7 +824,7 @@ static RPCHelpMan getaddressutxos() std::vector > unspentOutputs; for (const auto& address : addresses) { - if (!GetAddressUnspent(address.first, address.second, unspentOutputs)) { + if (!GetAddressUnspentIndex(address.first, address.second, unspentOutputs)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); } } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 02c5814538..e28aeaf4db 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/src/validation.cpp b/src/validation.cpp index 21b0e63c55..7152919049 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1055,56 +1055,6 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx return result; } -bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector &hashes) -{ - if (!fTimestampIndex) - return error("Timestamp index not enabled"); - - if (!pblocktree->ReadTimestampIndex(high, low, hashes)) - return error("Unable to get hashes for timestamps"); - - return true; -} - -bool GetSpentIndex(CTxMemPool& mempool, CSpentIndexKey &key, CSpentIndexValue &value) -{ - if (!fSpentIndex) - return false; - - if (mempool.getSpentIndex(key, value)) - return true; - - if (!pblocktree->ReadSpentIndex(key, value)) - return false; - - return true; -} - -bool GetAddressIndex(uint160 addressHash, AddressType type, - std::vector > &addressIndex, int start, int end) -{ - if (!fAddressIndex) - return error("address index not enabled"); - - if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) - return error("unable to get txids for address"); - - return true; -} - -bool GetAddressUnspent(uint160 addressHash, AddressType type, - std::vector > &unspentOutputs) -{ - if (!fAddressIndex) - return error("address index not enabled"); - - if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) - return error("unable to get txids for address"); - - return true; -} - - double ConvertBitsToDouble(unsigned int nBits) { int nShift = (nBits >> 24) & 0xff; diff --git a/src/validation.h b/src/validation.h index 7306edd7f5..9b2541fd93 100644 --- a/src/validation.h +++ b/src/validation.h @@ -22,7 +22,6 @@ #include #include // For CTxMemPool::cs #include -#include #include #include @@ -379,13 +378,6 @@ public: ScriptError GetScriptError() const { return error; } }; -bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector &hashes); -bool GetSpentIndex(CTxMemPool& mempool, CSpentIndexKey &key, CSpentIndexValue &value); -bool GetAddressIndex(uint160 addressHash, AddressType type, - std::vector > &addressIndex, - int start = 0, int end = 0); -bool GetAddressUnspent(uint160 addressHash, AddressType type, - std::vector > &unspentOutputs); /** Initializes the script-execution cache */ void InitScriptExecutionCache(); From 625982e8d2ed04327c3bfcb0e725ca466cbf4332 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:51:48 +0000 Subject: [PATCH 2/8] refactor: make CTxMemPool::get*Index functions and arguments const --- src/rpc/index_util.cpp | 2 +- src/rpc/index_util.h | 2 +- src/txmempool.cpp | 15 +++++++-------- src/txmempool.h | 10 +++++----- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index 65ddf3e49b..4b8bf64a61 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -33,7 +33,7 @@ bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, return true; } -bool GetSpentIndex(CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value) +bool GetSpentIndex(const CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value) { if (!fSpentIndex) return false; diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index af01cadf9c..15b82eb2a5 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -27,7 +27,7 @@ bool GetAddressIndex(uint160 addressHash, AddressType type, int32_t start = 0, int32_t end = 0); bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, std::vector>& unspentOutputs); -bool GetSpentIndex(CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value); +bool GetSpentIndex(const CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value); bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes); #endif // BITCOIN_RPC_CLIENT_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a9b9a09360..a2eaf621ff 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -427,7 +427,7 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces } } -void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) +void CTxMemPool::addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view) { LOCK(cs); const CTransaction& tx = entry.GetTx(); @@ -470,12 +470,12 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC mapAddressInserted.insert(std::make_pair(txhash, inserted)); } -bool CTxMemPool::getAddressIndex(std::vector > &addresses, - std::vector > &results) +bool CTxMemPool::getAddressIndex(const std::vector>& addresses, + std::vector>& results) const { LOCK(cs); for (const auto& address : addresses) { - addressDeltaMap::iterator ait = mapAddress.lower_bound(CMempoolAddressDeltaKey(address.second, address.first)); + addressDeltaMap::const_iterator ait = mapAddress.lower_bound(CMempoolAddressDeltaKey(address.second, address.first)); while (ait != mapAddress.end() && (*ait).first.m_address_bytes == address.first && (*ait).first.m_address_type == address.second) { results.push_back(*ait); ait++; @@ -500,7 +500,7 @@ bool CTxMemPool::removeAddressIndex(const uint256 txhash) return true; } -void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) +void CTxMemPool::addSpentIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view) { LOCK(cs); @@ -530,12 +530,11 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac mapSpentInserted.insert(make_pair(txhash, inserted)); } -bool CTxMemPool::getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) +bool CTxMemPool::getSpentIndex(const CSpentIndexKey& key, CSpentIndexValue& value) const { LOCK(cs); - mapSpentIndex::iterator it; + mapSpentIndex::const_iterator it = mapSpent.find(key); - it = mapSpent.find(key); if (it != mapSpent.end()) { value = it->second; return true; diff --git a/src/txmempool.h b/src/txmempool.h index a4717b7e88..823b45e892 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -635,13 +635,13 @@ public: void addUnchecked(const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); - void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); - bool getAddressIndex(std::vector > &addresses, - std::vector > &results); + void addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view); + bool getAddressIndex(const std::vector>& addresses, + std::vector>& results) const; bool removeAddressIndex(const uint256 txhash); - void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); - bool getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); + void addSpentIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view); + bool getSpentIndex(const CSpentIndexKey& key, CSpentIndexValue& value) const; bool removeSpentIndex(const uint256 txhash); void removeRecursive(const CTransaction& tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs); From 9a6503d9e8d582b0b552be4937748ba6c2bdfd68 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:57:01 +0000 Subject: [PATCH 3/8] refactor: make CBlockTreeDB::Read*Index arguments const With bonus code formatting. We cannot make the functions themselves const as the iterators are non-const. --- src/rpc/index_util.cpp | 9 +++++---- src/rpc/index_util.h | 8 ++++---- src/txdb.cpp | 37 ++++++++++++++++++------------------- src/txdb.h | 29 +++++++++++++++++------------ 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index 4b8bf64a61..fd04ef0231 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -9,8 +9,9 @@ #include #include -bool GetAddressIndex(uint160 addressHash, AddressType type, - std::vector>& addressIndex, int32_t start, int32_t end) +bool GetAddressIndex(const uint160& addressHash, const AddressType type, + std::vector>& addressIndex, + const int32_t start, const int32_t end) { if (!fAddressIndex) return error("address index not enabled"); @@ -21,7 +22,7 @@ bool GetAddressIndex(uint160 addressHash, AddressType type, return true; } -bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, +bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, std::vector>& unspentOutputs) { if (!fAddressIndex) @@ -33,7 +34,7 @@ bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, return true; } -bool GetSpentIndex(const CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value) +bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) { if (!fSpentIndex) return false; diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index 15b82eb2a5..adf260b05c 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -22,12 +22,12 @@ struct CSpentIndexValue; enum class AddressType : uint8_t; -bool GetAddressIndex(uint160 addressHash, AddressType type, +bool GetAddressIndex(const uint160& addressHash, const AddressType type, std::vector>& addressIndex, - int32_t start = 0, int32_t end = 0); -bool GetAddressUnspentIndex(uint160 addressHash, AddressType type, + const int32_t start = 0, const int32_t end = 0); +bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, std::vector>& unspentOutputs); -bool GetSpentIndex(const CTxMemPool& mempool, CSpentIndexKey& key, CSpentIndexValue& value); +bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value); bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes); #endif // BITCOIN_RPC_CLIENT_H diff --git a/src/txdb.cpp b/src/txdb.cpp index 9018be6849..f464ca300e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -263,13 +263,13 @@ bool CBlockTreeDB::WriteBatchSync(const std::vector >&vect) { +bool CBlockTreeDB::UpdateSpentIndex(const std::vector>& vect) { CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) { + for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) { if (it->second.IsNull()) { batch.Erase(std::make_pair(DB_SPENTINDEX, it->first)); } else { @@ -279,9 +279,9 @@ bool CBlockTreeDB::UpdateSpentIndex(const std::vector >&vect) { +bool CBlockTreeDB::UpdateAddressUnspentIndex(const std::vector>& vect) { CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) { + for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) { if (it->second.IsNull()) { batch.Erase(std::make_pair(DB_ADDRESSUNSPENTINDEX, it->first)); } else { @@ -291,9 +291,9 @@ bool CBlockTreeDB::UpdateAddressUnspentIndex(const std::vector > &unspentOutputs) { - +bool CBlockTreeDB::ReadAddressUnspentIndex(const uint160& addressHash, const AddressType type, + std::vector>& unspentOutputs) +{ std::unique_ptr pcursor(NewIterator()); pcursor->Seek(std::make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash))); @@ -316,24 +316,24 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, AddressType type return true; } -bool CBlockTreeDB::WriteAddressIndex(const std::vector >&vect) { +bool CBlockTreeDB::WriteAddressIndex(const std::vector>& vect) { CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) + for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) batch.Write(std::make_pair(DB_ADDRESSINDEX, it->first), it->second); return WriteBatch(batch); } -bool CBlockTreeDB::EraseAddressIndex(const std::vector >&vect) { +bool CBlockTreeDB::EraseAddressIndex(const std::vector>& vect) { CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) + for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) batch.Erase(std::make_pair(DB_ADDRESSINDEX, it->first)); return WriteBatch(batch); } -bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, AddressType type, - std::vector > &addressIndex, - int start, int end) { - +bool CBlockTreeDB::ReadAddressIndex(const uint160& addressHash, const AddressType type, + std::vector>& addressIndex, + const int32_t start, const int32_t end) +{ std::unique_ptr pcursor(NewIterator()); if (start > 0 && end > 0) { @@ -363,7 +363,7 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, AddressType type, return true; } -bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) { +bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey& timestampIndex) { CDBBatch batch(*this); batch.Write(std::make_pair(DB_TIMESTAMPINDEX, timestampIndex), 0); return WriteBatch(batch); @@ -376,8 +376,7 @@ bool CBlockTreeDB::EraseTimestampIndex(const CTimestampIndexKey& timestampIndex) return WriteBatch(batch); } -bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector &hashes) { - +bool CBlockTreeDB::ReadTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes) { std::unique_ptr pcursor(NewIterator()); pcursor->Seek(std::make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low))); diff --git a/src/txdb.h b/src/txdb.h index c2627aa079..b267617400 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -84,19 +84,24 @@ public: bool ReadLastBlockFile(int &nFile); bool WriteReindexing(bool fReindexing); void ReadReindexing(bool &fReindexing); - bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); - bool UpdateSpentIndex(const std::vector >&vect); - bool UpdateAddressUnspentIndex(const std::vector >&vect); - bool ReadAddressUnspentIndex(uint160 addressHash, AddressType type, - std::vector > &vect); - bool WriteAddressIndex(const std::vector > &vect); - bool EraseAddressIndex(const std::vector > &vect); - bool ReadAddressIndex(uint160 addressHash, AddressType type, - std::vector > &addressIndex, - int start = 0, int end = 0); - bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex); + + bool ReadSpentIndex(const CSpentIndexKey key, CSpentIndexValue& value); + bool UpdateSpentIndex(const std::vector>& vect); + + bool ReadAddressUnspentIndex(const uint160& addressHash, const AddressType type, + std::vector>& vect); + bool UpdateAddressUnspentIndex(const std::vector>& vect); + + bool WriteAddressIndex(const std::vector>& vect); + bool EraseAddressIndex(const std::vector>& vect); + bool ReadAddressIndex(const uint160& addressHash, const AddressType type, + std::vector>& addressIndex, + const int32_t start = 0, const int32_t end = 0); + + bool WriteTimestampIndex(const CTimestampIndexKey& timestampIndex); bool EraseTimestampIndex(const CTimestampIndexKey& timestampIndex); - bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector &vect); + bool ReadTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes); + bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function insertBlockIndex); From 488f0474a89f4dd509883a97622cb1d857823dcb Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:25:19 +0000 Subject: [PATCH 4/8] rpc: extend error-on-failure to GetSpentIndex --- src/rpc/index_util.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index fd04ef0231..d4693cfe3a 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -14,10 +14,10 @@ bool GetAddressIndex(const uint160& addressHash, const AddressType type, const int32_t start, const int32_t end) { if (!fAddressIndex) - return error("address index not enabled"); + return error("Address index not enabled"); if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) - return error("unable to get txids for address"); + return error("Unable to get txids for address"); return true; } @@ -26,10 +26,10 @@ bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, std::vector>& unspentOutputs) { if (!fAddressIndex) - return error("address index not enabled"); + return error("Address index not enabled"); if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) - return error("unable to get txids for address"); + return error("Unable to get txids for address"); return true; } @@ -37,13 +37,13 @@ bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) { if (!fSpentIndex) - return false; + return error("Spent index not enabled"); if (mempool.getSpentIndex(key, value)) return true; if (!pblocktree->ReadSpentIndex(key, value)) - return false; + return error("Unable to get spend information"); return true; } From 808842b1a364a8d259dc26c3aa3c79dd56a4a1a5 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 26 Jun 2024 19:09:14 +0000 Subject: [PATCH 5/8] refactor: define all key/value pairings as *Entry and use them instead --- src/addressindex.h | 6 ++++++ src/rpc/index_util.cpp | 4 ++-- src/rpc/index_util.h | 11 ++++------- src/rpc/misc.cpp | 16 +++++++--------- src/spentindex.h | 8 ++++++++ src/txdb.cpp | 18 +++++++++--------- src/txdb.h | 12 ++++++------ src/txmempool.cpp | 2 +- src/txmempool.h | 2 +- src/validation.cpp | 18 +++++++++--------- 10 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/addressindex.h b/src/addressindex.h index 42f8227237..e2dc67a7d8 100644 --- a/src/addressindex.h +++ b/src/addressindex.h @@ -17,6 +17,9 @@ #include class CScript; +struct CAddressIndexKey; +struct CMempoolAddressDelta; +struct CMempoolAddressDeltaKey; enum class AddressType : uint8_t { P2PK_OR_P2PKH = 1, @@ -26,6 +29,9 @@ enum class AddressType : uint8_t { }; template<> struct is_serializable_enum : std::true_type {}; +using CAddressIndexEntry = std::pair; +using CMempoolAddressDeltaEntry = std::pair; + struct CMempoolAddressDelta { public: diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index d4693cfe3a..804e956d86 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -10,7 +10,7 @@ #include bool GetAddressIndex(const uint160& addressHash, const AddressType type, - std::vector>& addressIndex, + std::vector& addressIndex, const int32_t start, const int32_t end) { if (!fAddressIndex) @@ -23,7 +23,7 @@ bool GetAddressIndex(const uint160& addressHash, const AddressType type, } bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, - std::vector>& unspentOutputs) + std::vector& unspentOutputs) { if (!fAddressIndex) return error("Address index not enabled"); diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index adf260b05c..fa0cd4f212 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -10,23 +10,20 @@ #include #include +#include +#include class CTxMemPool; class uint160; class uint256; -struct CAddressIndexKey; -struct CAddressUnspentKey; -struct CAddressUnspentValue; -struct CSpentIndexKey; -struct CSpentIndexValue; enum class AddressType : uint8_t; bool GetAddressIndex(const uint160& addressHash, const AddressType type, - std::vector>& addressIndex, + std::vector& addressIndex, const int32_t start = 0, const int32_t end = 0); bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, - std::vector>& unspentOutputs); + std::vector& unspentOutputs); bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value); bool GetTimestampIndex(const uint32_t high, const uint32_t low, std::vector& hashes); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 9a4a078a32..0ec2ddad8b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -701,13 +701,11 @@ static bool getAddressesFromParams(const UniValue& params, std::vector a, - std::pair b) { +static bool heightSort(CAddressUnspentIndexEntry a, CAddressUnspentIndexEntry b) { return a.second.m_block_height < b.second.m_block_height; } -static bool timestampSort(std::pair a, - std::pair b) { +static bool timestampSort(CMempoolAddressDeltaEntry a, CMempoolAddressDeltaEntry b) { return a.second.m_time < b.second.m_time; } @@ -749,7 +747,7 @@ static RPCHelpMan getaddressmempool() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } - std::vector > indexes; + std::vector indexes; CTxMemPool& mempool = EnsureAnyMemPool(request.context); if (!mempool.getAddressIndex(addresses, indexes)) { @@ -821,7 +819,7 @@ static RPCHelpMan getaddressutxos() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } - std::vector > unspentOutputs; + std::vector unspentOutputs; for (const auto& address : addresses) { if (!GetAddressUnspentIndex(address.first, address.second, unspentOutputs)) { @@ -906,7 +904,7 @@ static RPCHelpMan getaddressdeltas() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } - std::vector > addressIndex; + std::vector addressIndex; for (const auto& address : addresses) { if (start > 0 && end > 0) { @@ -975,7 +973,7 @@ static RPCHelpMan getaddressbalance() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } - std::vector > addressIndex; + std::vector addressIndex; for (const auto& address : addresses) { if (!GetAddressIndex(address.first, address.second, addressIndex)) { @@ -1054,7 +1052,7 @@ static RPCHelpMan getaddresstxids() } } - std::vector > addressIndex; + std::vector addressIndex; for (const auto& address : addresses) { if (start > 0 && end > 0) { diff --git a/src/spentindex.h b/src/spentindex.h index 944ba638ca..626762fc5f 100644 --- a/src/spentindex.h +++ b/src/spentindex.h @@ -16,6 +16,14 @@ #include +struct CAddressUnspentKey; +struct CAddressUnspentValue; +struct CSpentIndexKey; +struct CSpentIndexValue; + +using CAddressUnspentIndexEntry = std::pair; +using CSpentIndexEntry = std::pair; + struct CSpentIndexKey { public: uint256 m_tx_hash; diff --git a/src/txdb.cpp b/src/txdb.cpp index f464ca300e..038432c8fa 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -267,7 +267,7 @@ bool CBlockTreeDB::ReadSpentIndex(const CSpentIndexKey key, CSpentIndexValue& va return Read(std::make_pair(DB_SPENTINDEX, key), value); } -bool CBlockTreeDB::UpdateSpentIndex(const std::vector>& vect) { +bool CBlockTreeDB::UpdateSpentIndex(const std::vector& vect) { CDBBatch batch(*this); for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) { if (it->second.IsNull()) { @@ -279,9 +279,9 @@ bool CBlockTreeDB::UpdateSpentIndex(const std::vector>& vect) { +bool CBlockTreeDB::UpdateAddressUnspentIndex(const std::vector& vect) { CDBBatch batch(*this); - for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) { + for (std::vector::const_iterator it=vect.begin(); it!=vect.end(); it++) { if (it->second.IsNull()) { batch.Erase(std::make_pair(DB_ADDRESSUNSPENTINDEX, it->first)); } else { @@ -292,7 +292,7 @@ bool CBlockTreeDB::UpdateAddressUnspentIndex(const std::vector>& unspentOutputs) + std::vector& unspentOutputs) { std::unique_ptr pcursor(NewIterator()); @@ -316,22 +316,22 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(const uint160& addressHash, const Add return true; } -bool CBlockTreeDB::WriteAddressIndex(const std::vector>& vect) { +bool CBlockTreeDB::WriteAddressIndex(const std::vector& vect) { CDBBatch batch(*this); - for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) + for (std::vector::const_iterator it=vect.begin(); it!=vect.end(); it++) batch.Write(std::make_pair(DB_ADDRESSINDEX, it->first), it->second); return WriteBatch(batch); } -bool CBlockTreeDB::EraseAddressIndex(const std::vector>& vect) { +bool CBlockTreeDB::EraseAddressIndex(const std::vector& vect) { CDBBatch batch(*this); - for (std::vector>::const_iterator it=vect.begin(); it!=vect.end(); it++) + for (std::vector::const_iterator it=vect.begin(); it!=vect.end(); it++) batch.Erase(std::make_pair(DB_ADDRESSINDEX, it->first)); return WriteBatch(batch); } bool CBlockTreeDB::ReadAddressIndex(const uint160& addressHash, const AddressType type, - std::vector>& addressIndex, + std::vector& addressIndex, const int32_t start, const int32_t end) { std::unique_ptr pcursor(NewIterator()); diff --git a/src/txdb.h b/src/txdb.h index b267617400..54c79ade14 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -86,16 +86,16 @@ public: void ReadReindexing(bool &fReindexing); bool ReadSpentIndex(const CSpentIndexKey key, CSpentIndexValue& value); - bool UpdateSpentIndex(const std::vector>& vect); + bool UpdateSpentIndex(const std::vector& vect); bool ReadAddressUnspentIndex(const uint160& addressHash, const AddressType type, - std::vector>& vect); - bool UpdateAddressUnspentIndex(const std::vector>& vect); + std::vector& vect); + bool UpdateAddressUnspentIndex(const std::vector& vect); - bool WriteAddressIndex(const std::vector>& vect); - bool EraseAddressIndex(const std::vector>& vect); + bool WriteAddressIndex(const std::vector& vect); + bool EraseAddressIndex(const std::vector& vect); bool ReadAddressIndex(const uint160& addressHash, const AddressType type, - std::vector>& addressIndex, + std::vector& addressIndex, const int32_t start = 0, const int32_t end = 0); bool WriteTimestampIndex(const CTimestampIndexKey& timestampIndex); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a2eaf621ff..a6f0d84579 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -471,7 +471,7 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewC } bool CTxMemPool::getAddressIndex(const std::vector>& addresses, - std::vector>& results) const + std::vector& results) const { LOCK(cs); for (const auto& address : addresses) { diff --git a/src/txmempool.h b/src/txmempool.h index 823b45e892..739f139597 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -637,7 +637,7 @@ public: void addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view); bool getAddressIndex(const std::vector>& addresses, - std::vector>& results) const; + std::vector& results) const; bool removeAddressIndex(const uint256 txhash); void addSpentIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view); diff --git a/src/validation.cpp b/src/validation.cpp index 7152919049..15be0df400 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1685,9 +1685,9 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI return DISCONNECT_FAILED; } - std::vector > addressIndex; - std::vector > addressUnspentIndex; - std::vector > spentIndex; + std::vector addressIndex; + std::vector addressUnspentIndex; + std::vector spentIndex; std::optional mnlist_updates_opt{std::nullopt}; if (!m_chain_helper->special_tx->UndoSpecialTxsInBlock(block, pindex, mnlist_updates_opt)) { @@ -2152,9 +2152,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, int nInputs = 0; unsigned int nSigOps = 0; blockundo.vtxundo.reserve(block.vtx.size() - 1); - std::vector > addressIndex; - std::vector > addressUnspentIndex; - std::vector > spentIndex; + std::vector addressIndex; + std::vector addressUnspentIndex; + std::vector spentIndex; bool fDIP0001Active_context = pindex->nHeight >= Params().GetConsensus().DIP0001Height; @@ -4782,9 +4782,9 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i pindex->GetBlockHash().ToString(), state.ToString()); } - std::vector > addressIndex; - std::vector > addressUnspentIndex; - std::vector > spentIndex; + std::vector addressIndex; + std::vector addressUnspentIndex; + std::vector spentIndex; for (size_t i = 0; i < block.vtx.size(); i++) { const CTransactionRef& tx = block.vtx[i]; From ee9d11214e6aa3d90adf6b1d3ec8892ac8c6ca3b Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 26 Jun 2024 19:24:21 +0000 Subject: [PATCH 6/8] refactor: move pair value swapping out of CTxMemPool::getAddressIndex() --- src/rpc/index_util.cpp | 13 +++++++++++++ src/rpc/index_util.h | 3 +++ src/rpc/misc.cpp | 13 +++++++------ src/txmempool.cpp | 7 ++++--- src/txmempool.h | 2 +- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index 804e956d86..0680012e56 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -34,6 +34,19 @@ bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, return true; } +bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, + const std::vector& addressDeltaIndex, + std::vector& addressDeltaEntries) +{ + if (!fAddressIndex) + return error("Address index not enabled"); + + if (!mempool.getAddressIndex(addressDeltaIndex, addressDeltaEntries)) + return error("Unable to get address delta information"); + + return true; +} + bool GetSpentIndex(const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) { if (!fSpentIndex) diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index fa0cd4f212..889a544786 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -24,6 +24,9 @@ bool GetAddressIndex(const uint160& addressHash, const AddressType type, const int32_t start = 0, const int32_t end = 0); bool GetAddressUnspentIndex(const uint160& addressHash, const AddressType type, std::vector& unspentOutputs); +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); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0ec2ddad8b..6c2f8bd664 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -740,20 +740,21 @@ static RPCHelpMan getaddressmempool() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + CTxMemPool& mempool = EnsureAnyMemPool(request.context); - std::vector > addresses; - + std::vector> addresses; if (!getAddressesFromParams(request.params, addresses)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } + std::vector input_addresses; std::vector indexes; - - CTxMemPool& mempool = EnsureAnyMemPool(request.context); - if (!mempool.getAddressIndex(addresses, indexes)) { + for (const auto& [hash, type] : addresses) { + input_addresses.push_back({type, hash}); + } + if (!GetMempoolAddressDeltaIndex(mempool, input_addresses, indexes)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); } - std::sort(indexes.begin(), indexes.end(), timestampSort); UniValue result(UniValue::VARR); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a6f0d84579..b62c9f9fd5 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -470,13 +470,14 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewC mapAddressInserted.insert(std::make_pair(txhash, inserted)); } -bool CTxMemPool::getAddressIndex(const std::vector>& addresses, +bool CTxMemPool::getAddressIndex(const std::vector& addresses, std::vector& results) const { LOCK(cs); for (const auto& address : addresses) { - addressDeltaMap::const_iterator ait = mapAddress.lower_bound(CMempoolAddressDeltaKey(address.second, address.first)); - while (ait != mapAddress.end() && (*ait).first.m_address_bytes == address.first && (*ait).first.m_address_type == address.second) { + addressDeltaMap::const_iterator ait = mapAddress.lower_bound(address); + while (ait != mapAddress.end() && (*ait).first.m_address_bytes == address.m_address_bytes + && (*ait).first.m_address_type == address.m_address_type) { results.push_back(*ait); ait++; } diff --git a/src/txmempool.h b/src/txmempool.h index 739f139597..12efa08b51 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -636,7 +636,7 @@ public: void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); void addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view); - bool getAddressIndex(const std::vector>& addresses, + bool getAddressIndex(const std::vector& addresses, std::vector& results) const; bool removeAddressIndex(const uint256 txhash); 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 7/8] 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) { From 8fb863008e26256000e3c6f846274e01b62bb664 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 28 Jun 2024 08:17:42 +0000 Subject: [PATCH 8/8] refactor: inline sorting and make available through argument --- src/rpc/index_util.cpp | 19 +++++++++++++++++-- src/rpc/index_util.h | 5 +++-- src/rpc/misc.cpp | 16 +++------------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index d5ba2b1669..4e362af88c 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -25,7 +25,7 @@ bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, co } bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, - std::vector& unspentOutputs) + std::vector& unspentOutputs, const bool height_sort) { AssertLockHeld(::cs_main); @@ -35,12 +35,20 @@ bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressH if (!block_tree_db.ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) return error("Unable to get txids for address"); + if (height_sort) { + std::sort(unspentOutputs.begin(), unspentOutputs.end(), + [](const CAddressUnspentIndexEntry &a, const CAddressUnspentIndexEntry &b) { + return a.second.m_block_height < b.second.m_block_height; + }); + } + return true; } bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, const std::vector& addressDeltaIndex, - std::vector& addressDeltaEntries) + std::vector& addressDeltaEntries, + const bool timestamp_sort) { if (!fAddressIndex) return error("Address index not enabled"); @@ -48,6 +56,13 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, if (!mempool.getAddressIndex(addressDeltaIndex, addressDeltaEntries)) return error("Unable to get address delta information"); + if (timestamp_sort) { + std::sort(addressDeltaEntries.begin(), addressDeltaEntries.end(), + [](const CMempoolAddressDeltaEntry &a, const CMempoolAddressDeltaEntry &b) { + return a.second.m_time < b.second.m_time; + }); + } + return true; } diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index d296721be9..3155bf2263 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -29,11 +29,12 @@ bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, co 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) + std::vector& unspentOutputs, const bool height_sort = false) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, const std::vector& addressDeltaIndex, - std::vector& addressDeltaEntries); + std::vector& addressDeltaEntries, + const bool timestamp_sort = false); bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index eec4baec66..377acc2679 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -701,14 +701,6 @@ static bool getAddressesFromParams(const UniValue& params, std::vector