@ -115,8 +115,10 @@ namespace cryptonote
}
//---------------------------------------------------------------------------------
bool tx_memory_pool : : add_tx ( transaction & tx , /*const crypto::hash& tx_prefix_hash,*/ const crypto : : hash & id , const cryptonote : : blobdata & blob , size_t tx_weight , tx_verification_context & tvc , bool kept_by_block , bool relayed , bool do_not_relay , uint8_t version )
bool tx_memory_pool : : add_tx ( transaction & tx , /*const crypto::hash& tx_prefix_hash,*/ const crypto : : hash & id , const cryptonote : : blobdata & blob , size_t tx_weight , tx_verification_context & tvc , relay_method tx_relay , bool relayed , uint8_t version )
{
const bool kept_by_block = ( tx_relay = = relay_method : : block ) ;
// this should already be called with that lock, but let's make it explicit for clarity
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
@ -227,7 +229,7 @@ namespace cryptonote
crypto : : hash max_used_block_id = null_hash ;
uint64_t max_used_block_height = 0 ;
cryptonote : : txpool_tx_meta_t meta ;
cryptonote : : txpool_tx_meta_t meta {} ;
bool ch_inp_res = check_tx_inputs ( [ & tx ] ( ) - > cryptonote : : transaction & { return tx ; } , id , max_used_block_height , max_used_block_id , tvc , kept_by_block ) ;
if ( ! ch_inp_res )
{
@ -241,11 +243,10 @@ namespace cryptonote
meta . max_used_block_height = 0 ;
meta . last_failed_height = 0 ;
meta . last_failed_id = null_hash ;
meta . kept_by_block = kept_by_block ;
meta . receive_time = receive_time ;
meta . last_relayed_time = time ( NULL ) ;
meta . relayed = relayed ;
meta . do_not_relay = do_not_relay ;
meta . set_relay_method( tx_relay ) ;
meta . double_spend_seen = have_tx_keyimges_as_spent ( tx ) ;
meta . pruned = tx . pruned ;
meta . bf_padding = 0 ;
@ -256,9 +257,10 @@ namespace cryptonote
m_parsed_tx_cache . insert ( std : : make_pair ( id , tx ) ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
LockedTXN lock ( m_blockchain ) ;
m_blockchain . add_txpool_tx ( id , blob , meta ) ;
if ( ! insert_key_images ( tx , id , kept_by_block ) )
if ( ! insert_key_images ( tx , id , tx_relay ) )
return false ;
m_blockchain . add_txpool_tx ( id , blob , meta ) ;
m_txs_by_fee_and_receive_time . emplace ( std : : pair < double , std : : time_t > ( fee / ( double ) ( tx_weight ? tx_weight : 1 ) , receive_time ) , id ) ;
lock . commit ( ) ;
}
@ -280,7 +282,6 @@ namespace cryptonote
{
//update transactions container
meta . weight = tx_weight ;
meta . kept_by_block = kept_by_block ;
meta . fee = fee ;
meta . max_used_block_id = max_used_block_id ;
meta . max_used_block_height = max_used_block_height ;
@ -289,7 +290,7 @@ namespace cryptonote
meta . receive_time = receive_time ;
meta . last_relayed_time = time ( NULL ) ;
meta . relayed = relayed ;
meta . do_not_relay = do_not_relay ;
meta . set_relay_method( tx_relay ) ;
meta . double_spend_seen = false ;
meta . pruned = tx . pruned ;
meta . bf_padding = 0 ;
@ -302,9 +303,10 @@ namespace cryptonote
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
LockedTXN lock ( m_blockchain ) ;
m_blockchain . remove_txpool_tx ( id ) ;
m_blockchain . add_txpool_tx ( id , blob , meta ) ;
if ( ! insert_key_images ( tx , id , kept_by_block ) )
if ( ! insert_key_images ( tx , id , tx_relay ) )
return false ;
m_blockchain . add_txpool_tx ( id , blob , meta ) ;
m_txs_by_fee_and_receive_time . emplace ( std : : pair < double , std : : time_t > ( fee / ( double ) ( tx_weight ? tx_weight : 1 ) , receive_time ) , id ) ;
lock . commit ( ) ;
}
@ -315,7 +317,7 @@ namespace cryptonote
}
tvc . m_added_to_pool = true ;
if ( meta . fee > 0 & & ! do_not_ relay)
if ( meta . fee > 0 & & tx_relay ! = relay_method: : none )
tvc . m_should_be_relayed = true ;
}
@ -331,7 +333,7 @@ namespace cryptonote
return true ;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool : : add_tx ( transaction & tx , tx_verification_context & tvc , bool keeped_by_block , bool relayed , bool do_not_relay , uint8_t version )
bool tx_memory_pool : : add_tx ( transaction & tx , tx_verification_context & tvc , relay_method tx_relay , bool relayed , uint8_t version )
{
crypto : : hash h = null_hash ;
size_t blob_size = 0 ;
@ -339,7 +341,7 @@ namespace cryptonote
t_serializable_object_to_blob ( tx , bl ) ;
if ( bl . size ( ) = = 0 | | ! get_transaction_hash ( tx , h ) )
return false ;
return add_tx ( tx , h , bl , get_transaction_weight ( tx , bl . size ( ) ) , tvc , keeped_by_block, relayed , do_not_relay , version ) ;
return add_tx ( tx , h , bl , get_transaction_weight ( tx , bl . size ( ) ) , tvc , tx_relay, relayed , version ) ;
}
//---------------------------------------------------------------------------------
size_t tx_memory_pool : : get_txpool_weight ( ) const
@ -375,7 +377,7 @@ namespace cryptonote
txpool_tx_meta_t meta ;
if ( ! m_blockchain . get_txpool_tx_meta ( txid , meta ) )
{
MERROR ( " Failed to find tx in txpool" ) ;
MERROR ( " Failed to find tx _meta in txpool" ) ;
return ;
}
// don't prune the kept_by_block ones, they're likely added because we're adding a block with those
@ -384,7 +386,7 @@ namespace cryptonote
- - it ;
continue ;
}
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( txid );
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( txid , relay_category : : all );
cryptonote : : transaction_prefix tx ;
if ( ! parse_and_validate_tx_prefix_from_blob ( txblob , tx ) )
{
@ -413,17 +415,38 @@ namespace cryptonote
MINFO ( " Pool weight after pruning is larger than limit: " < < m_txpool_weight < < " / " < < bytes ) ;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool : : insert_key_images ( const transaction_prefix & tx , const crypto : : hash & id , bool kept_by_block )
bool tx_memory_pool : : insert_key_images ( const transaction_prefix & tx , const crypto : : hash & id , relay_method tx_relay )
{
for ( const auto & in : tx . vin )
{
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 ] ;
CHECK_AND_ASSERT_MES ( kept_by_block | | kei_image_set . size ( ) = = 0 , false , " internal error: kept_by_block= " < < kept_by_block
< < " , kei_image_set.size()= " < < kei_image_set . size ( ) < < ENDL < < " txin.k_image= " < < txin . k_image < < ENDL
< < " tx_id= " < < id ) ;
auto ins_res = kei_image_set . insert ( id ) ;
CHECK_AND_ASSERT_MES ( ins_res . second , false , " internal error: try to insert duplicate iterator in key_image set " ) ;
/* 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 ;
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 )
< < " , 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 ) ;
CHECK_AND_ASSERT_MES ( new_or_previously_private , false , " internal error: try to insert duplicate iterator in key_image set " ) ;
}
+ + m_cookie ;
return true ;
@ -475,10 +498,10 @@ namespace cryptonote
txpool_tx_meta_t meta ;
if ( ! m_blockchain . get_txpool_tx_meta ( id , meta ) )
{
MERROR ( " Failed to find tx in txpool" ) ;
MERROR ( " Failed to find tx _meta in txpool" ) ;
return false ;
}
txblob = m_blockchain . get_txpool_tx_blob ( id );
txblob = m_blockchain . get_txpool_tx_blob ( id , relay_category : : all );
auto ci = m_parsed_tx_cache . find ( id ) ;
if ( ci ! = m_parsed_tx_cache . end ( ) )
{
@ -533,7 +556,7 @@ namespace cryptonote
MERROR ( " Failed to find tx in txpool " ) ;
return false ;
}
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( txid );
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( txid , relay_category : : all );
auto ci = m_parsed_tx_cache . find ( txid ) ;
if ( ci ! = m_parsed_tx_cache . end ( ) )
{
@ -611,7 +634,7 @@ namespace cryptonote
remove . push_back ( std : : make_pair ( txid , meta . weight ) ) ;
}
return true ;
} , false );
} , false , relay_category : : all );
if ( ! remove . empty ( ) )
{
@ -621,7 +644,7 @@ namespace cryptonote
const crypto : : hash & txid = entry . first ;
try
{
cryptonote : : blobdata bd = m_blockchain . get_txpool_tx_blob ( txid );
cryptonote : : blobdata bd = m_blockchain . get_txpool_tx_blob ( txid , relay_category : : all );
cryptonote : : transaction_prefix tx ;
if ( ! parse_and_validate_tx_prefix_from_blob ( bd , tx ) )
{
@ -649,7 +672,7 @@ namespace cryptonote
}
//---------------------------------------------------------------------------------
//TODO: investigate whether boolean return is appropriate
bool tx_memory_pool : : get_relayable_transactions ( std : : vector < std : : pair < crypto : : hash , cryptonote : : blobdata > > & txs ) const
bool tx_memory_pool : : get_relayable_transactions ( std : : vector < std : : tuple < crypto : : hash , cryptonote : : blobdata , relay_method > > & txs ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
@ -667,8 +690,7 @@ namespace cryptonote
{
try
{
cryptonote : : blobdata bd = m_blockchain . get_txpool_tx_blob ( txid ) ;
txs . push_back ( std : : make_pair ( txid , bd ) ) ;
txs . emplace_back ( txid , m_blockchain . get_txpool_tx_blob ( txid , relay_category : : all ) , meta . get_relay_method ( ) ) ;
}
catch ( const std : : exception & e )
{
@ -678,26 +700,27 @@ namespace cryptonote
}
}
return true ;
} , false );
} , false , relay_category : : relayable );
return true ;
}
//---------------------------------------------------------------------------------
void tx_memory_pool : : set_relayed ( const std: : vector < std : : pair < crypto : : hash , cryptonote : : blobdata > > & txs )
void tx_memory_pool : : set_relayed ( const epee: : span < const crypto : : hash > hashes , const relay_method method )
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
const time_t now = time ( NULL ) ;
LockedTXN lock ( m_blockchain ) ;
for ( auto it = txs . begin ( ) ; it ! = txs . end ( ) ; + + it )
for ( const auto & hash : hashes )
{
try
{
txpool_tx_meta_t meta ;
if ( m_blockchain . get_txpool_tx_meta ( it- > first , meta ) )
if ( m_blockchain . get_txpool_tx_meta ( hash , meta ) )
{
meta . relayed = true ;
meta . last_relayed_time = now ;
m_blockchain . update_txpool_tx ( it - > first , meta ) ;
meta . set_relay_method ( method ) ;
m_blockchain . update_txpool_tx ( hash , meta ) ;
}
}
catch ( const std : : exception & e )
@ -709,18 +732,19 @@ namespace cryptonote
lock . commit ( ) ;
}
//---------------------------------------------------------------------------------
size_t tx_memory_pool : : get_transactions_count ( bool include_ unrelayed_txes ) const
size_t tx_memory_pool : : get_transactions_count ( bool include_ sensitive ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
return m_blockchain . get_txpool_tx_count ( include_ unrelayed_txes ) ;
return m_blockchain . get_txpool_tx_count ( include_ sensitive ) ;
}
//---------------------------------------------------------------------------------
void tx_memory_pool : : get_transactions ( std : : vector < transaction > & txs , bool include_ unrelayed_txes ) const
void tx_memory_pool : : get_transactions ( std : : vector < transaction > & txs , bool include_ sensitive ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
txs . reserve ( m_blockchain . get_txpool_tx_count ( include_unrelayed_txes ) ) ;
const relay_category category = include_sensitive ? relay_category : : all : relay_category : : broadcasted ;
txs . reserve ( m_blockchain . get_txpool_tx_count ( include_sensitive ) ) ;
m_blockchain . for_all_txpool_txes ( [ & txs ] ( const crypto : : hash & txid , const txpool_tx_meta_t & meta , const cryptonote : : blobdata * bd ) {
transaction tx ;
if ( ! ( meta . pruned ? parse_and_validate_tx_base_from_blob ( * bd , tx ) : parse_and_validate_tx_from_blob ( * bd , tx ) ) )
@ -732,39 +756,42 @@ namespace cryptonote
tx . set_hash ( txid ) ;
txs . push_back ( std : : move ( tx ) ) ;
return true ;
} , true , include_unrelayed_txes ) ;
} , true , category ) ;
}
//------------------------------------------------------------------
void tx_memory_pool : : get_transaction_hashes ( std : : vector < crypto : : hash > & txs , bool include_ unrelayed_txes ) const
void tx_memory_pool : : get_transaction_hashes ( std : : vector < crypto : : hash > & txs , bool include_ sensitive ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
txs . reserve ( m_blockchain . get_txpool_tx_count ( include_unrelayed_txes ) ) ;
const relay_category category = include_sensitive ? relay_category : : all : relay_category : : broadcasted ;
txs . reserve ( m_blockchain . get_txpool_tx_count ( include_sensitive ) ) ;
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 ) ;
} , false , category ) ;
}
//------------------------------------------------------------------
void tx_memory_pool : : get_transaction_backlog ( std : : vector < tx_backlog_entry > & backlog , bool include_ unrelayed_txes ) const
void tx_memory_pool : : get_transaction_backlog ( std : : vector < tx_backlog_entry > & backlog , bool include_ sensitive ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
const uint64_t now = time ( NULL ) ;
backlog . reserve ( m_blockchain . get_txpool_tx_count ( include_unrelayed_txes ) ) ;
const relay_category category = include_sensitive ? relay_category : : all : relay_category : : broadcasted ;
backlog . reserve ( m_blockchain . get_txpool_tx_count ( include_sensitive ) ) ;
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 . weight , meta . fee , meta . receive_time - now } ) ;
return true ;
} , false , include_unrelayed_txes ) ;
} , false , category ) ;
}
//------------------------------------------------------------------
void tx_memory_pool : : get_transaction_stats ( struct txpool_stats & stats , bool include_ unrelayed_txes ) const
void tx_memory_pool : : get_transaction_stats ( struct txpool_stats & stats , bool include_ sensitive ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
const uint64_t now = time ( NULL ) ;
const relay_category category = include_sensitive ? relay_category : : all : relay_category : : broadcasted ;
std : : map < uint64_t , txpool_histo > agebytes ;
stats . txs_total = m_blockchain . get_txpool_tx_count ( include_ unrelayed_txes ) ;
stats . txs_total = m_blockchain . get_txpool_tx_count ( include_ sensitive ) ;
std : : vector < uint32_t > weights ;
weights . reserve ( stats . txs_total ) ;
m_blockchain . for_all_txpool_txes ( [ & stats , & weights , now , & agebytes ] ( const crypto : : hash & txid , const txpool_tx_meta_t & meta , const cryptonote : : blobdata * bd ) {
@ -789,7 +816,8 @@ namespace cryptonote
if ( meta . double_spend_seen )
+ + stats . num_double_spends ;
return true ;
} , false , include_unrelayed_txes ) ;
} , false , category ) ;
stats . bytes_med = epee : : misc_utils : : median ( weights ) ;
if ( stats . txs_total > 1 )
{
@ -847,8 +875,10 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
tx_infos . reserve ( m_blockchain . get_txpool_tx_count ( ) ) ;
key_image_infos . reserve ( m_blockchain . get_txpool_tx_count ( ) ) ;
const relay_category category = include_sensitive_data ? relay_category : : all : relay_category : : broadcasted ;
const size_t count = m_blockchain . get_txpool_tx_count ( include_sensitive_data ) ;
tx_infos . reserve ( count ) ;
key_image_infos . reserve ( count ) ;
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 ) ;
@ -879,7 +909,7 @@ namespace cryptonote
txi . double_spend_seen = meta . double_spend_seen ;
tx_infos . push_back ( std : : move ( txi ) ) ;
return true ;
} , true , include_sensitive_data ) ;
} , true , category ) ;
txpool_tx_meta_t meta ;
for ( const key_images_container : : value_type & kee : m_spent_key_images ) {
@ -889,30 +919,13 @@ 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
{
if ( ! m_blockchain . get_txpool_tx_meta ( tx_id_hash , meta ) )
{
MERROR ( " Failed to get tx meta from txpool " ) ;
return false ;
}
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 ) ) ;
if ( m_blockchain . txpool_tx_matches_category ( tx_id_hash , category ) )
ki . txs_hashes . push_back ( epee : : string_tools : : pod_to_hex ( tx_id_hash ) ) ;
}
// 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) ;
key_image_infos . push_back ( std : : move ( ki ) ) ;
}
return true ;
}
@ -948,18 +961,19 @@ namespace cryptonote
txi . double_spend_seen = meta . double_spend_seen ;
tx_infos . push_back ( txi ) ;
return true ;
} , true , false ) ;
} , true , relay_category : : broadcasted ) ;
for ( const key_images_container : : value_type & kee : m_spent_key_images ) {
std : : vector < crypto : : hash > tx_hashes ;
const std : : unordered_set < crypto : : hash > & kei_image_set = kee . second ;
for ( const crypto : : hash & tx_id_hash : kei_image_set )
{
tx_hashes . push_back ( tx_id_hash ) ;
if ( m_blockchain . txpool_tx_matches_category ( tx_id_hash , relay_category : : broadcasted ) )
tx_hashes . push_back ( tx_id_hash ) ;
}
const crypto : : key_image & k_image = kee . first ;
key_image_infos [ k_image ] = std : : move ( tx_hashes ) ;
if ( ! tx_hashes . empty ( ) )
key_image_infos [ kee . first ] = std : : move ( tx_hashes ) ;
}
return true ;
}
@ -973,19 +987,26 @@ namespace cryptonote
for ( const auto & image : key_images )
{
spent . push_back ( m_spent_key_images . find ( image ) = = m_spent_key_images . end ( ) ? false : true ) ;
bool is_spent = false ;
const auto found = m_spent_key_images . find ( image ) ;
if ( found ! = m_spent_key_images . end ( ) )
{
for ( const crypto : : hash & tx_hash : found - > second )
is_spent | = m_blockchain . txpool_tx_matches_category ( tx_hash , relay_category : : broadcasted ) ;
}
spent . push_back ( is_spent ) ;
}
return true ;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool : : get_transaction ( const crypto : : hash & id , cryptonote : : blobdata & txblob ) const
bool tx_memory_pool : : get_transaction ( const crypto : : hash & id , cryptonote : : blobdata & txblob , relay_category tx_category ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
try
{
return m_blockchain . get_txpool_tx_blob ( id , txblob );
return m_blockchain . get_txpool_tx_blob ( id , txblob , tx_category );
}
catch ( const std : : exception & e )
{
@ -1009,11 +1030,11 @@ namespace cryptonote
return true ;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool : : have_tx ( const crypto : : hash & id ) const
bool tx_memory_pool : : have_tx ( const crypto : : hash & id , relay_category tx_category ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
CRITICAL_REGION_LOCAL1 ( m_blockchain ) ;
return m_blockchain . get_db ( ) . txpool_has_tx ( id );
return m_blockchain . get_db ( ) . txpool_has_tx ( id , tx_category );
}
//---------------------------------------------------------------------------------
bool tx_memory_pool : : have_tx_keyimges_as_spent ( const transaction & tx ) const
@ -1032,7 +1053,14 @@ namespace cryptonote
bool tx_memory_pool : : have_tx_keyimg_as_spent ( const crypto : : key_image & key_im ) const
{
CRITICAL_REGION_LOCAL ( m_transactions_lock ) ;
return m_spent_key_images . end ( ) ! = m_spent_key_images . find ( key_im ) ;
bool spent = false ;
const auto found = m_spent_key_images . find ( key_im ) ;
if ( found ! = m_spent_key_images . end ( ) )
{
for ( const crypto : : hash & tx_hash : found - > second )
spent | = m_blockchain . txpool_tx_matches_category ( tx_hash , relay_category : : broadcasted ) ;
}
return spent ;
}
//---------------------------------------------------------------------------------
void tx_memory_pool : : lock ( ) const
@ -1217,13 +1245,14 @@ namespace cryptonote
< < " weight: " < < meta . weight < < std : : endl
< < " fee: " < < print_money ( meta . fee ) < < std : : endl
< < " kept_by_block: " < < ( meta . kept_by_block ? ' T ' : ' F ' ) < < std : : endl
< < " is_local " < < ( meta . is_local ? ' T ' : ' F ' ) < < std : : endl
< < " double_spend_seen: " < < ( meta . double_spend_seen ? ' T ' : ' F ' ) < < std : : endl
< < " max_used_block_height: " < < meta . max_used_block_height < < std : : endl
< < " max_used_block_id: " < < meta . max_used_block_id < < std : : endl
< < " last_failed_height: " < < meta . last_failed_height < < std : : endl
< < " last_failed_id: " < < meta . last_failed_id < < std : : endl ;
return true ;
} , ! short_format );
} , ! short_format , relay_category : : all );
return ss . str ( ) ;
}
@ -1255,7 +1284,7 @@ namespace cryptonote
for ( ; sorted_it ! = m_txs_by_fee_and_receive_time . end ( ) ; + + sorted_it )
{
txpool_tx_meta_t meta ;
if ( ! m_blockchain . get_txpool_tx_meta ( sorted_it - > second , meta ) )
if ( ! m_blockchain . get_txpool_tx_meta ( sorted_it - > second , meta ) & & ! meta . matches ( relay_category : : legacy ) )
{
MERROR ( " failed to find tx meta " ) ;
continue ;
@ -1304,7 +1333,9 @@ namespace cryptonote
}
}
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( sorted_it - > second ) ;
// "local" and "stem" txes are filtered above
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( sorted_it - > second , relay_category : : all ) ;
cryptonote : : transaction tx ;
// Skip transactions that are not ready to be
@ -1379,7 +1410,7 @@ namespace cryptonote
remove . insert ( txid ) ;
}
return true ;
} , false );
} , false , relay_category : : all );
size_t n_removed = 0 ;
if ( ! remove . empty ( ) )
@ -1389,7 +1420,7 @@ namespace cryptonote
{
try
{
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( txid );
cryptonote : : blobdata txblob = m_blockchain . get_txpool_tx_blob ( txid , relay_category : : all );
cryptonote : : transaction tx ;
if ( ! parse_and_validate_tx_from_blob ( txblob , tx ) ) // remove pruned ones on startup, they're meant to be temporary
{
@ -1450,7 +1481,7 @@ namespace cryptonote
remove . push_back ( txid ) ;
return true ;
}
if ( ! insert_key_images ( tx , txid , meta . kept_by_block ) )
if ( ! insert_key_images ( tx , txid , meta . get_relay_method( ) ) )
{
MFATAL ( " Failed to insert key images from txpool tx " ) ;
return false ;
@ -1458,7 +1489,7 @@ namespace cryptonote
m_txs_by_fee_and_receive_time . emplace ( std : : pair < double , time_t > ( meta . fee / ( double ) meta . weight , meta . receive_time ) , txid ) ;
m_txpool_weight + = meta . weight ;
return true ;
} , true );
} , true , relay_category : : all );
if ( ! r )
return false ;
}