diff options
-rw-r--r-- | src/blockchain_db/blockchain_db.h | 4 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 45 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.h | 4 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 8 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.h | 4 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 16 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 14 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 62 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 22 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.cpp | 6 | ||||
-rwxr-xr-x | src/rpc/core_rpc_server.cpp | 18 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 8 | ||||
-rw-r--r-- | tests/unit_tests/hardfork.cpp | 4 |
13 files changed, 140 insertions, 75 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index ca097fad2..79676b808 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1315,7 +1315,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 @@ -1370,7 +1370,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; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 0296b4908..4e1ab8a48 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -4211,9 +4211,9 @@ void Blockchain::remove_txpool_tx(const crypto::hash &txid) m_db->remove_txpool_tx(txid); } -uint64_t Blockchain::get_txpool_tx_count() const +uint64_t Blockchain::get_txpool_tx_count(bool include_unrelayed_txes) const { - return m_db->get_txpool_tx_count(); + return m_db->get_txpool_tx_count(include_unrelayed_txes); } txpool_tx_meta_t Blockchain::get_txpool_tx_meta(const crypto::hash& txid) const @@ -4231,9 +4231,9 @@ cryptonote::blobdata Blockchain::get_txpool_tx_blob(const crypto::hash& txid) co return m_db->get_txpool_tx_blob(txid); } -bool Blockchain::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob) const +bool Blockchain::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 { - return m_db->for_all_txpool_txes(f, include_blob); + return m_db->for_all_txpool_txes(f, include_blob, include_unrelayed_txes); } void Blockchain::set_user_options(uint64_t maxthreads, uint64_t blocks_per_sync, blockchain_db_sync_mode sync_mode, bool fast_sync) diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index f64bd35e3..3f2930fb0 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -947,11 +947,11 @@ namespace cryptonote void add_txpool_tx(transaction &tx, const txpool_tx_meta_t &meta); void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta); void remove_txpool_tx(const crypto::hash &txid); - uint64_t get_txpool_tx_count() const; + uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const; txpool_tx_meta_t get_txpool_tx_meta(const crypto::hash& txid) const; bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const; cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const; - bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false) const; + 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; bool is_within_compiled_block_hash_area(uint64_t height) const; bool is_within_compiled_block_hash_area() const { return is_within_compiled_block_hash_area(m_db->height()); } diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 61f844612..3f56ffac7 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1182,21 +1182,21 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- - bool core::get_pool_transactions(std::list<transaction>& txs) const + bool core::get_pool_transactions(std::list<transaction>& txs, bool include_sensitive_data) const { - m_mempool.get_transactions(txs); + m_mempool.get_transactions(txs, include_sensitive_data); return true; } //----------------------------------------------------------------------------------------------- - bool core::get_pool_transaction_hashes(std::vector<crypto::hash>& txs) const + bool core::get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_sensitive_data) const { - m_mempool.get_transaction_hashes(txs); + m_mempool.get_transaction_hashes(txs, include_sensitive_data); return true; } //----------------------------------------------------------------------------------------------- - bool core::get_pool_transaction_stats(struct txpool_stats& stats) const + bool core::get_pool_transaction_stats(struct txpool_stats& stats, bool include_sensitive_data) const { - m_mempool.get_transaction_stats(stats); + m_mempool.get_transaction_stats(stats, include_sensitive_data); return true; } //----------------------------------------------------------------------------------------------- @@ -1210,9 +1210,9 @@ namespace cryptonote return m_mempool.have_tx(id); } //----------------------------------------------------------------------------------------------- - bool core::get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const + bool core::get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data) const { - return m_mempool.get_transactions_and_spent_keys_info(tx_infos, key_image_infos); + return m_mempool.get_transactions_and_spent_keys_info(tx_infos, key_image_infos, include_sensitive_data); } //----------------------------------------------------------------------------------------------- bool core::get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 7340e1024..a3d47280a 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -420,11 +420,12 @@ namespace cryptonote /** * @copydoc tx_memory_pool::get_transactions + * @param include_unrelayed_txes include unrelayed txes in result * * @note see tx_memory_pool::get_transactions */ - bool get_pool_transactions(std::list<transaction>& txs) const; - + bool get_pool_transactions(std::list<transaction>& txs, bool include_unrelayed_txes = true) const; + /** * @copydoc tx_memory_pool::get_txpool_backlog * @@ -434,17 +435,19 @@ namespace cryptonote /** * @copydoc tx_memory_pool::get_transactions + * @param include_unrelayed_txes include unrelayed txes in result * * @note see tx_memory_pool::get_transactions */ - bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs) const; + bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const; /** * @copydoc tx_memory_pool::get_transactions + * @param include_unrelayed_txes include unrelayed txes in result * * @note see tx_memory_pool::get_transactions */ - bool get_pool_transaction_stats(struct txpool_stats& stats) const; + bool get_pool_transaction_stats(struct txpool_stats& stats, bool include_unrelayed_txes = true) const; /** * @copydoc tx_memory_pool::get_transaction @@ -455,10 +458,11 @@ namespace cryptonote /** * @copydoc tx_memory_pool::get_pool_transactions_and_spent_keys_info + * @param include_unrelayed_txes include unrelayed txes in result * * @note see tx_memory_pool::get_pool_transactions_and_spent_keys_info */ - bool get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const; + bool get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_unrelayed_txes = true) const; /** * @copydoc tx_memory_pool::get_pool_for_rpc diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 40691f6a3..6bfcfe529 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -436,7 +436,7 @@ namespace cryptonote remove.insert(txid); } return true; - }); + }, false); if (!remove.empty()) { @@ -498,7 +498,7 @@ namespace cryptonote } } return true; - }); + }, false); return true; } //--------------------------------------------------------------------------------- @@ -525,14 +525,14 @@ namespace cryptonote } } //--------------------------------------------------------------------------------- - size_t tx_memory_pool::get_transactions_count() const + size_t tx_memory_pool::get_transactions_count(bool include_unrelayed_txes) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); - return m_blockchain.get_txpool_tx_count(); + return m_blockchain.get_txpool_tx_count(include_unrelayed_txes); } //--------------------------------------------------------------------------------- - void tx_memory_pool::get_transactions(std::list<transaction>& txs) const + void tx_memory_pool::get_transactions(std::list<transaction>& txs, bool include_unrelayed_txes) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); @@ -546,20 +546,20 @@ namespace cryptonote } txs.push_back(tx); return true; - }, true); + }, true, include_unrelayed_txes); } //------------------------------------------------------------------ - void tx_memory_pool::get_transaction_hashes(std::vector<crypto::hash>& txs) const + void tx_memory_pool::get_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); m_blockchain.for_all_txpool_txes([&txs](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ txs.push_back(txid); return true; - }); + }, false, include_unrelayed_txes); } //------------------------------------------------------------------ - void tx_memory_pool::get_transaction_backlog(std::vector<tx_backlog_entry>& backlog) const + void tx_memory_pool::get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_unrelayed_txes) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); @@ -567,16 +567,16 @@ namespace cryptonote m_blockchain.for_all_txpool_txes([&backlog, now](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ backlog.push_back({meta.blob_size, meta.fee, meta.receive_time - now}); return true; - }); + }, false, include_unrelayed_txes); } //------------------------------------------------------------------ - void tx_memory_pool::get_transaction_stats(struct txpool_stats& stats) const + void tx_memory_pool::get_transaction_stats(struct txpool_stats& stats, bool include_unrelayed_txes) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); const uint64_t now = time(NULL); std::map<uint64_t, txpool_histo> agebytes; - stats.txs_total = m_blockchain.get_txpool_tx_count(); + stats.txs_total = m_blockchain.get_txpool_tx_count(include_unrelayed_txes); std::vector<uint32_t> sizes; sizes.reserve(stats.txs_total); m_blockchain.for_all_txpool_txes([&stats, &sizes, now, &agebytes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ @@ -601,7 +601,7 @@ namespace cryptonote if (meta.double_spend_seen) ++stats.num_double_spends; return true; - }); + }, false, include_unrelayed_txes); stats.bytes_med = epee::misc_utils::median(sizes); if (stats.txs_total > 1) { @@ -648,11 +648,11 @@ namespace cryptonote } //------------------------------------------------------------------ //TODO: investigate whether boolean return is appropriate - bool tx_memory_pool::get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const + bool tx_memory_pool::get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); - m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ + m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ tx_info txi; txi.id_hash = epee::string_tools::pod_to_hex(txid); txi.tx_blob = *bd; @@ -671,15 +671,18 @@ namespace cryptonote txi.max_used_block_id_hash = epee::string_tools::pod_to_hex(meta.max_used_block_id); txi.last_failed_height = meta.last_failed_height; txi.last_failed_id_hash = epee::string_tools::pod_to_hex(meta.last_failed_id); - txi.receive_time = meta.receive_time; + // In restricted mode we do not include this data: + txi.receive_time = include_sensitive_data ? meta.receive_time : 0; txi.relayed = meta.relayed; - txi.last_relayed_time = meta.last_relayed_time; + // In restricted mode we do not include this data: + txi.last_relayed_time = include_sensitive_data ? meta.last_relayed_time : 0; txi.do_not_relay = meta.do_not_relay; txi.double_spend_seen = meta.double_spend_seen; tx_infos.push_back(txi); return true; - }, true); + }, true, include_sensitive_data); + txpool_tx_meta_t meta; for (const key_images_container::value_type& kee : m_spent_key_images) { const crypto::key_image& k_image = kee.first; const std::unordered_set<crypto::hash>& kei_image_set = kee.second; @@ -687,9 +690,26 @@ namespace cryptonote ki.id_hash = epee::string_tools::pod_to_hex(k_image); for (const crypto::hash& tx_id_hash : kei_image_set) { + if (!include_sensitive_data) + { + try + { + meta = m_blockchain.get_txpool_tx_meta(tx_id_hash); + if (!meta.relayed) + // Do not include that transaction if in restricted mode and it's not relayed + continue; + } + catch (const std::exception &e) + { + MERROR("Failed to get tx meta from txpool: " << e.what()); + return false; + } + } ki.txs_hashes.push_back(epee::string_tools::pod_to_hex(tx_id_hash)); } - key_image_infos.push_back(ki); + // Only return key images for which we have at least one tx that we can show for them + if (!ki.txs_hashes.empty()) + key_image_infos.push_back(ki); } return true; } @@ -723,7 +743,7 @@ namespace cryptonote txi.double_spend_seen = meta.double_spend_seen; tx_infos.push_back(txi); return true; - }, true); + }, true, false); for (const key_images_container::value_type& kee : m_spent_key_images) { std::vector<crypto::hash> tx_hashes; @@ -1090,7 +1110,7 @@ namespace cryptonote remove.insert(txid); } return true; - }); + }, false); size_t n_removed = 0; if (!remove.empty()) diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 8a0106638..d657c6554 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -234,29 +234,37 @@ namespace cryptonote * @brief get a list of all transactions in the pool * * @param txs return-by-reference the list of transactions + * @param include_unrelayed_txes include unrelayed txes in the result + * */ - void get_transactions(std::list<transaction>& txs) const; + void get_transactions(std::list<transaction>& txs, bool include_unrelayed_txes = true) const; /** * @brief get a list of all transaction hashes in the pool * * @param txs return-by-reference the list of transactions + * @param include_unrelayed_txes include unrelayed txes in the result + * */ - void get_transaction_hashes(std::vector<crypto::hash>& txs) const; + void get_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const; /** * @brief get (size, fee, receive time) for all transaction in the pool * * @param txs return-by-reference that data + * @param include_unrelayed_txes include unrelayed txes in the result + * */ - void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog) const; + void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_unrelayed_txes = true) const; /** * @brief get a summary statistics of all transaction hashes in the pool * * @param stats return-by-reference the pool statistics + * @param include_unrelayed_txes include unrelayed txes in the result + * */ - void get_transaction_stats(struct txpool_stats& stats) const; + void get_transaction_stats(struct txpool_stats& stats, bool include_unrelayed_txes = true) const; /** * @brief get information about all transactions and key images in the pool @@ -265,10 +273,11 @@ namespace cryptonote * * @param tx_infos return-by-reference the transactions' information * @param key_image_infos return-by-reference the spent key images' information + * @param include_sensitive_data include unrelayed txes and fields that are sensitive to the node privacy * * @return true */ - bool get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const; + bool get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data = true) const; /** * @brief get information about all transactions and key images in the pool @@ -309,6 +318,7 @@ namespace cryptonote * nonzero fee * hasn't been relayed too recently * isn't old enough that relaying it is considered harmful + * Note a transaction can be "relayable" even if do_not_relay is true * * @param txs return-by-reference the transactions and their hashes * @@ -328,7 +338,7 @@ namespace cryptonote * * @return the number of transactions in the pool */ - size_t get_transactions_count() const; + size_t get_transactions_count(bool include_unrelayed_txes = true) const; /** * @brief get a string containing human-readable pool information diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 6733d66c2..83b04bff5 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -814,7 +814,7 @@ bool t_rpc_command_executor::print_transaction_pool_long() { } else { - if (!m_rpc_server->on_get_transaction_pool(req, res) || res.status != CORE_RPC_STATUS_OK) + if (!m_rpc_server->on_get_transaction_pool(req, res, false) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); return true; @@ -899,7 +899,7 @@ bool t_rpc_command_executor::print_transaction_pool_short() { } else { - if (!m_rpc_server->on_get_transaction_pool(req, res) || res.status != CORE_RPC_STATUS_OK) + if (!m_rpc_server->on_get_transaction_pool(req, res, false) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); return true; @@ -956,7 +956,7 @@ bool t_rpc_command_executor::print_transaction_pool_stats() { else { memset(&res.pool_stats, 0, sizeof(res.pool_stats)); - if (!m_rpc_server->on_get_transaction_pool_stats(req, res) || res.status != CORE_RPC_STATUS_OK) + if (!m_rpc_server->on_get_transaction_pool_stats(req, res, false) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); return true; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index e653b9520..9094ec732 100755 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -591,7 +591,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res) + bool core_rpc_server::on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, bool request_has_rpc_origin) { CHECK_CORE_BUSY(); std::vector<crypto::key_image> key_images; @@ -623,7 +623,7 @@ namespace cryptonote // check the pool too std::vector<cryptonote::tx_info> txs; std::vector<cryptonote::spent_key_image_info> ki; - r = m_core.get_pool_transactions_and_spent_keys_info(txs, ki); + r = m_core.get_pool_transactions_and_spent_keys_info(txs, ki, !request_has_rpc_origin || !m_restricted); if(!r) { res.status = "Failed"; @@ -870,26 +870,26 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res) + bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, bool request_has_rpc_origin) { CHECK_CORE_BUSY(); - m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images); + m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !m_restricted); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res) + bool core_rpc_server::on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, bool request_has_rpc_origin) { CHECK_CORE_BUSY(); - m_core.get_pool_transaction_hashes(res.tx_hashes); + m_core.get_pool_transaction_hashes(res.tx_hashes, !request_has_rpc_origin || !m_restricted); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res) + bool core_rpc_server::on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, bool request_has_rpc_origin) { CHECK_CORE_BUSY(); - m_core.get_pool_transaction_stats(res.pool_stats); + m_core.get_pool_transaction_stats(res.pool_stats, !request_has_rpc_origin || !m_restricted); res.status = CORE_RPC_STATUS_OK; return true; } @@ -1852,7 +1852,7 @@ namespace cryptonote const command_line::arg_descriptor<bool> core_rpc_server::arg_restricted_rpc = { "restricted-rpc" - , "Restrict RPC to view only commands" + , "Restrict RPC to view only commands and do not return privacy sensitive data in RPC calls" , false }; } // namespace cryptonote diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 73a308a72..79405a9d3 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -137,7 +137,7 @@ namespace cryptonote bool on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res); bool on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res); bool on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res); - bool on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res); + bool on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, bool request_has_rpc_origin = true); bool on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res); bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res); bool on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res); @@ -153,9 +153,9 @@ namespace cryptonote bool on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res); bool on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res); bool on_set_log_categories(const COMMAND_RPC_SET_LOG_CATEGORIES::request& req, COMMAND_RPC_SET_LOG_CATEGORIES::response& res); - bool on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res); - bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res); - bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res); + bool on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, bool request_has_rpc_origin = true); + bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, bool request_has_rpc_origin = true); + bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, bool request_has_rpc_origin = true); bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res); bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res); bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res); diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index 2b0904224..c235f49fd 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -115,13 +115,13 @@ public: virtual void add_txpool_tx(const transaction &tx, const txpool_tx_meta_t& details) {} virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& details) {} - virtual uint64_t get_txpool_tx_count() const { return 0; } + virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const { return 0; } virtual bool txpool_has_tx(const crypto::hash &txid) const { return false; } virtual void remove_txpool_tx(const crypto::hash& txid) {} virtual txpool_tx_meta_t get_txpool_tx_meta(const crypto::hash& txid) const { return txpool_tx_meta_t(); } virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const { return false; } virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const { return ""; } - 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 { return false; } + 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 = false) const { return false; } virtual void add_block( const block& blk , const size_t& block_size |