From 20dd9d7adc0e4d4076be33a73dcea76e1b03f0ff Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 11 Jul 2022 16:42:26 +0200 Subject: [PATCH] More efficient view tags caching --- src/crypto.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/crypto.cpp b/src/crypto.cpp index 9e6c9ce..78f21a6 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -169,17 +169,16 @@ public: bool get_derivation(const hash& key1, const hash& key2, size_t output_index, hash& derivation, uint8_t& view_tag) { - std::array index; + std::array index; memcpy(index.data(), key1.h, HASH_SIZE); memcpy(index.data() + HASH_SIZE, key2.h, HASH_SIZE); - memcpy(index.data() + HASH_SIZE * 2, &output_index, sizeof(size_t)); { MutexLock lock(m); auto it = derivations.find(index); if (it != derivations.end()) { - derivation = it->second.derivation; - view_tag = it->second.view_tag; + derivation = it->second.m_derivation; + view_tag = it->second.get_view_tag(output_index); return true; } } @@ -197,11 +196,10 @@ public: ge_p1p1_to_p2(&point2, &point3); ge_tobytes(reinterpret_cast(&derivation), &point2); - derive_view_tag(derivation, output_index, view_tag); - { MutexLock lock(m); - derivations.emplace(index, DerivationEntry{ derivation, view_tag } ); + auto result = derivations.emplace(index, DerivationEntry{ derivation, {} }); + view_tag = result.first->second.get_view_tag(output_index); } return true; @@ -293,13 +291,25 @@ public: private: struct DerivationEntry { - hash derivation; - // cppcheck-suppress unusedStructMember - uint8_t view_tag; + hash m_derivation; + std::vector m_viewTags; + + uint8_t get_view_tag(size_t output_index) { + auto it = std::find_if(m_viewTags.begin(), m_viewTags.end(), [output_index](uint32_t k) { return (k >> 8) == output_index; }); + if (it != m_viewTags.end()) { + return static_cast(*it); + } + + uint8_t t; + derive_view_tag(m_derivation, output_index, t); + m_viewTags.emplace_back(static_cast(output_index << 8) | t); + + return t; + } }; uv_mutex_t m; - unordered_map, DerivationEntry> derivations; + unordered_map, DerivationEntry> derivations; unordered_map, hash> public_keys; unordered_map, std::pair> tx_keys; };