diff options
author | luigi1111 <luigi1111w@gmail.com> | 2020-04-21 09:03:37 -0500 |
---|---|---|
committer | luigi1111 <luigi1111w@gmail.com> | 2020-04-21 09:03:37 -0500 |
commit | c846c8650eb8a4822f85b8464410fdc6f8e55a8f (patch) | |
tree | 944e16375599f34b85cec42b6e9aee01c14d00fb /src | |
parent | Merge pull request #6433 (diff) | |
parent | Always reject duplicate key-images from second txid (diff) | |
download | monero-c846c8650eb8a4822f85b8464410fdc6f8e55a8f.tar.xz |
Merge pull request #6445
5715460 Always reject duplicate key-images from second txid (vtnerd)
babf25d Allow unrestricted rpc calls to get full txpool info (vtnerd)
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 8 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 6 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 22 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 6 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 19 |
5 files changed, 36 insertions, 25 deletions
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 10bbff457..3ff3c77e2 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -428,9 +428,9 @@ namespace cryptonote return m_blockchain_storage.get_split_transactions_blobs(txs_ids, txs, missed_txs); } //----------------------------------------------------------------------------------------------- - bool core::get_txpool_backlog(std::vector<tx_backlog_entry>& backlog) const + bool core::get_txpool_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive_txes) const { - m_mempool.get_transaction_backlog(backlog); + m_mempool.get_transaction_backlog(backlog, include_sensitive_txes); return true; } //----------------------------------------------------------------------------------------------- @@ -1544,9 +1544,9 @@ namespace cryptonote return m_blockchain_storage.get_db().get_block_cumulative_difficulty(height); } //----------------------------------------------------------------------------------------------- - size_t core::get_pool_transactions_count() const + size_t core::get_pool_transactions_count(bool include_sensitive_txes) const { - return m_mempool.get_transactions_count(); + return m_mempool.get_transactions_count(include_sensitive_txes); } //----------------------------------------------------------------------------------------------- bool core::have_block(const crypto::hash& id) const diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 79a846de1..255645efc 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -469,10 +469,11 @@ namespace cryptonote /** * @copydoc tx_memory_pool::get_txpool_backlog + * @param include_sensitive_txes include private transactions * * @note see tx_memory_pool::get_txpool_backlog */ - bool get_txpool_backlog(std::vector<tx_backlog_entry>& backlog) const; + bool get_txpool_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive_txes = false) const; /** * @copydoc tx_memory_pool::get_transactions @@ -514,10 +515,11 @@ namespace cryptonote /** * @copydoc tx_memory_pool::get_transactions_count + * @param include_sensitive_txes include private transactions * * @note see tx_memory_pool::get_transactions_count */ - size_t get_pool_transactions_count() const; + size_t get_pool_transactions_count(bool include_sensitive_txes = false) const; /** * @copydoc Blockchain::get_total_transactions diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index c49a3dabc..a7b2e4422 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -210,7 +210,7 @@ namespace cryptonote // TODO: Investigate why not? if(!kept_by_block) { - if(have_tx_keyimges_as_spent(tx)) + if(have_tx_keyimges_as_spent(tx, id)) { mark_double_spend(tx); LOG_PRINT_L1("Transaction with id= "<< id << " used already spent key images"); @@ -253,7 +253,7 @@ namespace cryptonote meta.last_relayed_time = time(NULL); meta.relayed = relayed; meta.set_relay_method(tx_relay); - meta.double_spend_seen = have_tx_keyimges_as_spent(tx); + meta.double_spend_seen = have_tx_keyimges_as_spent(tx, id); meta.pruned = tx.pruned; meta.bf_padding = 0; memset(meta.padding, 0, sizeof(meta.padding)); @@ -1098,30 +1098,32 @@ namespace cryptonote return m_blockchain.get_db().txpool_has_tx(id, tx_category); } //--------------------------------------------------------------------------------- - bool tx_memory_pool::have_tx_keyimges_as_spent(const transaction& tx) const + bool tx_memory_pool::have_tx_keyimges_as_spent(const transaction& tx, const crypto::hash& txid) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); for(const auto& in: tx.vin) { CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, true);//should never fail - if(have_tx_keyimg_as_spent(tokey_in.k_image)) + if(have_tx_keyimg_as_spent(tokey_in.k_image, txid)) return true; } return false; } //--------------------------------------------------------------------------------- - bool tx_memory_pool::have_tx_keyimg_as_spent(const crypto::key_image& key_im) const + bool tx_memory_pool::have_tx_keyimg_as_spent(const crypto::key_image& key_im, const crypto::hash& txid) const { CRITICAL_REGION_LOCAL(m_transactions_lock); - bool spent = false; const auto found = m_spent_key_images.find(key_im); - if (found != m_spent_key_images.end()) + if (found != m_spent_key_images.end() && !found->second.empty()) { - for (const crypto::hash& tx_hash : found->second) - spent |= m_blockchain.txpool_tx_matches_category(tx_hash, relay_category::broadcasted); + // If another tx is using the key image, always return as spent. + // See `insert_key_images`. + if (1 < found->second.size() || *(found->second.cbegin()) != txid) + return true; + return m_blockchain.txpool_tx_matches_category(txid, relay_category::broadcasted); } - return spent; + return false; } //--------------------------------------------------------------------------------- void tx_memory_pool::lock() const diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index ca0e50415..292d427e2 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -470,10 +470,11 @@ namespace cryptonote * @brief check if a transaction in the pool has a given spent key image * * @param key_im the spent key image to look for + * @param txid hash of the new transaction where `key_im` was seen. * * @return true if the spent key image is present, otherwise false */ - bool have_tx_keyimg_as_spent(const crypto::key_image& key_im) const; + bool have_tx_keyimg_as_spent(const crypto::key_image& key_im, const crypto::hash& txid) const; /** * @brief check if any spent key image in a transaction is in the pool @@ -484,10 +485,11 @@ namespace cryptonote * @note see tx_pool::have_tx_keyimg_as_spent * * @param tx the transaction to check spent key images of + * @param txid hash of `tx`. * * @return true if any spent key images are present in the pool, otherwise false */ - bool have_tx_keyimges_as_spent(const transaction& tx) const; + bool have_tx_keyimges_as_spent(const transaction& tx, const crypto::hash& txid) const; /** * @brief forget a transaction's spent key images diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 1fd0c037b..9b0eeb1f1 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -438,7 +438,7 @@ namespace cryptonote store_difficulty(m_core.get_blockchain_storage().get_difficulty_for_next_block(), res.difficulty, res.wide_difficulty, res.difficulty_top64); res.target = m_core.get_blockchain_storage().get_difficulty_target(); res.tx_count = m_core.get_blockchain_storage().get_total_transactions() - res.height; //without coinbase - res.tx_pool_size = m_core.get_pool_transactions_count(); + res.tx_pool_size = m_core.get_pool_transactions_count(!restricted); res.alt_blocks_count = restricted ? 0 : m_core.get_blockchain_storage().get_alternative_blocks_count(); uint64_t total_conn = restricted ? 0 : m_p2p.get_public_connections_count(); res.outgoing_connections_count = restricted ? 0 : m_p2p.get_public_outgoing_connections_count(); @@ -1119,6 +1119,8 @@ namespace cryptonote } res.sanity_check_failed = false; + const bool restricted = m_restricted && ctx; + tx_verification_context tvc{}; if(!m_core.handle_incoming_tx({tx_blob, crypto::null_hash}, tvc, (req.do_not_relay ? relay_method::none : relay_method::local), false) || tvc.m_verifivation_failed) { @@ -1423,12 +1425,13 @@ namespace cryptonote const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; + const bool allow_sensitive = !request_has_rpc_origin || !restricted; - size_t n_txes = m_core.get_pool_transactions_count(); + size_t n_txes = m_core.get_pool_transactions_count(allow_sensitive); if (n_txes > 0) { CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_TX); - m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !restricted); + m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, allow_sensitive); for (tx_info& txi : res.transactions) txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(txi.tx_blob); } @@ -1448,12 +1451,13 @@ namespace cryptonote const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; + const bool allow_sensitive = !request_has_rpc_origin || !restricted; - size_t n_txes = m_core.get_pool_transactions_count(); + size_t n_txes = m_core.get_pool_transactions_count(allow_sensitive); if (n_txes > 0) { CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_POOL_HASH); - m_core.get_pool_transaction_hashes(res.tx_hashes, !request_has_rpc_origin || !restricted); + m_core.get_pool_transaction_hashes(res.tx_hashes, allow_sensitive); } res.status = CORE_RPC_STATUS_OK; @@ -1471,13 +1475,14 @@ namespace cryptonote const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; + const bool allow_sensitive = !request_has_rpc_origin || !restricted; - size_t n_txes = m_core.get_pool_transactions_count(); + size_t n_txes = m_core.get_pool_transactions_count(allow_sensitive); if (n_txes > 0) { CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_POOL_HASH); std::vector<crypto::hash> tx_hashes; - m_core.get_pool_transaction_hashes(tx_hashes, !request_has_rpc_origin || !restricted); + m_core.get_pool_transaction_hashes(tx_hashes, allow_sensitive); res.tx_hashes.reserve(tx_hashes.size()); for (const crypto::hash &tx_hash: tx_hashes) res.tx_hashes.push_back(epee::string_tools::pod_to_hex(tx_hash)); |