Merge pull request #10512

b8cc5b6 blockchain_db: hide sensitive txs in get_txids_loose (jeffro256)
This commit is contained in:
tobtoht
2026-06-09 18:40:12 +00:00
5 changed files with 24 additions and 7 deletions
+5 -1
View File
@@ -1278,12 +1278,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<crypto::hash> the list of all matching txids
*
* @throw TX_EXISTS if the number of txids that match exceed `max_num_txs`
*/
virtual std::vector<crypto::hash> get_txids_loose(const crypto::hash& txid_template, std::uint32_t nbits, uint64_t max_num_txs = 0) = 0;
virtual std::vector<crypto::hash> 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
+8 -1
View File
@@ -3141,7 +3141,10 @@ bool BlockchainLMDB::get_pruned_tx_blobs_from(const crypto::hash& h, size_t coun
return true;
}
std::vector<crypto::hash> BlockchainLMDB::get_txids_loose(const crypto::hash& txid_template, std::uint32_t bits, uint64_t max_num_txs)
std::vector<crypto::hash> 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();
@@ -3167,6 +3170,7 @@ std::vector<crypto::hash> 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))
@@ -3182,6 +3186,9 @@ std::vector<crypto::hash> 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"));
+1 -1
View File
@@ -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<crypto::hash> get_txids_loose(const crypto::hash& h, std::uint32_t bits, uint64_t max_num_txs = 0) override;
std::vector<crypto::hash> 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;
+1 -1
View File
@@ -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<cryptonote::blobdata> &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::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata>>>>& blocks, bool pruned, bool get_miner_tx_hash) const override { return false; }
virtual std::vector<crypto::hash> get_txids_loose(const crypto::hash& h, std::uint32_t bits, uint64_t max_num_txs = 0) override { return {}; }
virtual std::vector<crypto::hash> 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; }
+9 -3
View File
@@ -3409,7 +3409,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)
@@ -3449,9 +3450,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<crypto::hash> 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&)