Skip to content

Commit

Permalink
Merge pull request Veil-Project#539 from blondfrogs/new_lru_cache
Browse files Browse the repository at this point in the history
Added new and fix crash
  • Loading branch information
blondfrogs authored Apr 27, 2019
2 parents 1131eff + 8a8b1ff commit 7c9e97a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 24 deletions.
13 changes: 8 additions & 5 deletions src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <libzerocoin/CoinSpend.h>
#include <veil/zerocoin/zchain.h>
#include <primitives/zerocoin.h>
#include <veil/zerocoin/lrucache.h>

bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
{
Expand Down Expand Up @@ -234,7 +235,9 @@ bool CheckZerocoinSpend(const CTransaction& tx, CValidationState& state)
return fValidated;
}

std::set<uint256> setValidatedPubcoin;
// Create a lru cache to hold the currently validated pubcoins with a max size of 5000
LRUCacheTemplate<std::string,bool> cacheValidatedPubcoin(5000);

bool CheckZerocoinMint(const CTxOut& txout, CBigNum& bnValue, CValidationState& state, bool fSkipZerocoinMintIsPrime)
{
libzerocoin::PublicCoin pubCoin(Params().Zerocoin_Params());
Expand All @@ -244,12 +247,12 @@ bool CheckZerocoinMint(const CTxOut& txout, CBigNum& bnValue, CValidationState&
bnValue = pubCoin.getValue();
uint256 hashPubcoin = GetPubCoinHash(bnValue);

if (!fSkipZerocoinMintIsPrime && ! setValidatedPubcoin.count(hashPubcoin)) {
bool value;
if (!fSkipZerocoinMintIsPrime && !cacheValidatedPubcoin.get(hashPubcoin.GetHex(), value)) {
if (!pubCoin.validate())
return state.DoS(100, error("CheckZerocoinMint() : PubCoin does not validate"));
while (setValidatedPubcoin.size() > 5000)
setValidatedPubcoin.erase(setValidatedPubcoin.begin());
setValidatedPubcoin.emplace(hashPubcoin);

cacheValidatedPubcoin.set(hashPubcoin.GetHex(), true);
}

return true;
Expand Down
24 changes: 12 additions & 12 deletions src/veil/zerocoin/lrucache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

#include "lrucache.h"

LRUCache::LRUCache()
PrecomputeLRUCache::PrecomputeLRUCache()
{
Clear();
}

void LRUCache::Clear()
void PrecomputeLRUCache::Clear()
{
cache_list.clear();
mapCacheLocation.clear();
mapDirtyWitnessData.clear();
}

void LRUCache::AddNew(const uint256& hash, CoinWitnessCacheData& data)
void PrecomputeLRUCache::AddNew(const uint256& hash, CoinWitnessCacheData& data)
{
cache_list.push_front(std::make_pair(hash, data));
mapCacheLocation.insert(make_pair(hash, cache_list.begin()));
Expand All @@ -25,29 +25,29 @@ void LRUCache::AddNew(const uint256& hash, CoinWitnessCacheData& data)
mapDirtyWitnessData.erase(hash);
}

int LRUCache::Size() const
int PrecomputeLRUCache::Size() const
{
return mapCacheLocation.size();
}

int LRUCache::DirtyCacheSize() const
int PrecomputeLRUCache::DirtyCacheSize() const
{
return mapDirtyWitnessData.size();
}

bool LRUCache::Contains(const uint256& hash) const
bool PrecomputeLRUCache::Contains(const uint256& hash) const
{
return mapCacheLocation.count(hash) > 0 || mapDirtyWitnessData.count(hash) > 0;
}

void LRUCache::MoveDirtyToLRU(const uint256& hash)
void PrecomputeLRUCache::MoveDirtyToLRU(const uint256& hash)
{
auto data = CoinWitnessData(mapDirtyWitnessData.at(hash));
auto cachedata = CoinWitnessCacheData(&data);
AddNew(hash, cachedata);
}

void LRUCache::MoveLastToDirtyIfFull()
void PrecomputeLRUCache::MoveLastToDirtyIfFull()
{
if (mapCacheLocation.size() > PRECOMPUTE_LRU_CACHE_SIZE) {
auto last_it = cache_list.end(); last_it --;
Expand All @@ -58,7 +58,7 @@ void LRUCache::MoveLastToDirtyIfFull()
}
}

CoinWitnessData LRUCache::GetWitnessData(const uint256& hash)
CoinWitnessData PrecomputeLRUCache::GetWitnessData(const uint256& hash)
{
if (mapDirtyWitnessData.count(hash)) {
MoveDirtyToLRU(hash);
Expand All @@ -74,7 +74,7 @@ CoinWitnessData LRUCache::GetWitnessData(const uint256& hash)
return CoinWitnessData();
}

void LRUCache::Remove(const uint256& hash)
void PrecomputeLRUCache::Remove(const uint256& hash)
{
auto it = mapCacheLocation.find(hash);
if (it != mapCacheLocation.end()) {
Expand All @@ -84,7 +84,7 @@ void LRUCache::Remove(const uint256& hash)
mapDirtyWitnessData.erase(hash);
}

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

void LRUCache::FlushToDisk(CPrecomputeDB* pprecomputeDB)
void PrecomputeLRUCache::FlushToDisk(CPrecomputeDB* pprecomputeDB)
{
// Save all cache data that was dirty back into the database
for (auto item : mapDirtyWitnessData) {
Expand Down
54 changes: 51 additions & 3 deletions src/veil/zerocoin/lrucache.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#define VEIL_LRUCACHE_H

#include <veil/zerocoin/witness.h>
#include <unordered_map>
#include <list>

class LRUCache
class PrecomputeLRUCache
{
private:
std::list<std::pair<uint256, CoinWitnessCacheData> > cache_list;
Expand All @@ -22,12 +24,58 @@ class LRUCache
void Clear();
void FlushToDisk(CPrecomputeDB* pprecomputeDB);
CoinWitnessData GetWitnessData(const uint256& hash);
LRUCache();
PrecomputeLRUCache();
void MoveDirtyToLRU(const uint256& hash);
void MoveLastToDirtyIfFull();
void Remove(const uint256& hash);
int Size() const;
int DirtyCacheSize() const;
};

#endif //VEIL_LRUCACHE_H


template<typename K, typename V = K>
class LRUCacheTemplate
{

private:
std::list<K>items;
std::unordered_map <K, std::pair<V, typename std::list<K>::iterator>> keyValuesMap;
int csize;

public:
LRUCacheTemplate(int s) :csize(s) {
if (csize < 1)
csize = 10;
}

void set(const K key, const V value) {
auto pos = keyValuesMap.find(key);
if (pos == keyValuesMap.end()) {
items.push_front(key);
keyValuesMap[key] = { value, items.begin() };
if (keyValuesMap.size() > csize) {
keyValuesMap.erase(items.back());
items.pop_back();
}
}
else {
items.erase(pos->second.second);
items.push_front(key);
keyValuesMap[key] = { value, items.begin() };
}
}

bool get(const K key, V &value) {
auto pos = keyValuesMap.find(key);
if (pos == keyValuesMap.end())
return false;
items.erase(pos->second.second);
items.push_front(key);
keyValuesMap[key] = { pos->second.first, items.begin() };
value = pos->second.first;
return true;
}
};

#endif //VEIL_LRUCACHE_H
2 changes: 1 addition & 1 deletion src/veil/zerocoin/precompute.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Precompute

public:

LRUCache lru;
PrecomputeLRUCache lru;

Precompute();
void SetNull();
Expand Down
2 changes: 1 addition & 1 deletion src/veil/zerocoin/witness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ CPrecomputeDB::CPrecomputeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBW
{
}

bool CPrecomputeDB::LoadPrecomputes(LRUCache* lru)
bool CPrecomputeDB::LoadPrecomputes(PrecomputeLRUCache* lru)
{

std::unique_ptr<CDBIterator> pcursor(NewIterator());
Expand Down
4 changes: 2 additions & 2 deletions src/veil/zerocoin/witness.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#define PRECOMPUTE_FLUSH_TIME 3600 // 1 Hour

class CoinWitnessCacheData;
class LRUCache;
class PrecomputeLRUCache;

class CoinWitnessData
{
Expand Down Expand Up @@ -90,7 +90,7 @@ class CPrecomputeDB : public CDBWrapper

public:
/** Veil zerocoin precompute database functions */
bool LoadPrecomputes(LRUCache* lru);
bool LoadPrecomputes(PrecomputeLRUCache* lru);
bool LoadPrecomputes(std::set<uint256> setHashes);
bool EraseAllPrecomputes();
bool WritePrecompute(const uint256& hash, const CoinWitnessCacheData& data);
Expand Down

0 comments on commit 7c9e97a

Please sign in to comment.