Skip to content

Commit 8f9ad12

Browse files
committed
tx_pool: fix early return in remove_transaction_keyimages
Replace CHECK_AND_ASSERT_MES macros with explicit error checks that continue processing remaining inputs instead of returning early. The previous behavior could leave orphaned key images in m_spent_key_images when an error was encountered partway through the input list, since callers already deleted the transaction from the pool before calling this function. Track success via an all_found flag so the return value still indicates whether all key images were found and removed. Also clean up empty key_image sets instead of just failing on them. Resolves the FIXME at the top of the function that noted: "Should probably not return early, however."
1 parent 6f284e8 commit 8f9ad12

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

src/cryptonote_core/tx_pool.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -501,37 +501,56 @@ namespace cryptonote
501501
return true;
502502
}
503503
//---------------------------------------------------------------------------------
504-
//FIXME: Can return early before removal of all of the key images.
505-
// At the least, need to make sure that a false return here
506-
// is treated properly. Should probably not return early, however.
507504
bool tx_memory_pool::remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &actual_hash)
508505
{
509506
CRITICAL_REGION_LOCAL(m_transactions_lock);
510507
CRITICAL_REGION_LOCAL1(m_blockchain);
511508
// ND: Speedup
509+
bool all_found = true;
512510
for(const txin_v& vi: tx.vin)
513511
{
514-
CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false);
515-
auto it = m_spent_key_images.find(txin.k_image);
516-
CHECK_AND_ASSERT_MES(it != m_spent_key_images.end(), false, "failed to find transaction input in key images. img=" << txin.k_image << ENDL
517-
<< "transaction id = " << actual_hash);
518-
std::unordered_set<crypto::hash>& key_image_set = it->second;
519-
CHECK_AND_ASSERT_MES(key_image_set.size(), false, "empty key_image set, img=" << txin.k_image << ENDL
520-
<< "transaction id = " << actual_hash);
512+
const txin_to_key *txin = boost::get<txin_to_key>(&vi);
513+
if (nullptr == txin)
514+
{
515+
MERROR("unexpected input variant type in remove_transaction_keyimages, transaction id = " << actual_hash);
516+
all_found = false;
517+
continue;
518+
}
519+
auto it = m_spent_key_images.find(txin->k_image);
520+
if(it == m_spent_key_images.end())
521+
{
522+
MERROR("failed to find transaction input in key images. img=" << txin->k_image << ENDL
523+
<< "transaction id = " << actual_hash);
524+
all_found = false;
525+
continue;
526+
}
527+
std::unordered_set<crypto::hash>& key_image_set = it->second;
528+
if(key_image_set.empty())
529+
{
530+
MERROR("empty key_image set, img=" << txin->k_image << ENDL
531+
<< "transaction id = " << actual_hash);
532+
m_spent_key_images.erase(it);
533+
all_found = false;
534+
continue;
535+
}
521536

522537
auto it_in_set = key_image_set.find(actual_hash);
523-
CHECK_AND_ASSERT_MES(it_in_set != key_image_set.end(), false, "transaction id not found in key_image set, img=" << txin.k_image << ENDL
524-
<< "transaction id = " << actual_hash);
538+
if(it_in_set == key_image_set.end())
539+
{
540+
MERROR("transaction id not found in key_image set, img=" << txin->k_image << ENDL
541+
<< "transaction id = " << actual_hash);
542+
all_found = false;
543+
continue;
544+
}
525545
key_image_set.erase(it_in_set);
526-
if(!key_image_set.size())
546+
if(key_image_set.empty())
527547
{
528548
//it is now empty hash container for this key_image
529549
m_spent_key_images.erase(it);
530550
}
531-
532551
}
533552
++m_cookie;
534-
return true;
553+
return all_found;
535554
}
536555
//---------------------------------------------------------------------------------
537556
bool tx_memory_pool::take_tx(const crypto::hash &id,

0 commit comments

Comments
 (0)