From 29d84e3bcf92e42e51971b5c0f7061bb2fabf76c Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:48:49 +0100 Subject: [PATCH] Fixed data race in tx mempool --- src/block_template.cpp | 20 ++++++++------------ src/mempool.h | 18 +++++++++++++++++- src/p2pool.cpp | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/block_template.cpp b/src/block_template.cpp index 235fb7e..0fb0848 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -322,22 +322,18 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const } // Only choose transactions that were received 5 or more seconds ago, or high fee (>= 0.006 XMR) transactions - size_t total_mempool_transactions; - { - m_mempoolTxs.clear(); + m_mempoolTxs.clear(); - ReadLock mempool_lock(mempool.m_lock); + const uint64_t cur_time = seconds_since_epoch(); + size_t total_mempool_transactions = 0; - total_mempool_transactions = mempool.m_transactions.size(); + mempool.iterate([this, cur_time, &total_mempool_transactions](const hash&, const TxMempoolData& tx) { + ++total_mempool_transactions; - const uint64_t cur_time = seconds_since_epoch(); - - for (auto& it : mempool.m_transactions) { - if ((cur_time > it.second.time_received + 5) || (it.second.fee >= HIGH_FEE_VALUE)) { - m_mempoolTxs.emplace_back(it.second); - } + if ((cur_time > tx.time_received + 5) || (tx.fee >= HIGH_FEE_VALUE)) { + m_mempoolTxs.emplace_back(tx); } - } + }); // Safeguard for busy mempool moments // If the block template gets too big, nodes won't be able to send and receive it because of p2p packet size limit diff --git a/src/mempool.h b/src/mempool.h index 212f4b8..c71ea01 100644 --- a/src/mempool.h +++ b/src/mempool.h @@ -34,7 +34,23 @@ public: void add(const TxMempoolData& tx); void swap(std::vector& transactions); -public: + size_t size() const + { + ReadLock lock(m_lock); + return m_transactions.size(); + } + + template + void iterate(T&& callback) const + { + ReadLock lock(m_lock); + + for (const auto& it : m_transactions) { + callback(it.first, it.second); + } + } + +private: mutable uv_rwlock_t m_lock; unordered_map m_transactions; }; diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 9ed851b..9084592 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -361,7 +361,7 @@ void p2pool::handle_miner_data(MinerData& data) "\ndifficulty = " << data.difficulty << "\nmedian_weight = " << data.median_weight << "\nalready_generated_coins = " << data.already_generated_coins << - "\ntransactions = " << m_mempool->m_transactions.size() << + "\ntransactions = " << m_mempool->size() << "\n---------------------------------------------------------------------------------------------------------------" );