|
|
|
@ -217,12 +217,8 @@ public:
|
|
|
|
|
{
|
|
|
|
|
WriteLock lock(derivations_lock);
|
|
|
|
|
|
|
|
|
|
DerivationEntry& entry = derivations->emplace(index, DerivationEntry{ derivation, {} }).first->second;
|
|
|
|
|
|
|
|
|
|
const uint32_t k = static_cast<uint32_t>(output_index << 8) | view_tag;
|
|
|
|
|
if (std::find(entry.m_viewTags.begin(), entry.m_viewTags.end(), k) == entry.m_viewTags.end()) {
|
|
|
|
|
entry.m_viewTags.emplace_back(k);
|
|
|
|
|
}
|
|
|
|
|
DerivationEntry& entry = derivations->emplace(index, DerivationEntry{ derivation, { 0xFFFFFFFFUL, 0xFFFFFFFFUL }, {} }).first->second;
|
|
|
|
|
entry.add_view_tag(static_cast<uint32_t>(output_index << 8) | view_tag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
@ -308,16 +304,19 @@ public:
|
|
|
|
|
WriteLock lock(derivations_lock);
|
|
|
|
|
delete derivations;
|
|
|
|
|
derivations = new DerivationsMap();
|
|
|
|
|
derivations->reserve(5000);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
WriteLock lock(public_keys_lock);
|
|
|
|
|
delete public_keys;
|
|
|
|
|
public_keys = new PublicKeysMap();
|
|
|
|
|
public_keys->reserve(5000);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
WriteLock lock(tx_keys_lock);
|
|
|
|
|
delete tx_keys;
|
|
|
|
|
tx_keys = new TxKeysMap();
|
|
|
|
|
tx_keys->reserve(50);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -325,10 +324,24 @@ private:
|
|
|
|
|
struct DerivationEntry
|
|
|
|
|
{
|
|
|
|
|
hash m_derivation;
|
|
|
|
|
std::vector<uint32_t> m_viewTags;
|
|
|
|
|
uint32_t m_viewTags1[2] = { 0xFFFFFFFFUL, 0xFFFFFFFFUL };
|
|
|
|
|
std::vector<uint32_t> m_viewTags2;
|
|
|
|
|
|
|
|
|
|
bool find_view_tag(size_t output_index, uint8_t& view_tag) const {
|
|
|
|
|
for (uint32_t k : m_viewTags) {
|
|
|
|
|
FORCEINLINE bool find_view_tag(size_t output_index, uint8_t& view_tag) const
|
|
|
|
|
{
|
|
|
|
|
#define ITER(i) do { \
|
|
|
|
|
const uint32_t k = m_viewTags1[i]; \
|
|
|
|
|
if ((k >> 8) == output_index) { \
|
|
|
|
|
view_tag = static_cast<uint8_t>(k); \
|
|
|
|
|
return true; \
|
|
|
|
|
} \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
ITER(0);
|
|
|
|
|
ITER(1);
|
|
|
|
|
#undef ITER
|
|
|
|
|
|
|
|
|
|
for (const uint32_t k : m_viewTags2) {
|
|
|
|
|
if ((k >> 8) == output_index) {
|
|
|
|
|
view_tag = static_cast<uint8_t>(k);
|
|
|
|
|
return true;
|
|
|
|
@ -336,6 +349,28 @@ private:
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FORCEINLINE void add_view_tag(uint32_t k)
|
|
|
|
|
{
|
|
|
|
|
#define ITER(i) do { \
|
|
|
|
|
const uint32_t t = m_viewTags1[i]; \
|
|
|
|
|
if (t == 0xFFFFFFFFUL) { \
|
|
|
|
|
m_viewTags1[i] = k; \
|
|
|
|
|
return; \
|
|
|
|
|
} \
|
|
|
|
|
else if (t == k) { \
|
|
|
|
|
return; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
ITER(0);
|
|
|
|
|
ITER(1);
|
|
|
|
|
#undef ITER
|
|
|
|
|
|
|
|
|
|
if (std::find(m_viewTags2.begin(), m_viewTags2.end(), k) == m_viewTags2.end()) {
|
|
|
|
|
m_viewTags2.emplace_back(k);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef unordered_map<std::array<uint8_t, HASH_SIZE * 2>, DerivationEntry> DerivationsMap;
|
|
|
|
|