aboutsummaryrefslogtreecommitdiff
path: root/src/blockchain_db
diff options
context:
space:
mode:
authorbinaryFate <binaryfate@users.noreply.github.com>2017-11-08 13:06:41 +0100
committerbinaryFate <binaryfate@users.noreply.github.com>2017-11-08 13:07:07 +0100
commit10013e94342c0d9ca2f10c79779b08affc5209c1 (patch)
treebf0a97c4a827807d50977861f6a33838ec6b6991 /src/blockchain_db
parentMerge pull request #2764 (diff)
downloadmonero-10013e94342c0d9ca2f10c79779b08affc5209c1.tar.xz
Protect node privacy by proper filtering in restricted-mode RPC answers
This patch allows to filter out sensitive information for queries that rely on the pool state, when running in restricted mode. This filtering is only applied to data sent back to RPC queries. Results of inline commands typed locally in the daemon are not affected. In practice, when running with `--restricted-rpc`: * get_transaction_pool will list relayed transactions with the fields "last relayed time" and "received time" set to zero. * get_transaction_pool will not list transaction that have do_not_relay set to true, and will not list key images that are used only for such transactions * get_transaction_pool_hashes.bin will not list such transaction * get_transaction_pool_stats will not count such transactions in any of the aggregated values that are computed The implementation does not make filtering the default, so developers should be mindful of this if they add new RPC functionality. Fixes #2590.
Diffstat (limited to 'src/blockchain_db')
-rw-r--r--src/blockchain_db/blockchain_db.h4
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp45
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h4
3 files changed, 42 insertions, 11 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 838385e8a..9b5ffec15 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -1314,7 +1314,7 @@ public:
/**
* @brief get the number of transactions in the txpool
*/
- virtual uint64_t get_txpool_tx_count() const = 0;
+ virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const = 0;
/**
* @brief check whether a txid is in the txpool
@@ -1369,7 +1369,7 @@ public:
*
* @return false if the function returns false for any transaction, otherwise true
*/
- virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false) const = 0;
+ virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, bool include_unrelayed_txes = true) const = 0;
/**
* @brief runs a function over all key images stored
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 5bd02bcf7..6ebb35639 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -1522,21 +1522,49 @@ void BlockchainLMDB::update_txpool_tx(const crypto::hash &txid, const txpool_tx_
}
}
-uint64_t BlockchainLMDB::get_txpool_tx_count() const
+uint64_t BlockchainLMDB::get_txpool_tx_count(bool include_unrelayed_txes) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- TXN_PREFIX_RDONLY();
int result;
+ uint64_t num_entries = 0;
- MDB_stat db_stats;
- if ((result = mdb_stat(m_txn, m_txpool_meta, &db_stats)))
- throw0(DB_ERROR(lmdb_error("Failed to query m_txpool_meta: ", result).c_str()));
+ TXN_PREFIX_RDONLY();
+
+ if (include_unrelayed_txes)
+ {
+ // No filtering, we can get the number of tx the "fast" way
+ MDB_stat db_stats;
+ if ((result = mdb_stat(m_txn, m_txpool_meta, &db_stats)))
+ throw0(DB_ERROR(lmdb_error("Failed to query m_txpool_meta: ", result).c_str()));
+ num_entries = db_stats.ms_entries;
+ }
+ else
+ {
+ // Filter unrelayed tx out of the result, so we need to loop over transactions and check their meta data
+ RCURSOR(txpool_meta);
+ RCURSOR(txpool_blob);
+ MDB_val k;
+ MDB_val v;
+ MDB_cursor_op op = MDB_FIRST;
+ while (1)
+ {
+ result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, op);
+ op = MDB_NEXT;
+ if (result == MDB_NOTFOUND)
+ break;
+ if (result)
+ throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str()));
+ const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
+ if (!meta.do_not_relay)
+ ++num_entries;
+ }
+ }
TXN_POSTFIX_RDONLY();
- return db_stats.ms_entries;
+ return num_entries;
}
bool BlockchainLMDB::txpool_has_tx(const crypto::hash& txid) const
@@ -1633,7 +1661,7 @@ cryptonote::blobdata BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid
return bd;
}
-bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob) const
+bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, bool include_unrelayed_txes) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@@ -1657,6 +1685,9 @@ bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&,
throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str()));
const crypto::hash txid = *(const crypto::hash*)k.mv_data;
const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
+ if (!include_unrelayed_txes && meta.do_not_relay)
+ // Skipping that tx
+ continue;
const cryptonote::blobdata *passed_bd = NULL;
cryptonote::blobdata bd;
if (include_blob)
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index 98571a7f8..fce8f29ed 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -243,13 +243,13 @@ public:
virtual void add_txpool_tx(const transaction &tx, const txpool_tx_meta_t& meta);
virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& meta);
- virtual uint64_t get_txpool_tx_count() const;
+ virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const;
virtual bool txpool_has_tx(const crypto::hash &txid) const;
virtual void remove_txpool_tx(const crypto::hash& txid);
virtual txpool_tx_meta_t get_txpool_tx_meta(const crypto::hash& txid) const;
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const;
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const;
- virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false) const;
+ virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false, bool include_unrelayed_txes = true) const;
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
virtual bool for_blocks_range(const uint64_t& h1, const uint64_t& h2, std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const;