From 2a3cd13b197ce0fb82c879bda2b068f95129b20b Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 1 Oct 2021 15:21:32 +0200 Subject: [PATCH] P2PServer: delete old cached blocks after initial sync Saves ~20 MB of memory --- src/crypto.cpp | 23 +++++++++++++++++++---- src/crypto.h | 3 +++ src/main.cpp | 5 +++++ src/p2p_server.cpp | 17 ++++++++++++----- src/p2p_server.h | 1 + src/side_chain.cpp | 4 ++++ tests/src/crypto_tests.cpp | 4 ++++ 7 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/crypto.cpp b/src/crypto.cpp index 8397152..4b2806d 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -241,21 +241,36 @@ private: std::unordered_map, hash> public_keys; }; -static Cache cache; +static Cache* cache = nullptr; bool generate_key_derivation(const hash& key1, const hash& key2, hash& derivation) { - return cache.get_derivation(key1, key2, derivation); + return cache->get_derivation(key1, key2, derivation); } bool derive_public_key(const hash& derivation, size_t output_index, const hash& base, hash& derived_key) { - return cache.get_public_key(derivation, output_index, base, derived_key); + return cache->get_public_key(derivation, output_index, base, derived_key); +} + +void init_crypto_cache() +{ + if (!cache) { + cache = new Cache(); + } +} + +void destroy_crypto_cache() +{ + if (cache) { + delete cache; + cache = nullptr; + } } void clear_crypto_cache() { - cache.clear(); + cache->clear(); } } // namespace p2pool diff --git a/src/crypto.h b/src/crypto.h index 6ac7574..9a4fe54 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -23,6 +23,9 @@ void generate_keys(hash& pub, hash& sec); bool check_keys(const hash& pub, const hash& sec); bool generate_key_derivation(const hash& key1, const hash& key2, hash& derivation); bool derive_public_key(const hash& derivation, size_t output_index, const hash& base, hash& derived_key); + +void init_crypto_cache(); +void destroy_crypto_cache(); void clear_crypto_cache(); } // namespace p2pool diff --git a/src/main.cpp b/src/main.cpp index 69ea41f..801442e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ */ #include "common.h" +#include "crypto.h" #include "p2pool.h" #include "stratum_server.h" #include "p2p_server.h" @@ -68,10 +69,14 @@ int main(int argc, char* argv[]) int result; memory_tracking_start(); + + p2pool::init_crypto_cache(); { p2pool::p2pool pool(argc, argv); result = pool.run(); } + p2pool::destroy_crypto_cache(); + memory_tracking_stop(); return result; diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index 19e4f2c..2871357 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -102,14 +102,11 @@ P2PServer::~P2PServer() uv_mutex_destroy(&m_peerListLock); uv_mutex_destroy(&m_broadcastLock); uv_mutex_destroy(&m_missingBlockRequestsLock); + + clear_cached_blocks(); uv_rwlock_destroy(&m_cachedBlocksLock); delete m_block; - - for (auto it : m_cachedBlocks) { - delete it.second; - } - delete m_cache; } @@ -124,6 +121,16 @@ void P2PServer::add_cached_block(const PoolBlock& block) m_cachedBlocks.insert({ new_block->m_sidechainId, new_block }); } +void P2PServer::clear_cached_blocks() +{ + WriteLock lock(m_cachedBlocksLock); + + for (auto it : m_cachedBlocks) { + delete it.second; + } + m_cachedBlocks.clear(); +} + void P2PServer::store_in_cache(const PoolBlock& block) { if (m_cache && block.m_verified && !block.m_invalid) { diff --git a/src/p2p_server.h b/src/p2p_server.h index 0ef5482..2461216 100644 --- a/src/p2p_server.h +++ b/src/p2p_server.h @@ -49,6 +49,7 @@ public: ~P2PServer(); void add_cached_block(const PoolBlock& block); + void clear_cached_blocks(); void store_in_cache(const PoolBlock& block); void connect_to_peers(const std::string& peer_list); diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 5f24022..3a406cb 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -1552,6 +1552,10 @@ void SideChain::prune_old_blocks() if (num_blocks_pruned) { LOGINFO(4, "pruned " << num_blocks_pruned << " old blocks at heights <= " << h); + + // If side-chain started pruning blocks it means the initial sync is complete + // It's now safe to delete cached blocks + m_pool->p2p_server()->clear_cached_blocks(); } } diff --git a/tests/src/crypto_tests.cpp b/tests/src/crypto_tests.cpp index fd1e1a7..ff254ab 100644 --- a/tests/src/crypto_tests.cpp +++ b/tests/src/crypto_tests.cpp @@ -25,6 +25,8 @@ namespace p2pool { TEST(crypto, derivation) { + init_crypto_cache(); + // Run the tests twice to check how crypto cache works for (int i = 0; i < 2; ++i) { std::ifstream f("crypto_tests.txt"); @@ -61,6 +63,8 @@ TEST(crypto, derivation) } } while (!f.eof()); } + + destroy_crypto_cache(); } }