aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2022-08-08 20:29:56 -0500
committerluigi1111 <luigi1111w@gmail.com>2022-08-08 20:29:56 -0500
commit5c33f40cd8b75ad6f486fa1738df1f3462ca1ac1 (patch)
treedf124190c4928356412d23382a36ee813d986dda
parentMerge pull request #8483 (diff)
parentFixed get_block_template_backlog performance (diff)
downloadmonero-5c33f40cd8b75ad6f486fa1738df1f3462ca1ac1.tar.xz
Merge pull request #8455
099fc1f Fixed get_block_template_backlog performance (SChernykh)
-rw-r--r--src/cryptonote_core/tx_pool.cpp67
-rw-r--r--src/cryptonote_core/tx_pool.h6
2 files changed, 56 insertions, 17 deletions
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 0c18b2a34..be81d39f1 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -925,26 +925,61 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
- const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted;
- backlog.reserve(m_blockchain.get_txpool_tx_count(include_sensitive));
- txpool_tx_meta_t tmp_meta;
- m_blockchain.for_all_txpool_txes([this, &backlog, &tmp_meta](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
- transaction tx;
- if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, tx) : parse_and_validate_tx_from_blob(*bd, tx)))
+
+ std::vector<tx_block_template_backlog_entry> tmp;
+ uint64_t total_weight = 0;
+
+ // First get everything from the mempool, filter it later
+ m_blockchain.for_all_txpool_txes([&tmp, &total_weight](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*){
+ tmp.emplace_back(tx_block_template_backlog_entry{txid, meta.weight, meta.fee});
+ total_weight += meta.weight;
+ return true;
+ }, false, include_sensitive ? relay_category::all : relay_category::broadcasted);
+
+ // Limit backlog to 112.5% of current median weight. This is enough to mine a full block with the optimal block reward
+ const uint64_t median_weight = m_blockchain.get_current_cumulative_block_weight_median();
+ const uint64_t max_backlog_weight = median_weight + (median_weight / 8);
+
+ // If the total weight is too high, choose the best paying transactions
+ if (total_weight > max_backlog_weight)
+ std::sort(tmp.begin(), tmp.end(), [](const auto& a, const auto& b){ return a.fee * b.weight > b.fee * a.weight; });
+
+ backlog.clear();
+ uint64_t w = 0;
+
+ std::unordered_set<crypto::key_image> k_images;
+
+ for (const tx_block_template_backlog_entry& e : tmp)
+ {
+ try
{
- MERROR("Failed to parse tx from txpool");
- // continue
- return true;
- }
- tx.set_hash(txid);
+ txpool_tx_meta_t meta;
+ if (!m_blockchain.get_txpool_tx_meta(e.id, meta))
+ continue;
- tmp_meta = meta;
+ cryptonote::blobdata txblob;
+ if (!m_blockchain.get_txpool_tx_blob(e.id, txblob, relay_category::all))
+ continue;
- if (is_transaction_ready_to_go(tmp_meta, txid, *bd, tx))
- backlog.push_back({txid, meta.weight, meta.fee});
+ cryptonote::transaction tx;
+ if (is_transaction_ready_to_go(meta, e.id, txblob, tx))
+ {
+ if (have_key_images(k_images, tx))
+ continue;
+ append_key_images(k_images, tx);
- return true;
- }, true, category);
+ backlog.push_back(e);
+ w += e.weight;
+ if (w > max_backlog_weight)
+ break;
+ }
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to check transaction readiness: " << e.what());
+ // continue, not fatal
+ }
+ }
}
//------------------------------------------------------------------
void tx_memory_pool::get_transaction_stats(struct txpool_stats& stats, bool include_sensitive) const
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 65c39f87c..accd8c863 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -266,7 +266,11 @@ namespace cryptonote
void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive = false) const;
/**
- * @brief get (hash, weight, fee) for all transactions in the pool - the minimum required information to create a block template
+ * @brief get (hash, weight, fee) for transactions in the pool - the minimum required information to create a block template
+ *
+ * Not all transactions in the pool will be returned for performance reasons
+ * If there are too many transactions in the pool, only the highest-paying transactions
+ * will be returned - but enough for the miner to create a full block
*
* @param backlog return-by-reference that data
* @param include_sensitive return stempool, anonymity-pool, and unrelayed txes