diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index e3888487d..3baf38f6c 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1286,12 +1286,16 @@ public: * * @param txid_template the transaction id template * @param nbits number of bits to compare against in the template + * @param category tx relay category for which to filter txs in the mempool * @param max_num_txs The maximum number of txids to match, if we hit this limit, throw early * @return std::vector the list of all matching txids * * @throw TX_EXISTS if the number of txids that match exceed `max_num_txs` */ - virtual std::vector get_txids_loose(const crypto::hash& txid_template, std::uint32_t nbits, uint64_t max_num_txs = 0) = 0; + virtual std::vector get_txids_loose(const crypto::hash& txid_template, + std::uint32_t nbits, + relay_category category, + uint64_t max_num_txs = 0) = 0; /** * @brief fetches a variable number of blocks and transactions from the given height, in canonical blockchain order diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 173aa1f5a..14c53f271 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -3137,7 +3137,10 @@ bool BlockchainLMDB::get_pruned_tx_blobs_from(const crypto::hash& h, size_t coun return true; } -std::vector BlockchainLMDB::get_txids_loose(const crypto::hash& txid_template, std::uint32_t bits, uint64_t max_num_txs) +std::vector BlockchainLMDB::get_txids_loose(const crypto::hash& txid_template, + std::uint32_t bits, + relay_category category, + uint64_t max_num_txs) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -3163,6 +3166,7 @@ std::vector BlockchainLMDB::get_txids_loose(const crypto::hash& tx // In tx_indicies, the hash is stored at the data, in txpool_meta at the key const crypto::hash* const p_dbtxid = (const crypto::hash*)(doing_chain ? v.mv_data : k.mv_data); + const txpool_tx_meta_t* p_meta = (const txpool_tx_meta_t*)(doing_chain ? nullptr : v.mv_data); // Check if we reached the end of a DB or the hashes no longer match the template if (get_result == MDB_NOTFOUND || compare_hash32_reversed_nbits(txid_template, *p_dbtxid, bits)) @@ -3178,6 +3182,9 @@ std::vector BlockchainLMDB::get_txids_loose(const crypto::hash& tx } break; // if we get to this point, then we finished pool processing and we are done } + // If processing mempool, check that the tx matches relay category + else if (p_meta && !p_meta->matches(category)) + continue; else if (matching_hashes.size() >= max_num_txs && max_num_txs != 0) throw0(TX_EXISTS("number of tx hashes in template range exceeds maximum")); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index a3924190a..b084e6746 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -258,7 +258,7 @@ public: bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override; bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override; - std::vector get_txids_loose(const crypto::hash& h, std::uint32_t bits, uint64_t max_num_txs = 0) override; + std::vector get_txids_loose(const crypto::hash& h, std::uint32_t bits, relay_category category, uint64_t max_num_txs = 0) override; uint64_t get_tx_count() const override; diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h index 5b1614e90..5e79a4fa8 100644 --- a/src/blockchain_db/testdb.h +++ b/src/blockchain_db/testdb.h @@ -71,7 +71,7 @@ public: virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector &bd) const override { return false; } virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const override { return false; } - virtual std::vector get_txids_loose(const crypto::hash& h, std::uint32_t bits, uint64_t max_num_txs = 0) override { return {}; } + virtual std::vector get_txids_loose(const crypto::hash& h, std::uint32_t bits, relay_category category, uint64_t max_num_txs = 0) override { return {}; } virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override { return false; } virtual uint64_t get_block_height(const crypto::hash& h) const override { return 0; } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index d758109e2..f71db2eae 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -3633,7 +3633,8 @@ namespace cryptonote // so shunting this request to a random node seems counterproductive. #if BYTE_ORDER == LITTLE_ENDIAN - const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (m_restricted ? 1 : 10); + const bool restricted = m_restricted && ctx; + const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (restricted ? 1 : 10); // Sanity check parameters if (req.num_matching_bits > 256) @@ -3673,9 +3674,14 @@ namespace cryptonote try { // Do the DB fetch - const auto txids = m_core.get_blockchain_storage().get_db().get_txids_loose(search_hash, req.num_matching_bits, max_num_txids); + const relay_category tx_relay_category = restricted ? relay_category::broadcasted : relay_category::all; + const std::vector txids = m_core.get_blockchain_storage().get_db().get_txids_loose( + search_hash, + req.num_matching_bits, + tx_relay_category, + max_num_txids); // Fill out response form - for (const auto& txid : txids) + for (const crypto::hash& txid : txids) res.txids.emplace_back(epee::string_tools::pod_to_hex(txid)); } catch (const TX_EXISTS&)