diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 1005bdf..cf84d8c 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -19,6 +19,7 @@ #include "block_cache.h" #include "pool_block.h" #include "p2p_server.h" +#include "side_chain.h" LOG_CATEGORY(BlockCache) diff --git a/src/pool_block.cpp b/src/pool_block.cpp index c05a717..5e190f0 100644 --- a/src/pool_block.cpp +++ b/src/pool_block.cpp @@ -115,6 +115,7 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b) m_broadcasted = b.m_broadcasted; m_wantBroadcast = b.m_wantBroadcast; m_precalculated = b.m_precalculated; + m_precalculatedShares = b.m_precalculatedShares; m_localTimestamp = seconds_since_epoch(); m_receivedTimestamp = b.m_receivedTimestamp; @@ -302,6 +303,8 @@ void PoolBlock::reset_offchain_data() m_wantBroadcast = false; m_precalculated = false; + m_precalculatedShares.clear(); + m_precalculatedShares.shrink_to_fit(); m_localTimestamp = seconds_since_epoch(); m_receivedTimestamp = 0; diff --git a/src/pool_block.h b/src/pool_block.h index a614a1b..25e88a6 100644 --- a/src/pool_block.h +++ b/src/pool_block.h @@ -32,6 +32,7 @@ static FORCEINLINE constexpr int pool_block_debug() { return POOL_BLOCK_DEBUG; } class RandomX_Hasher_Base; class SideChain; +struct MinerShare; /* * -------------------------------------------------- @@ -160,6 +161,7 @@ struct PoolBlock mutable bool m_wantBroadcast; bool m_precalculated; + std::vector m_precalculatedShares; uint64_t m_localTimestamp; uint64_t m_receivedTimestamp; diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 041ae20..f9499bd 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -1677,7 +1677,10 @@ void SideChain::verify(PoolBlock* block) } std::vector shares; - if (!get_shares(block, shares)) { + if (block->m_precalculated && !block->m_precalculatedShares.empty()) { + shares = std::move(block->m_precalculatedShares); + } + else if (!get_shares(block, shares)) { block->m_invalid = true; return; } @@ -2342,13 +2345,11 @@ void SideChain::launch_precalc(const PoolBlock* block) if (b->m_precalculated) { continue; } - std::vector shares; - if (get_shares(b, shares, nullptr, true)) { + if (get_shares(b, b->m_precalculatedShares, nullptr, true)) { b->m_precalculated = true; - PrecalcJob* job = new PrecalcJob{ b, std::move(shares) }; { MutexLock lock2(m_precalcJobsMutex); - m_precalcJobs.push_back(job); + m_precalcJobs.push_back(b); uv_cond_signal(&m_precalcJobsCond); } } @@ -2358,9 +2359,12 @@ void SideChain::launch_precalc(const PoolBlock* block) void SideChain::precalc_worker() { + std::vector> wallets; + wallets.reserve(m_chainWindowSize); + do { - PrecalcJob* job; - size_t num_inputs; + const PoolBlock* job; + { MutexLock lock(m_precalcJobsMutex); @@ -2381,32 +2385,25 @@ void SideChain::precalc_worker() // Filter out duplicate inputs for get_eph_public_key() uint8_t t[HASH_SIZE * 2 + sizeof(size_t)]; - memcpy(t, job->b->m_txkeySec.h, HASH_SIZE); + memcpy(t, job->m_txkeySec.h, HASH_SIZE); - const size_t n = job->shares.size(); - num_inputs = n; + const size_t n = job->m_precalculatedShares.size(); + wallets.clear(); for (size_t i = 0; i < n; ++i) { - memcpy(t + HASH_SIZE, job->shares[i].m_wallet->view_public_key().h, HASH_SIZE); + memcpy(t + HASH_SIZE, job->m_precalculatedShares[i].m_wallet->view_public_key().h, HASH_SIZE); memcpy(t + HASH_SIZE * 2, &i, sizeof(i)); - if (!m_uniquePrecalcInputs->insert(robin_hood::hash_bytes(t, array_size(t))).second) { - job->shares[i].m_wallet = nullptr; - --num_inputs; + if (m_uniquePrecalcInputs->insert(robin_hood::hash_bytes(t, array_size(t))).second) { + wallets.emplace_back(i, job->m_precalculatedShares[i].m_wallet); } } } - if (num_inputs) { - for (size_t i = 0, n = job->shares.size(); i < n; ++i) { - if (job->shares[i].m_wallet) { - hash eph_public_key; - uint8_t view_tag; - job->shares[i].m_wallet->get_eph_public_key(job->b->m_txkeySec, i, eph_public_key, view_tag); - } - } + for (const std::pair& w : wallets) { + hash eph_public_key; + uint8_t view_tag; + w.second->get_eph_public_key(job->m_txkeySec, w.first, eph_public_key, view_tag); } - - delete job; } while (true); } @@ -2420,9 +2417,6 @@ void SideChain::finish_precalc() { { MutexLock lock(m_precalcJobsMutex); - for (PrecalcJob* job : m_precalcJobs) { - delete job; - } m_precalcJobs.clear(); m_precalcJobs.shrink_to_fit(); uv_cond_broadcast(&m_precalcJobsCond); diff --git a/src/side_chain.h b/src/side_chain.h index 7f3bd45..27988e4 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -147,16 +147,10 @@ private: ChainMain m_watchBlock; hash m_watchBlockMerkleRoot; - struct PrecalcJob - { - const PoolBlock* b; - std::vector shares; - }; - uv_cond_t m_precalcJobsCond; uv_mutex_t m_precalcJobsMutex; - std::vector m_precalcJobs; + std::vector m_precalcJobs; std::vector m_precalcWorkers; unordered_set* m_uniquePrecalcInputs;