aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/tx_pool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core/tx_pool.cpp')
-rw-r--r--src/cryptonote_core/tx_pool.cpp79
1 files changed, 78 insertions, 1 deletions
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 24e5752ad..ce1bc1ad2 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -83,6 +83,7 @@ namespace cryptonote
txd_p.first->second.max_used_block_id = null_hash;
txd_p.first->second.max_used_block_height = 0;
txd_p.first->second.kept_by_block = kept_by_block;
+ txd_p.first->second.receive_time = time(nullptr);
tvc.m_verifivation_impossible = true;
tvc.m_added_to_pool = true;
}else
@@ -104,6 +105,7 @@ namespace cryptonote
txd_p.first->second.max_used_block_height = max_used_block_height;
txd_p.first->second.last_failed_height = 0;
txd_p.first->second.last_failed_id = null_hash;
+ txd_p.first->second.receive_time = time(nullptr);
tvc.m_added_to_pool = true;
if(txd_p.first->second.fee > 0)
@@ -178,6 +180,30 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------------------------
+ void tx_memory_pool::on_idle()
+ {
+ m_remove_stuck_tx_interval.do_call([this](){return remove_stuck_transactions();});
+ }
+ //---------------------------------------------------------------------------------
+ //proper tx_pool handling courtesy of CryptoZoidberg and Boolberry
+ bool tx_memory_pool::remove_stuck_transactions()
+ {
+ CRITICAL_REGION_LOCAL(m_transactions_lock);
+ for(auto it = m_transactions.begin(); it!= m_transactions.end();)
+ {
+ uint64_t tx_age = time(nullptr) - it->second.receive_time;
+
+ if((tx_age > CRYPTONOTE_MEMPOOL_TX_LIVETIME && !it->second.kept_by_block) ||
+ (tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) )
+ {
+ LOG_PRINT_L0("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age );
+ m_transactions.erase(it++);
+ }else
+ ++it;
+ }
+ return true;
+ }
+ //---------------------------------------------------------------------------------
size_t tx_memory_pool::get_transactions_count()
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
@@ -350,18 +376,69 @@ namespace cryptonote
//---------------------------------------------------------------------------------
bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee)
{
+ // Warning: This function takes already_generated_
+ // coins as an argument and appears to do nothing
+ // with it.
+
CRITICAL_REGION_LOCAL(m_transactions_lock);
total_size = 0;
fee = 0;
- size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
+ size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; // Max block size
std::unordered_set<crypto::key_image> k_images;
+
+ // Tx size limit as in wallet2.h
+ // tx_pool.cpp uses size_t for tx sizes, whereas
+ // wallet2.h uses uint64_t; just use size_t here
+ // for now
+ size_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
+
+ // Calculate size limit based on median too; useful
+ // for when we actually fix wallet2.h's maximum
+ // allowable tx size
+ //
+ // Can be removed when wallet2.h calculates max
+ // tx size based on the median too; just use
+ // upper_transaction_size_limit_median in all cases
+ size_t upper_transaction_size_limit_median = ((median_size * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
+ if (upper_transaction_size_limit_median > upper_transaction_size_limit)
+ upper_transaction_size_limit = upper_transaction_size_limit_median;
+
BOOST_FOREACH(transactions_container::value_type& tx, m_transactions)
{
+ // Can not exceed maximum block size
if (max_total_size < total_size + tx.second.blob_size)
continue;
+ // Check to see if the minimum fee is included;
+ // exclude tx missing minimum fee
+ if (tx.second.fee < DEFAULT_FEE)
+ continue;
+
+ // Skip transactions that are too large
+ // TODO: Correct upper_transactions_size_limit
+ // such that it is based on median block size;
+ // We need to make a similar patch for
+ // wallet2.h
+ if (tx.second.blob_size > upper_transaction_size_limit)
+ continue;
+
+ // If adding this tx will make the block size
+ // greater than 130% of the median, reject the
+ // tx; this will keep down largely punitive tx
+ // from being included
+ if ( (total_size + tx.second.blob_size) > ((130 * median_size) / 100) )
+ continue;
+
+ // If we've exceeded the penalty free size,
+ // stop including more tx
+ if (total_size > median_size)
+ break;
+
+ // Skip transactions that are not ready to be
+ // included into the blockchain or that are
+ // missing key images
if (!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx))
continue;