Skip to content

Commit

Permalink
[Cleanup] Remove precomputing
Browse files Browse the repository at this point in the history
Precomputing for zPIV spends is no longer used, and the bulk of it's
code was simply commented out. This removes the now-dead code, as well
as removes the runtime `-precompute` option and it's associated thread.

Github-Pull: #1234
Rebased-From: 2e1c2d0
  • Loading branch information
Fuzzbawls committed Jan 11, 2020
1 parent ee4aed3 commit f035a4a
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 305 deletions.
5 changes: 0 additions & 5 deletions src/init.cpp
Expand Up @@ -2025,11 +2025,6 @@ bool AppInit2()
// Run a thread to flush wallet periodically
threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));

if (GetBoolArg("-precompute", false)) {
// Run a thread to precompute any zPIV spends
threadGroup.create_thread(boost::bind(&ThreadPrecomputeSpends));
}

if (GetBoolArg("-staking", true)) {
// ppcoin:mint proof-of-stake blocks in the background
threadGroup.create_thread(boost::bind(&ThreadStakeMinter));
Expand Down
296 changes: 0 additions & 296 deletions src/wallet/wallet.cpp
Expand Up @@ -5199,302 +5199,6 @@ bool CWallet::DatabaseMint(CDeterministicMint& dMint)
return true;
}

void ThreadPrecomputeSpends()
{
boost::this_thread::interruption_point();
LogPrintf("ThreadPrecomputeSpends started\n");
CWallet* pwallet = pwalletMain;
try {
pwallet->PrecomputeSpends();
boost::this_thread::interruption_point();
} catch (const std::exception& e) {
LogPrintf("ThreadPrecomputeSpends() exception: %s \n", e.what());
} catch (...) {
LogPrintf("ThreadPrecomputeSpends() error \n");
}
LogPrintf("ThreadPrecomputeSpends exiting,\n");
}

void CWallet::PrecomputeSpends()
{
// We don't even need to worry about this code.. no zPIV.
/*
LogPrintf("Precomputer started\n");
RenameThread("pivx-precomputer");
CWalletDB walletdb("precomputes.dat", "cr+");
// Create LRU Cache
std::list<std::pair<uint256, CoinWitnessCacheData> > item_list;
std::map<uint256, std::list<std::pair<uint256, CoinWitnessCacheData> >::iterator> item_map;
// Dirty cache that needs to be written to disk
std::map<uint256, CoinWitnessCacheData> mapDirtyWitnessData;
// Initialize Variables
bool fLoadedPrecomputesFromDB = false;
bool fOnFirstLoad = true;
int64_t nLastCacheCleanUpTime = GetTime();
int64_t nLastCacheWriteDB = nLastCacheCleanUpTime;
int nRequiredStakeDepthBuffer = Params().Zerocoin_RequiredStakeDepth() + 10;
int nAdjustableCacheLength = GetArg("-precomputecachelength", DEFAULT_PRECOMPUTE_LENGTH);
// Force the cache length to be divisible by 10
if (nAdjustableCacheLength % 10)
nAdjustableCacheLength -= nAdjustableCacheLength % 10;
if (nAdjustableCacheLength < MIN_PRECOMPUTE_LENGTH)
nAdjustableCacheLength = MIN_PRECOMPUTE_LENGTH;
if (nAdjustableCacheLength > MAX_PRECOMPUTE_LENGTH)
nAdjustableCacheLength = MAX_PRECOMPUTE_LENGTH;
while (true) {
// Check to see if we need to clear the cache
if (fClearSpendCache) {
fClearSpendCache = false;
item_map.clear();
item_list.clear();
mapDirtyWitnessData.clear();
nLastCacheCleanUpTime = GetTime();
nLastCacheWriteDB = nLastCacheCleanUpTime;
}
// Get the list of zPIV inputs
std::list <std::unique_ptr<CStakeInput>> listInputs;
if (!SelectStakeCoins(listInputs, 0, true)) {
MilliSleep(5000);
continue;
}
if (listInputs.empty()) {
MilliSleep(5000);
continue;
}
if (ShutdownRequested())
break;
while (IsLocked())
MilliSleep(5000);
// If we haven't loaded from database yet, load the precomputes from the database
if (!fLoadedPrecomputesFromDB) {
// Load the precomputes into the LRU cache
walletdb.LoadPrecomputes(item_list, item_map);
fLoadedPrecomputesFromDB = true;
LogPrint("precompute", "%s: Loaded precomputes from database. Size of lru cache: %d\n", __func__,
item_map.size());
}
// Do some precomputing of zerocoin spend knowledge proofs
std::set <uint256> setInputHashes;
for (std::unique_ptr <CStakeInput>& stakeInput : listInputs) {
if (ShutdownRequested() || IsLocked())
break;
CoinWitnessCacheData tempDataHolder;
{
TRY_LOCK(zpivTracker->cs_spendcache, fLocked);
if (!fLocked)
continue;
if (fGlobalUnlockSpendCache) {
break;
}
// When we see a clear spend cache bool set to true, break out of the loop
// All cache data will be cleared at the beginning of the while loop above
if (fClearSpendCache) {
break;
}
uint256 serialHash = stakeInput->GetSerialHash();
setInputHashes.insert(serialHash);
CoinWitnessData* witnessData = zpivTracker->GetSpendCache(serialHash);
// Initialize nHeightStop so it can be set below
int nHeightStop = 0;
if (witnessData->nHeightAccStart) { // Witness is already valid
nHeightStop = std::min(chainActive.Height() - nRequiredStakeDepthBuffer,
(witnessData->nHeightAccEnd ? witnessData->nHeightAccEnd
: witnessData->nHeightAccStart) +
nAdjustableCacheLength);
} else if (item_map.count(serialHash)) { // Check Database cache
// Get the witness data from the cache
auto it = item_map.find(serialHash);
item_list.splice(item_list.begin(), item_list, it->second);
*witnessData = CoinWitnessData(it->second->second);
// Set the stop height from the variables received from the database cache
nHeightStop = std::min(chainActive.Height() - nRequiredStakeDepthBuffer,
(witnessData->nHeightAccEnd ? witnessData->nHeightAccEnd
: witnessData->nHeightAccStart) +
nAdjustableCacheLength);
LogPrint("precompute", "%s: Got Witness Data from lru cache: %s\n", __func__,
witnessData->ToString());
} else if (mapDirtyWitnessData.count(serialHash) || walletdb.ReadPrecompute(serialHash, tempDataHolder)) {
if (mapDirtyWitnessData.count(serialHash)) {
// Get the witness data from the dirty cache if it exists
*witnessData = CoinWitnessData(mapDirtyWitnessData.at(serialHash));
LogPrint("precompute", "%s: Got Witness Data from mapDirtyWitnessData: %s\n", __func__,
witnessData->ToString());
} else {
// Get the witness data from the database
*witnessData = CoinWitnessData(tempDataHolder);
LogPrint("precompute", "%s: Got Witness Data from precompute database: %s\n", __func__,
witnessData->ToString());
}
// Set the stop height from the variables received from the database cache
nHeightStop = std::min(chainActive.Height() - nRequiredStakeDepthBuffer,
(witnessData->nHeightAccEnd ? witnessData->nHeightAccEnd
: witnessData->nHeightAccStart) +
nAdjustableCacheLength);
// Add the serialHash found into the cache
item_list.push_front(std::make_pair(serialHash, tempDataHolder));
item_map.insert(std::make_pair(serialHash, item_list.begin()));
// We just added a new hash into our LRU cache, so remove it if we also have it in the dirty map
mapDirtyWitnessData.erase(serialHash);
if (item_map.size() > PRECOMPUTE_LRU_CACHE_SIZE) {
auto last_it = item_list.end(); last_it --;
item_map.erase(last_it->first);
CoinWitnessCacheData removedData = item_list.back().second;
mapDirtyWitnessData[serialHash] = removedData;
item_list.pop_back();
}
} else { // This has no cache, so initialize it
CZerocoinMint mint;
if (!GetMintFromStakeHash(serialHash, mint))
continue;
*witnessData = CoinWitnessData(mint);
nHeightStop = std::min(chainActive.Height() - nRequiredStakeDepthBuffer,
mint.GetHeight() + nAdjustableCacheLength);
}
if (nHeightStop - (witnessData->nHeightAccEnd ? witnessData->nHeightAccEnd : witnessData->nHeightAccStart) < 20)
continue;
CBlockIndex* pindexStop = chainActive[nHeightStop];
AccumulatorMap mapAccumulators(Params().Zerocoin_Params(false));
LogPrint("precompute","%s: caching mint %s of denom %d start=%d stop=%d end=%s\n", __func__,
witnessData->coin->getValue().GetHex().substr(0, 6),
ZerocoinDenominationToInt(witnessData->denom),
witnessData->nHeightAccStart, nHeightStop, witnessData->nHeightAccEnd);
if (!GenerateAccumulatorWitness(witnessData, mapAccumulators, pindexStop)) {
LogPrintf("%s: Generate witness failed!\n", __func__);
// If we fail this check, we need to make sure we remove this from the LRU cache
auto it = item_map.find(serialHash);
if (it != item_map.end())
{
item_list.erase(it->second);
item_map.erase(it);
}
mapDirtyWitnessData.erase(serialHash);
walletdb.ErasePrecompute(serialHash);
continue;
}
CoinWitnessCacheData serialData(witnessData);
// If the LRU cache already has a entry for it, update the entry and move it to the front of the list
auto it = item_map.find(serialHash);
if (it != item_map.end()) {
item_list.splice(item_list.begin(), item_list, it->second);
item_list.begin()->second = serialData;
} else {
item_list.push_front(std::make_pair(serialHash, serialData));
item_map.insert(std::make_pair(serialHash, item_list.begin()));
}
// We just added a new hash into our LRU cache, so remove it if we also have it in the dirty map
mapDirtyWitnessData.erase(serialHash);
// Clean up the LRU cache to the max size
while (item_map.size() > PRECOMPUTE_LRU_CACHE_SIZE) {
auto last_it = item_list.end(); last_it --;
item_map.erase(last_it->first);
mapDirtyWitnessData[serialHash] = item_list.back().second;
item_list.pop_back();
}
}
// Sleep for 150ms to allow any potential spend attempt
MilliSleep(150);
}
if (fGlobalUnlockSpendCache) {
fGlobalUnlockSpendCache = false;
}
// On first load, and every 5 minutes clean up our cache with only valid unspent inputs
if (fOnFirstLoad || nLastCacheCleanUpTime < GetTime() - PRECOMPUTE_FLUSH_TIME) {
LogPrint("precompute", "%s: Cleaning up precompute cache\n", __func__);
// We only want to clear the cache if we have calculated new witness data
if (setInputHashes.size()) {
// Get a list of hashes currently in the database
std::set <uint256> databaseHashes;
walletdb.LoadPrecomputes(databaseHashes);
// Remove old cache data
for (auto inputHash : setInputHashes) {
databaseHashes.erase(inputHash);
}
// Erase all old hashes from the database
for (auto hash : databaseHashes) {
auto it = item_map.find(hash);
if (it != item_map.end())
{
item_list.erase(it->second);
item_map.erase(it);
}
mapDirtyWitnessData.erase(hash);
walletdb.ErasePrecompute(hash);
}
nLastCacheCleanUpTime = GetTime();
}
}
// On first load, and every 5 minutes write the cache to database
if (mapDirtyWitnessData.size() > PRECOMPUTE_MAX_DIRTY_CACHE_SIZE || nLastCacheWriteDB < GetTime() - PRECOMPUTE_FLUSH_TIME || ShutdownRequested()) {
// Save all cache data that was dirty back into the database
for (auto item : mapDirtyWitnessData) {
walletdb.WritePrecompute(item.first, item.second);
}
mapDirtyWitnessData.clear();
// Save the LRU cache data into the database
for (auto item : item_list) {
walletdb.WritePrecompute(item.first, item.second);
}
LogPrint("precompute", "%s: Writing precomputes to database. Precomputes size: %d\n", __func__, item_map.size());
nLastCacheWriteDB = GetTime();
}
fOnFirstLoad = false;
if (ShutdownRequested())
break;
LogPrint("precompute", "%s: Finished precompute round...\n\n", __func__);
MilliSleep(5000);
}*/
}

CWallet::CWallet()
{
SetNull();
Expand Down
4 changes: 0 additions & 4 deletions src/wallet/wallet.h
Expand Up @@ -325,8 +325,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface

std::vector<CWalletTx> getWalletTxs();

void PrecomputeSpends();

//! check whether we are allowed to upgrade (or already support) to the named feature
bool CanSupportFeature(enum WalletFeature wf);

Expand Down Expand Up @@ -1027,6 +1025,4 @@ class CAccountingEntry
std::vector<char> _ssExtra;
};

void ThreadPrecomputeSpends();

#endif // BITCOIN_WALLET_H

0 comments on commit f035a4a

Please sign in to comment.