Skip to content

Commit

Permalink
Database mints generated by the mintpool.
Browse files Browse the repository at this point in the history
- Load all generated mints on initialization. Then remove mints from the mintpool that are already known.
  • Loading branch information
presstab authored and Fuzzbawls committed Apr 9, 2018
1 parent c697920 commit 4b7c9ba
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,6 +1647,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)

//Load zerocoin mint hashes to memory
CWalletDB(pwalletMain->strWalletFile).ListMintedCoins(true, true, true, pwalletMain->zpivTracker);
zwalletMain->LoadMintPoolFromDB();
zwalletMain->RemoveMintsFromPool(pwalletMain->zpivTracker->GetSerialHashes());
zwalletMain->SyncWithChain();
} // (!fDisableWallet)
#else // ENABLE_WALLET
Expand Down
21 changes: 15 additions & 6 deletions src/mintpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ CMintPool::CMintPool(uint32_t nCount)
void CMintPool::Add(const CBigNum& bnValue, const uint32_t& nCount)
{
uint256 hash = GetPubCoinHash(bnValue);
insert(make_pair(hash, nCount));
if (nCount > nCountLastGenerated)
nCountLastGenerated = nCount;

Add(make_pair(hash, nCount));
LogPrintf("%s : add %s to mint pool, nCountLastGenerated=%d\n", __func__, bnValue.GetHex().substr(0, 6), nCountLastGenerated);
}

void CMintPool::Add(const pair<uint256, uint32_t>& pMint)
{
insert(pMint);
if (pMint.second > nCountLastGenerated)
nCountLastGenerated = pMint.second;
}

bool CMintPool::Has(const CBigNum& bnValue)
{
return static_cast<bool>(count(GetPubCoinHash(bnValue)));
Expand Down Expand Up @@ -84,11 +88,16 @@ bool CMintPool::Next(pair<uint256, uint32_t>& pMint)

void CMintPool::Remove(const CBigNum& bnValue)
{
auto it = find(GetPubCoinHash(bnValue));
Remove(GetPubCoinHash(bnValue));
LogPrintf("%s : remove %s from mint pool\n", __func__, bnValue.GetHex().substr(0, 6));
}

void CMintPool::Remove(const uint256& hashPubcoin)
{
auto it = find(hashPubcoin);
if (it == end())
return;

LogPrintf("%s : remove %s from mint pool\n", __func__, it->first.GetHex().substr(0, 6));
nCountLastRemoved = it->second;
erase(it);
}
Expand Down
2 changes: 2 additions & 0 deletions src/mintpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ class CMintPool : public std::map<uint256, uint32_t> //pubcoin hash, count
CMintPool();
explicit CMintPool(uint32_t nCount);
void Add(const CBigNum& bnValue, const uint32_t& nCount);
void Add(const std::pair<uint256, uint32_t>& pMint);
bool Has(const CBigNum& bnValue);
void Remove(const CBigNum& bnValue);
void Remove(const uint256& hashPubcoin);
std::pair<uint256, uint32_t> Get(const CBigNum& bnValue);
std::list<std::pair<uint256, uint32_t> > List();
void Reset();
Expand Down
75 changes: 71 additions & 4 deletions src/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,68 @@ bool CWalletDB::ReadZPIVCount(uint32_t& nCount)
return Read(string("dzc"), nCount);
}

bool CWalletDB::WriteMintPoolPair(const uint256& hashMasterSeed, const uint256& hashPubcoin, const uint32_t& nCount)
{
return Write(make_pair(string("mintpool"), hashPubcoin), make_pair(hashMasterSeed, nCount));
}

//! map with hashMasterSeed as the key, paired with vector of hashPubcoins and their count
std::map<uint256, std::vector<pair<uint256, uint32_t> > > CWalletDB::MapMintPool()
{
std::map<uint256, std::vector<pair<uint256, uint32_t> > > mapPool;
Dbc* pcursor = GetCursor();
if (!pcursor)
throw runtime_error(std::string(__func__)+" : cannot create DB cursor");
unsigned int fFlags = DB_SET_RANGE;
for (;;)
{
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
if (fFlags == DB_SET_RANGE)
ssKey << make_pair(string("mintpool"), uint256(0));
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
{
pcursor->close();
throw runtime_error(std::string(__func__)+" : error scanning DB");
}

// Unserialize
string strType;
ssKey >> strType;
if (strType != "mintpool")
break;

uint256 hashPubcoin;
ssKey >> hashPubcoin;

uint256 hashMasterSeed;
ssValue >> hashMasterSeed;

uint32_t nCount;
ssValue >> nCount;

pair<uint256, uint32_t> pMint;
pMint.first = hashPubcoin;
pMint.second = nCount;
if (mapPool.count(hashMasterSeed)) {
mapPool.at(hashMasterSeed).emplace_back(pMint);
} else {
vector<pair<uint256, uint32_t> > vPairs;
vPairs.emplace_back(pMint);
mapPool.insert(make_pair(hashMasterSeed, vPairs));
}
}

pcursor->close();

return mapPool;
}

std::list<CZerocoinMint> CWalletDB::ListMintedCoins(bool fUnusedOnly, bool fMaturedOnly, bool fUpdateStatus, CzPIVTracker* zpivTracker)
{
std::list<CZerocoinMint> listPubCoin;
Expand Down Expand Up @@ -1262,12 +1324,17 @@ std::list<CZerocoinMint> CWalletDB::ListMintedCoins(bool fUnusedOnly, bool fMatu
pcursor->close();

//overwrite any updates
for (CZerocoinMint& mint : vOverWrite)
zpivTracker->UpdateMint(mint);
for (CZerocoinMint& mint : vOverWrite) {
zpivTracker->UpdateMint(mint, false);
WriteZerocoinMint(mint);
}

// archive mints
for (CZerocoinMint& mint : vArchive)
zpivTracker->Archive(mint);
for (CZerocoinMint& mint : vArchive) {
zpivTracker->Archive(mint, false);
ArchiveMintOrphan(mint);
}


return listPubCoin;
}
Expand Down
2 changes: 2 additions & 0 deletions src/walletdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ class CWalletDB : public CDB
bool WriteZPIVCount(const uint32_t& nCount);
bool ReadZPIVCount(uint32_t& nCount);
bool ReadZerocoinMintFromSerial(const CBigNum& bnSerial, CZerocoinMint& mint);
std::map<uint256, std::vector<pair<uint256, uint32_t> > > MapMintPool();
bool WriteMintPoolPair(const uint256& hashMasterSeed, const uint256& hashPubcoin, const uint32_t& nCount);

private:
CWalletDB(const CWalletDB&);
Expand Down
14 changes: 13 additions & 1 deletion src/zpivtracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ CzPIVTracker::CzPIVTracker(std::string strWalletFile)
mapSerialHashes.clear();
}

bool CzPIVTracker::Archive(CZerocoinMint& mint)
bool CzPIVTracker::Archive(CZerocoinMint& mint, bool fUpdateDB)
{
uint256 hashSerial = GetSerialHash(mint.GetSerialNumber());
if (mapSerialHashes.count(hashSerial))
mapSerialHashes.at(hashSerial).isArchived = true;

if (!fUpdateDB)
return true;

return CWalletDB(strWalletFile).ArchiveMintOrphan(mint);
}

Expand All @@ -26,6 +29,15 @@ CMintMeta CzPIVTracker::Get(const uint256 &hashSerial)
return mapSerialHashes.at(hashSerial);
}

std::vector<uint256> CzPIVTracker::GetSerialHashes()
{
vector<uint256> vHashes;
for (auto it : mapSerialHashes)
vHashes.emplace_back(it.first);

return vHashes;
}

CAmount CzPIVTracker::GetBalance(bool fConfirmedOnly, bool fUnconfirmedOnly) const
{
CAmount nTotal = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/zpivtracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ class CzPIVTracker
std::map<uint256, CMintMeta> mapSerialHashes;
public:
CzPIVTracker(std::string strWalletFile);
bool Archive(CZerocoinMint& mint);
bool Archive(CZerocoinMint& mint, bool fUpdateDB = true);
bool HasPubcoin(const CBigNum& bnValue) const;
bool HasPubcoinHash(const uint256& hashPubcoin) const;
bool HasSerial(const CBigNum& bnSerial) const;
bool HasSerialHash(const uint256& hashSerial) const;
bool IsEmpty() const { return mapSerialHashes.empty(); }
CMintMeta Get(const uint256& hashSerial);
CAmount GetBalance(bool fConfirmedOnly, bool fUnconfirmedOnly) const;
std::vector<uint256> GetSerialHashes();
std::vector<CMintMeta> GetMints(bool fConfirmedOnly) const;
CAmount GetUnconfirmedBalance() const;
bool UpdateMint(CZerocoinMint& mint, bool fUpdateDB = true);
Expand Down
25 changes: 24 additions & 1 deletion src/zpivwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ bool CzPIVWallet::SetMasterSeed(const uint256& seedMaster, bool fResetCount)
void CzPIVWallet::GenerateMintPool()
{
int n = std::max(mintPool.CountOfLastGenerated() + 1, nCount);

int nStop = n + 20;
uint256 hashSeed = Hash(seedMaster.begin(), seedMaster.end());
LogPrintf("%s : n=%d nStop=%d\n", __func__, n, nStop);
for (int i = n; i < nStop; i++) {
uint512 seedZerocoin = GetZerocoinSeed(i);
Expand All @@ -69,10 +69,33 @@ void CzPIVWallet::GenerateMintPool()
coin.setVersion(PrivateCoin::CURRENT_VERSION);
coin.setPrivKey(key.GetPrivKey());
mintPool.Add(coin.getPublicCoin().getValue(), i);
CWalletDB(strWalletFile).WriteMintPoolPair(hashSeed, GetPubCoinHash(coin.getPublicCoin().getValue()), i);
LogPrintf("%s : %s count=%d\n", __func__, coin.getPublicCoin().getValue().GetHex().substr(0, 6), i);
}
}

// pubcoin hashes are stored to db so that a full accounting of mints belonging to the seed can be tracked without regenerating
bool CzPIVWallet::LoadMintPoolFromDB()
{
vector<pair<uint256, uint32_t> > vGenerated;
map<uint256, vector<pair<uint256, uint32_t> > > mapMintPool = CWalletDB(strWalletFile).MapMintPool();

//Todo: separate hashMasterSeeds
for (auto& it : mapMintPool) {
//todo check for any missing
for (auto& pair : it.second)
mintPool.Add(pair);
}

return true;
}

void CzPIVWallet::RemoveMintsFromPool(const std::vector<uint256>& vPubcoinHashes)
{
for (const uint256& hash : vPubcoinHashes)
mintPool.Remove(hash);
}

//Catch the counter up with the chain
map<uint256, uint32_t> mapMissingMints;
void CzPIVWallet::SyncWithChain()
Expand Down
2 changes: 2 additions & 0 deletions src/zpivwallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class CzPIVWallet
void GenerateDeterministicZPIV(libzerocoin::CoinDenomination denom, libzerocoin::PrivateCoin& coin, bool fGenerateOnly = false);
void GenerateMint(uint32_t nCount, libzerocoin::PrivateCoin& coin, libzerocoin::CoinDenomination denom = libzerocoin::CoinDenomination::ZQ_ONE);
void GenerateMintPool();
bool LoadMintPoolFromDB();
void RemoveMintsFromPool(const std::vector<uint256>& vPubcoinHashes);
bool SetMintSeen(const CBigNum& bnValue, const int& nHeight, const uint256& txid, const libzerocoin::CoinDenomination& denom);
bool IsInMintPool(const CBigNum& bnValue) { return mintPool.Has(bnValue); }

Expand Down

0 comments on commit 4b7c9ba

Please sign in to comment.