aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2020-04-10 16:10:33 -0500
committerluigi1111 <luigi1111w@gmail.com>2020-04-10 16:10:33 -0500
commit228af683a7e187c4541ea50621ed4b3382c5eb6a (patch)
treed617991d6bd17f31b433d7ade31b1a9c4e86016c /src
parentMerge pull request #6398 (diff)
parentCorrect key image check in tx_pool (diff)
downloadmonero-228af683a7e187c4541ea50621ed4b3382c5eb6a.tar.xz
Merge pull request #6403
5de2295 Correct key image check in tx_pool (vtnerd)
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_core/tx_pool.cpp23
1 files changed, 7 insertions, 16 deletions
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 53a6ce579..d7fc89d61 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -404,27 +404,18 @@ namespace cryptonote
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, txin, false);
std::unordered_set<crypto::hash>& kei_image_set = m_spent_key_images[txin.k_image];
- /* If any existing key-image in the set is publicly visible AND this is
- not forcibly "kept_by_block", then fail (duplicate key image). If all
- existing key images are supposed to be hidden, we silently allow so
- that the node doesn't leak knowledge of a local/stem tx. */
- bool visible = false;
+ // Only allow multiple txes per key-image if kept-by-block. Only allow
+ // the same txid if going from local/stem->fluff.
+
if (tx_relay != relay_method::block)
{
- for (const crypto::hash& other_id : kei_image_set)
- visible |= m_blockchain.txpool_tx_matches_category(other_id, relay_category::legacy);
- }
-
- CHECK_AND_ASSERT_MES(!visible, false, "internal error: tx_relay=" << unsigned(tx_relay)
+ const bool one_txid =
+ (kei_image_set.empty() || (kei_image_set.size() == 1 && *(kei_image_set.cbegin()) == id));
+ CHECK_AND_ASSERT_MES(one_txid, false, "internal error: tx_relay=" << unsigned(tx_relay)
<< ", kei_image_set.size()=" << kei_image_set.size() << ENDL << "txin.k_image=" << txin.k_image << ENDL
<< "tx_id=" << id);
+ }
- /* If adding a tx (hash) that already exists, fail only if the tx has
- been publicly "broadcast" previously. This way, when a private tx is
- received for the first time from a remote node, "this" node will
- respond as-if it were seen for the first time. LMDB does the
- "hard-check" on key-images, so the effect is overwriting the existing
- tx_pool metadata and "first seen" time. */
const bool new_or_previously_private =
kei_image_set.insert(id).second ||
!m_blockchain.txpool_tx_matches_category(id, relay_category::legacy);