From dd1b36636c8c6f21df9448232a083bb7d66c7f7e Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 4 Dec 2024 01:25:26 +0700 Subject: [PATCH 1/2] feat: show human friendly error if missing spentindex, txindex or addressindex It also fixes spam messages about missing txindex for each RPC call getrawtransaction node0 2024-12-03T18:54:33.349605Z [ http] [httpserver.cpp:248] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:40052 node0 2024-12-03T18:54:33.349634Z [httpworker.3] [rpc/request.cpp:180] [parse] [rpc] ThreadRPCServer method=getrawtransaction user=__cookie__ node0 2024-12-03T18:54:33.349729Z [httpworker.3] [util/system.h:57] [error] ERROR: Spent index not enabled node0 2024-12-03T18:54:33.349735Z [httpworker.3] [util/system.h:57] [error] ERROR: Spent index not enabled node0 2024-12-03T18:54:33.349738Z [httpworker.3] [util/system.h:57] [error] ERROR: Spent index not enabled node0 2024-12-03T18:54:33.349808Z [httpworker.3] [httprpc.cpp:93] [~RpcHttpRequest] [bench] HTTP RPC request handled: user=__cookie__ command=getrawtransaction external=false status=200 elapsed_time_ms=0 node0 2024-12-03T18:54:33.349998Z [ http] [httpserver.cpp:248] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:40052 node0 2024-12-03T18:54:33.350027Z [httpworker.0] [rpc/request.cpp:180] [parse] [rpc] ThreadRPCServer method=getrawtransaction user=__cookie__ node0 2024-12-03T18:54:33.350128Z [httpworker.0] [util/system.h:57] [error] ERROR: Spent index not enabled node0 2024-12-03T18:54:33.350133Z [httpworker.0] [util/system.h:57] [error] ERROR: Spent index not enabled node0 2024-12-03T18:54:33.350137Z [httpworker.0] [util/system.h:57] [error] ERROR: Spent index not enabled --- src/rpc/blockchain.cpp | 4 ++++ src/rpc/index_util.cpp | 15 +++++++++++++++ src/rpc/index_util.h | 5 +++++ src/rpc/misc.cpp | 20 +++++++++++++++++++- src/rpc/rawtransaction.cpp | 27 ++++++++++++++++----------- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 5c3890a0c9..c52317a9fc 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -870,6 +870,10 @@ static RPCHelpMan getblockhashes() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (!IsTimestampIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Timestamp index is disabled. You should run Dash Core with -timestampindex (requires reindex)"); + } + unsigned int high = request.params[0].get_int(); unsigned int low = request.params[1].get_int(); std::vector blockHashes; diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index abe6912868..1557a71fa3 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -10,6 +10,11 @@ #include #include +bool IsAddressIndexAvailable() +{ + return fAddressIndex; +} + bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, std::vector& addressIndex, const int32_t start, const int32_t end) @@ -67,6 +72,11 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, return true; } +bool IsSpentIndexAvailable() +{ + return fSpentIndex; +} + bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) { @@ -84,6 +94,11 @@ bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const return true; } +bool IsTimestampIndexAvailable() +{ + return fTimestampIndex; +} + bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low, std::vector& hashes) { diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index 6bd3b73124..bc79e5a96c 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -24,6 +24,7 @@ enum class AddressType : uint8_t; extern RecursiveMutex cs_main; +bool IsAddressIndexAvailable(); 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) @@ -35,9 +36,13 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, const std::vector& addressDeltaIndex, std::vector& addressDeltaEntries, const bool timestamp_sort = false); + +bool IsSpentIndexAvailable(); bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + +bool IsTimestampIndexAvailable(); bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low, std::vector& hashes) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 40ed64f821..287d7d03ba 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -742,6 +742,10 @@ static RPCHelpMan getaddressmempool() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (!IsAddressIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); + } + CTxMemPool& mempool = EnsureAnyMemPool(request.context); std::vector> addresses; @@ -814,6 +818,9 @@ static RPCHelpMan getaddressutxos() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (!IsAddressIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); + } std::vector > addresses; @@ -887,7 +894,9 @@ static RPCHelpMan getaddressdeltas() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - + if (!IsAddressIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); + } UniValue startValue = find_value(request.params[0].get_obj(), "start"); UniValue endValue = find_value(request.params[0].get_obj(), "end"); @@ -979,6 +988,9 @@ static RPCHelpMan getaddressbalance() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (!IsAddressIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); + } std::vector > addresses; @@ -1052,6 +1064,9 @@ static RPCHelpMan getaddresstxids() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (!IsAddressIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); + } std::vector > addresses; @@ -1142,6 +1157,9 @@ static RPCHelpMan getspentinfo() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (!IsSpentIndexAvailable()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Spent index is disabled. You should run Dash Core with -spentindex (requires reindex)"); + } UniValue txidValue = find_value(request.params[0].get_obj(), "txid"); UniValue indexValue = find_value(request.params[0].get_obj(), "index"); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 09e7c7d862..375a7e46cf 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -71,27 +71,32 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo // data into the returned UniValue. uint256 txid = tx.GetHash(); + CSpentIndexTxInfo *txSpentInfoPtr{nullptr}; // Add spent information if spentindex is enabled CSpentIndexTxInfo txSpentInfo; - for (const auto& txin : tx.vin) { - if (!tx.IsCoinBase()) { + if (IsSpentIndexAvailable()) { + txSpentInfo = CSpentIndexTxInfo{}; + for (const auto& txin : tx.vin) { + if (!tx.IsCoinBase()) { + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); + if (GetSpentIndex(*active_chainstate.m_blockman.m_block_tree_db, mempool, spentKey, spentInfo)) { + txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo); + } + } + } + for (unsigned int i = 0; i < tx.vout.size(); i++) { CSpentIndexValue spentInfo; - CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); + CSpentIndexKey spentKey(txid, i); if (GetSpentIndex(*active_chainstate.m_blockman.m_block_tree_db, mempool, spentKey, spentInfo)) { txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo); } } - } - for (unsigned int i = 0; i < tx.vout.size(); i++) { - CSpentIndexValue spentInfo; - CSpentIndexKey spentKey(txid, i); - if (GetSpentIndex(*active_chainstate.m_blockman.m_block_tree_db, mempool, spentKey, spentInfo)) { - txSpentInfo.mSpentInfo.emplace(spentKey, spentInfo); - } + txSpentInfoPtr = &txSpentInfo; } - TxToUniv(tx, uint256(), entry, true, /* txundo = */ nullptr, &txSpentInfo); + TxToUniv(tx, uint256(), entry, true, /* txundo = */ nullptr, txSpentInfoPtr); bool chainLock = false; if (!hashBlock.IsNull()) { From a275bda266b9d4d485eb5bc3ce20e1a4c193e4e5 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 11 Dec 2024 01:26:07 +0700 Subject: [PATCH 2/2] refactor: removed duplicated code with errors messages for txindex, timestampindex, spentindex --- src/rpc/blockchain.cpp | 4 ---- src/rpc/index_util.cpp | 42 +++++++++++++++----------------------- src/rpc/index_util.h | 8 +++++--- src/rpc/misc.cpp | 25 ----------------------- src/rpc/rawtransaction.cpp | 2 +- 5 files changed, 23 insertions(+), 58 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index c52317a9fc..5c3890a0c9 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -870,10 +870,6 @@ static RPCHelpMan getblockhashes() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsTimestampIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Timestamp index is disabled. You should run Dash Core with -timestampindex (requires reindex)"); - } - unsigned int high = request.params[0].get_int(); unsigned int low = request.params[1].get_int(); std::vector blockHashes; diff --git a/src/rpc/index_util.cpp b/src/rpc/index_util.cpp index 1557a71fa3..30ca50caa1 100644 --- a/src/rpc/index_util.cpp +++ b/src/rpc/index_util.cpp @@ -6,13 +6,17 @@ #include #include +#include +#include #include #include #include -bool IsAddressIndexAvailable() +static void EnsureAddressIndexAvailable() { - return fAddressIndex; + if (!fAddressIndex) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); + } } bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, @@ -20,12 +24,11 @@ bool GetAddressIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, co const int32_t start, const int32_t end) { AssertLockHeld(::cs_main); + EnsureAddressIndexAvailable(); - if (!fAddressIndex) - return error("Address index not enabled"); - - if (!block_tree_db.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; } @@ -34,9 +37,7 @@ bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressH std::vector& unspentOutputs, const bool height_sort) { AssertLockHeld(::cs_main); - - if (!fAddressIndex) - return error("Address index not enabled"); + EnsureAddressIndexAvailable(); if (!block_tree_db.ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) return error("Unable to get txids for address"); @@ -56,8 +57,7 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, std::vector& addressDeltaEntries, const bool timestamp_sort) { - if (!fAddressIndex) - return error("Address index not enabled"); + EnsureAddressIndexAvailable(); if (!mempool.getAddressIndex(addressDeltaIndex, addressDeltaEntries)) return error("Unable to get address delta information"); @@ -72,18 +72,14 @@ bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, return true; } -bool IsSpentIndexAvailable() -{ - return fSpentIndex; -} - 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 (!fSpentIndex) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Spent index is disabled. You should run Dash Core with -spentindex (requires reindex)"); + } if (mempool.getSpentIndex(key, value)) return true; @@ -94,18 +90,14 @@ bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const return true; } -bool IsTimestampIndexAvailable() -{ - return fTimestampIndex; -} - 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 (!fTimestampIndex) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Timestamp index is disabled. You should run Dash Core with -timestampindex (requires reindex)"); + } if (!block_tree_db.ReadTimestampIndex(high, low, hashes)) return error("Unable to get hashes for timestamps"); diff --git a/src/rpc/index_util.h b/src/rpc/index_util.h index bc79e5a96c..c5bc19b016 100644 --- a/src/rpc/index_util.h +++ b/src/rpc/index_util.h @@ -24,25 +24,27 @@ enum class AddressType : uint8_t; extern RecursiveMutex cs_main; -bool IsAddressIndexAvailable(); +//! throws JSONRPCError if address index is unavailable 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) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +//! throws JSONRPCError if address index is unavailable bool GetAddressUnspentIndex(CBlockTreeDB& block_tree_db, const uint160& addressHash, const AddressType type, std::vector& unspentOutputs, const bool height_sort = false) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +//! throws JSONRPCError if address index is unavailable bool GetMempoolAddressDeltaIndex(const CTxMemPool& mempool, const std::vector& addressDeltaIndex, std::vector& addressDeltaEntries, const bool timestamp_sort = false); -bool IsSpentIndexAvailable(); +//! throws JSONRPCError if spent index is unavailable bool GetSpentIndex(CBlockTreeDB& block_tree_db, const CTxMemPool& mempool, const CSpentIndexKey& key, CSpentIndexValue& value) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); -bool IsTimestampIndexAvailable(); +//! throws JSONRPCError if timestamp index is unavailable bool GetTimestampIndex(CBlockTreeDB& block_tree_db, const uint32_t high, const uint32_t low, std::vector& hashes) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 287d7d03ba..4f42dffe9a 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -742,10 +742,6 @@ static RPCHelpMan getaddressmempool() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsAddressIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); - } - CTxMemPool& mempool = EnsureAnyMemPool(request.context); std::vector> addresses; @@ -818,12 +814,7 @@ static RPCHelpMan getaddressutxos() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsAddressIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); - } - std::vector > addresses; - if (!getAddressesFromParams(request.params, addresses)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } @@ -894,10 +885,6 @@ static RPCHelpMan getaddressdeltas() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsAddressIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); - } - UniValue startValue = find_value(request.params[0].get_obj(), "start"); UniValue endValue = find_value(request.params[0].get_obj(), "end"); @@ -988,10 +975,6 @@ static RPCHelpMan getaddressbalance() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsAddressIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); - } - std::vector > addresses; if (!getAddressesFromParams(request.params, addresses)) { @@ -1064,10 +1047,6 @@ static RPCHelpMan getaddresstxids() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsAddressIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Address index is disabled. You should run Dash Core with -addressindex (requires reindex)"); - } - std::vector > addresses; if (!getAddressesFromParams(request.params, addresses)) { @@ -1157,10 +1136,6 @@ static RPCHelpMan getspentinfo() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (!IsSpentIndexAvailable()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Spent index is disabled. You should run Dash Core with -spentindex (requires reindex)"); - } - UniValue txidValue = find_value(request.params[0].get_obj(), "txid"); UniValue indexValue = find_value(request.params[0].get_obj(), "index"); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 375a7e46cf..78ae6ec3a5 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -75,7 +75,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo // Add spent information if spentindex is enabled CSpentIndexTxInfo txSpentInfo; - if (IsSpentIndexAvailable()) { + if (fSpentIndex) { txSpentInfo = CSpentIndexTxInfo{}; for (const auto& txin : tx.vin) { if (!tx.IsCoinBase()) {