diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index 1016f92..5792e17 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -47,6 +47,7 @@ P2PServer::P2PServer(p2pool* pool) , m_cache(pool->params().m_blockCache ? new BlockCache() : nullptr) , m_cacheLoaded(false) , m_initialPeerList(pool->params().m_p2pPeerList) + , m_cachedBlocks(nullptr) , m_rng(RandomDeviceSeed::instance) , m_block(new PoolBlock()) , m_timer{} @@ -128,18 +129,34 @@ void P2PServer::add_cached_block(const PoolBlock& block) return; } - PoolBlock* new_block = new PoolBlock(block); - m_cachedBlocks.insert({ new_block->m_sidechainId, new_block }); + if (!m_cachedBlocks) { + m_cachedBlocks = new unordered_map(); + } + + if (m_cachedBlocks->find(block.m_sidechainId) == m_cachedBlocks->end()) { + PoolBlock* new_block = new PoolBlock(block); + m_cachedBlocks->insert({ new_block->m_sidechainId, new_block }); + } } void P2PServer::clear_cached_blocks() { + if (!m_cachedBlocks) { + return; + } + WriteLock lock(m_cachedBlocksLock); - for (auto it : m_cachedBlocks) { + if (!m_cachedBlocks) { + return; + } + + for (auto it : *m_cachedBlocks) { delete it.second; } - m_cachedBlocks.clear(); + + delete m_cachedBlocks; + m_cachedBlocks = nullptr; } void P2PServer::store_in_cache(const PoolBlock& block) @@ -934,12 +951,14 @@ void P2PServer::download_missing_blocks() return; } + ReadLock lock2(m_cachedBlocksLock); + // Try to download each block from a random client for (const hash& id : missing_blocks) { P2PClient* client = clients[get_random64() % clients.size()]; { - MutexLock lock2(m_missingBlockRequestsLock); + MutexLock lock3(m_missingBlockRequestsLock); const uint64_t truncated_block_id = *reinterpret_cast(id.h); if (!m_missingBlockRequests.insert({ client->m_peerId, truncated_block_id }).second) { @@ -949,6 +968,15 @@ void P2PServer::download_missing_blocks() } } + if (m_cachedBlocks) { + auto it = m_cachedBlocks->find(id); + if (it != m_cachedBlocks->end()) { + LOGINFO(5, "using cached block for id = " << id); + client->handle_incoming_block_async(it->second); + continue; + } + } + const bool result = send(client, [&id](void* buf) { @@ -1944,11 +1972,13 @@ void P2PServer::P2PClient::post_handle_incoming_block(const uint32_t reset_count ReadLock lock(server->m_cachedBlocksLock); for (const hash& id : missing_blocks) { - auto it = server->m_cachedBlocks.find(id); - if (it != server->m_cachedBlocks.end()) { - LOGINFO(5, "using cached block for id = " << id); - handle_incoming_block_async(it->second); - continue; + if (server->m_cachedBlocks) { + auto it = server->m_cachedBlocks->find(id); + if (it != server->m_cachedBlocks->end()) { + LOGINFO(5, "using cached block for id = " << id); + handle_incoming_block_async(it->second); + continue; + } } const bool result = m_owner->send(this, diff --git a/src/p2p_server.h b/src/p2p_server.h index c13f235..a9a85dd 100644 --- a/src/p2p_server.h +++ b/src/p2p_server.h @@ -149,7 +149,7 @@ private: uint32_t m_maxIncomingPeers; uv_rwlock_t m_cachedBlocksLock; - unordered_map m_cachedBlocks; + unordered_map* m_cachedBlocks; private: static void on_timer(uv_timer_t* timer) { reinterpret_cast(timer->data)->on_timer(); }