Skip to content

Commit 7c9e97a

Browse files
authored
Merge pull request #539 from blondfrogs/new_lru_cache
Added new and fix crash
2 parents 1131eff + 8a8b1ff commit 7c9e97a

File tree

6 files changed

+75
-24
lines changed

6 files changed

+75
-24
lines changed

src/consensus/tx_verify.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <libzerocoin/CoinSpend.h>
2626
#include <veil/zerocoin/zchain.h>
2727
#include <primitives/zerocoin.h>
28+
#include <veil/zerocoin/lrucache.h>
2829

2930
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
3031
{
@@ -234,7 +235,9 @@ bool CheckZerocoinSpend(const CTransaction& tx, CValidationState& state)
234235
return fValidated;
235236
}
236237

237-
std::set<uint256> setValidatedPubcoin;
238+
// Create a lru cache to hold the currently validated pubcoins with a max size of 5000
239+
LRUCacheTemplate<std::string,bool> cacheValidatedPubcoin(5000);
240+
238241
bool CheckZerocoinMint(const CTxOut& txout, CBigNum& bnValue, CValidationState& state, bool fSkipZerocoinMintIsPrime)
239242
{
240243
libzerocoin::PublicCoin pubCoin(Params().Zerocoin_Params());
@@ -244,12 +247,12 @@ bool CheckZerocoinMint(const CTxOut& txout, CBigNum& bnValue, CValidationState&
244247
bnValue = pubCoin.getValue();
245248
uint256 hashPubcoin = GetPubCoinHash(bnValue);
246249

247-
if (!fSkipZerocoinMintIsPrime && ! setValidatedPubcoin.count(hashPubcoin)) {
250+
bool value;
251+
if (!fSkipZerocoinMintIsPrime && !cacheValidatedPubcoin.get(hashPubcoin.GetHex(), value)) {
248252
if (!pubCoin.validate())
249253
return state.DoS(100, error("CheckZerocoinMint() : PubCoin does not validate"));
250-
while (setValidatedPubcoin.size() > 5000)
251-
setValidatedPubcoin.erase(setValidatedPubcoin.begin());
252-
setValidatedPubcoin.emplace(hashPubcoin);
254+
255+
cacheValidatedPubcoin.set(hashPubcoin.GetHex(), true);
253256
}
254257

255258
return true;

src/veil/zerocoin/lrucache.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44

55
#include "lrucache.h"
66

7-
LRUCache::LRUCache()
7+
PrecomputeLRUCache::PrecomputeLRUCache()
88
{
99
Clear();
1010
}
1111

12-
void LRUCache::Clear()
12+
void PrecomputeLRUCache::Clear()
1313
{
1414
cache_list.clear();
1515
mapCacheLocation.clear();
1616
mapDirtyWitnessData.clear();
1717
}
1818

19-
void LRUCache::AddNew(const uint256& hash, CoinWitnessCacheData& data)
19+
void PrecomputeLRUCache::AddNew(const uint256& hash, CoinWitnessCacheData& data)
2020
{
2121
cache_list.push_front(std::make_pair(hash, data));
2222
mapCacheLocation.insert(make_pair(hash, cache_list.begin()));
@@ -25,29 +25,29 @@ void LRUCache::AddNew(const uint256& hash, CoinWitnessCacheData& data)
2525
mapDirtyWitnessData.erase(hash);
2626
}
2727

28-
int LRUCache::Size() const
28+
int PrecomputeLRUCache::Size() const
2929
{
3030
return mapCacheLocation.size();
3131
}
3232

33-
int LRUCache::DirtyCacheSize() const
33+
int PrecomputeLRUCache::DirtyCacheSize() const
3434
{
3535
return mapDirtyWitnessData.size();
3636
}
3737

38-
bool LRUCache::Contains(const uint256& hash) const
38+
bool PrecomputeLRUCache::Contains(const uint256& hash) const
3939
{
4040
return mapCacheLocation.count(hash) > 0 || mapDirtyWitnessData.count(hash) > 0;
4141
}
4242

43-
void LRUCache::MoveDirtyToLRU(const uint256& hash)
43+
void PrecomputeLRUCache::MoveDirtyToLRU(const uint256& hash)
4444
{
4545
auto data = CoinWitnessData(mapDirtyWitnessData.at(hash));
4646
auto cachedata = CoinWitnessCacheData(&data);
4747
AddNew(hash, cachedata);
4848
}
4949

50-
void LRUCache::MoveLastToDirtyIfFull()
50+
void PrecomputeLRUCache::MoveLastToDirtyIfFull()
5151
{
5252
if (mapCacheLocation.size() > PRECOMPUTE_LRU_CACHE_SIZE) {
5353
auto last_it = cache_list.end(); last_it --;
@@ -58,7 +58,7 @@ void LRUCache::MoveLastToDirtyIfFull()
5858
}
5959
}
6060

61-
CoinWitnessData LRUCache::GetWitnessData(const uint256& hash)
61+
CoinWitnessData PrecomputeLRUCache::GetWitnessData(const uint256& hash)
6262
{
6363
if (mapDirtyWitnessData.count(hash)) {
6464
MoveDirtyToLRU(hash);
@@ -74,7 +74,7 @@ CoinWitnessData LRUCache::GetWitnessData(const uint256& hash)
7474
return CoinWitnessData();
7575
}
7676

77-
void LRUCache::Remove(const uint256& hash)
77+
void PrecomputeLRUCache::Remove(const uint256& hash)
7878
{
7979
auto it = mapCacheLocation.find(hash);
8080
if (it != mapCacheLocation.end()) {
@@ -84,7 +84,7 @@ void LRUCache::Remove(const uint256& hash)
8484
mapDirtyWitnessData.erase(hash);
8585
}
8686

87-
void LRUCache::AddToCache(const uint256& hash, CoinWitnessCacheData& serialData)
87+
void PrecomputeLRUCache::AddToCache(const uint256& hash, CoinWitnessCacheData& serialData)
8888
{
8989
// If the LRU cache already has a entry for it, update the entry and move it to the front of the list
9090
auto it = mapCacheLocation.find(hash);
@@ -100,7 +100,7 @@ void LRUCache::AddToCache(const uint256& hash, CoinWitnessCacheData& serialData)
100100
MoveLastToDirtyIfFull();
101101
}
102102

103-
void LRUCache::FlushToDisk(CPrecomputeDB* pprecomputeDB)
103+
void PrecomputeLRUCache::FlushToDisk(CPrecomputeDB* pprecomputeDB)
104104
{
105105
// Save all cache data that was dirty back into the database
106106
for (auto item : mapDirtyWitnessData) {

src/veil/zerocoin/lrucache.h

+51-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#define VEIL_LRUCACHE_H
88

99
#include <veil/zerocoin/witness.h>
10+
#include <unordered_map>
11+
#include <list>
1012

11-
class LRUCache
13+
class PrecomputeLRUCache
1214
{
1315
private:
1416
std::list<std::pair<uint256, CoinWitnessCacheData> > cache_list;
@@ -22,12 +24,58 @@ class LRUCache
2224
void Clear();
2325
void FlushToDisk(CPrecomputeDB* pprecomputeDB);
2426
CoinWitnessData GetWitnessData(const uint256& hash);
25-
LRUCache();
27+
PrecomputeLRUCache();
2628
void MoveDirtyToLRU(const uint256& hash);
2729
void MoveLastToDirtyIfFull();
2830
void Remove(const uint256& hash);
2931
int Size() const;
3032
int DirtyCacheSize() const;
3133
};
3234

33-
#endif //VEIL_LRUCACHE_H
35+
36+
37+
template<typename K, typename V = K>
38+
class LRUCacheTemplate
39+
{
40+
41+
private:
42+
std::list<K>items;
43+
std::unordered_map <K, std::pair<V, typename std::list<K>::iterator>> keyValuesMap;
44+
int csize;
45+
46+
public:
47+
LRUCacheTemplate(int s) :csize(s) {
48+
if (csize < 1)
49+
csize = 10;
50+
}
51+
52+
void set(const K key, const V value) {
53+
auto pos = keyValuesMap.find(key);
54+
if (pos == keyValuesMap.end()) {
55+
items.push_front(key);
56+
keyValuesMap[key] = { value, items.begin() };
57+
if (keyValuesMap.size() > csize) {
58+
keyValuesMap.erase(items.back());
59+
items.pop_back();
60+
}
61+
}
62+
else {
63+
items.erase(pos->second.second);
64+
items.push_front(key);
65+
keyValuesMap[key] = { value, items.begin() };
66+
}
67+
}
68+
69+
bool get(const K key, V &value) {
70+
auto pos = keyValuesMap.find(key);
71+
if (pos == keyValuesMap.end())
72+
return false;
73+
items.erase(pos->second.second);
74+
items.push_front(key);
75+
keyValuesMap[key] = { pos->second.first, items.begin() };
76+
value = pos->second.first;
77+
return true;
78+
}
79+
};
80+
81+
#endif //VEIL_LRUCACHE_H

src/veil/zerocoin/precompute.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Precompute
2020

2121
public:
2222

23-
LRUCache lru;
23+
PrecomputeLRUCache lru;
2424

2525
Precompute();
2626
void SetNull();

src/veil/zerocoin/witness.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ CPrecomputeDB::CPrecomputeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBW
144144
{
145145
}
146146

147-
bool CPrecomputeDB::LoadPrecomputes(LRUCache* lru)
147+
bool CPrecomputeDB::LoadPrecomputes(PrecomputeLRUCache* lru)
148148
{
149149

150150
std::unique_ptr<CDBIterator> pcursor(NewIterator());

src/veil/zerocoin/witness.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#define PRECOMPUTE_FLUSH_TIME 3600 // 1 Hour
1414

1515
class CoinWitnessCacheData;
16-
class LRUCache;
16+
class PrecomputeLRUCache;
1717

1818
class CoinWitnessData
1919
{
@@ -90,7 +90,7 @@ class CPrecomputeDB : public CDBWrapper
9090

9191
public:
9292
/** Veil zerocoin precompute database functions */
93-
bool LoadPrecomputes(LRUCache* lru);
93+
bool LoadPrecomputes(PrecomputeLRUCache* lru);
9494
bool LoadPrecomputes(std::set<uint256> setHashes);
9595
bool EraseAllPrecomputes();
9696
bool WritePrecompute(const uint256& hash, const CoinWitnessCacheData& data);

0 commit comments

Comments
 (0)