Skip to content

Commit

Permalink
Merge bitcoin#636: [Main] Write to the zerocoinDB in batches
Browse files Browse the repository at this point in the history
cd672cd [Main] Write to the zerocoinDB in batches (Fuzzbawls)

Tree-SHA512: 031d41bf5d09b2f3636e191e0de5fbf8062cd967f76a25fe2705dceaf4e9a65875c394af5fb6e2ad08739a4acd3fa7945eff4594a11040e5aa9cf2b93ca04cd8
  • Loading branch information
Mrs-X committed Jun 28, 2018
2 parents 98c7a4f + cd672cd commit d359c61
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 23 deletions.
16 changes: 5 additions & 11 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2937,8 +2937,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
unsigned int nSigOps = 0;
CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
std::vector<pair<CoinSpend, uint256> > vSpends;
vector<pair<PublicCoin, uint256> > vMints;
std::vector<std::pair<CoinSpend, uint256> > vSpends;
std::vector<std::pair<PublicCoin, uint256> > vMints;
vPos.reserve(block.vtx.size());
CBlockUndo blockundo;
blockundo.vtxundo.reserve(block.vtx.size() - 1);
Expand Down Expand Up @@ -3135,10 +3135,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
//Record zPIV serials
set<uint256> setAddedTx;
for (pair<CoinSpend, uint256> pSpend : vSpends) {
//record spend to database
if (!zerocoinDB->WriteCoinSpend(pSpend.first.getCoinSerialNumber(), pSpend.second))
return state.Abort(("Failed to record coin serial to database"));

// Send signal to wallet if this is ours
if (pwalletMain) {
if (pwalletMain->IsMyZerocoinSpend(pSpend.first.getCoinSerialNumber())) {
Expand All @@ -3163,11 +3159,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}
}

//Record mints to db
for (pair<PublicCoin, uint256> pMint : vMints) {
if (!zerocoinDB->WriteCoinMint(pMint.first, pMint.second))
return state.Abort(("Failed to record new mint to database"));
}
// Flush spend/mint info to disk
if (!zerocoinDB->WriteCoinSpendBatch(vSpends)) return state.Abort(("Failed to record coin serials to database"));
if (!zerocoinDB->WriteCoinMintBatch(vMints)) return state.Abort(("Failed to record new mints to database"));

//Record accumulator checksums
DatabaseChecksums(mapAccumulators);
Expand Down
33 changes: 25 additions & 8 deletions src/txdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,19 @@ CZerocoinDB::CZerocoinDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDB
{
}

bool CZerocoinDB::WriteCoinMint(const PublicCoin& pubCoin, const uint256& hashTx)
bool CZerocoinDB::WriteCoinMintBatch(const std::vector<std::pair<libzerocoin::PublicCoin, uint256> >& mintInfo)
{
uint256 hash = GetPubCoinHash(pubCoin.getValue());
return Write(make_pair('m', hash), hashTx, true);
CLevelDBBatch batch;
size_t count = 0;
for (std::vector<std::pair<libzerocoin::PublicCoin, uint256> >::const_iterator it=mintInfo.begin(); it != mintInfo.end(); it++) {
PublicCoin pubCoin = it->first;
uint256 hash = GetPubCoinHash(pubCoin.getValue());
batch.Write(make_pair('m', hash), it->second);
++count;
}

LogPrint("zero", "Writing %u coin mints to db.\n", (unsigned int)count);
return WriteBatch(batch, true);
}

bool CZerocoinDB::ReadCoinMint(const CBigNum& bnPubcoin, uint256& hashTx)
Expand All @@ -316,13 +325,21 @@ bool CZerocoinDB::EraseCoinMint(const CBigNum& bnPubcoin)
return Erase(make_pair('m', hash));
}

bool CZerocoinDB::WriteCoinSpend(const CBigNum& bnSerial, const uint256& txHash)
bool CZerocoinDB::WriteCoinSpendBatch(const std::vector<std::pair<libzerocoin::CoinSpend, uint256> >& spendInfo)
{
CDataStream ss(SER_GETHASH, 0);
ss << bnSerial;
uint256 hash = Hash(ss.begin(), ss.end());
CLevelDBBatch batch;
size_t count = 0;
for (std::vector<std::pair<libzerocoin::CoinSpend, uint256> >::const_iterator it=spendInfo.begin(); it != spendInfo.end(); it++) {
CBigNum bnSerial = it->first.getCoinSerialNumber();
CDataStream ss(SER_GETHASH, 0);
ss << bnSerial;
uint256 hash = Hash(ss.begin(), ss.end());
batch.Write(make_pair('s', hash), it->second);
++count;
}

return Write(make_pair('s', hash), txHash, true);
LogPrint("zero", "Writing %u coin spends to db.\n", (unsigned int)count);
return WriteBatch(batch, true);
}

bool CZerocoinDB::ReadCoinSpend(const CBigNum& bnSerial, uint256& txHash)
Expand Down
7 changes: 5 additions & 2 deletions src/txdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class CBlockTreeDB : public CLevelDBWrapper
bool LoadBlockIndexGuts();
};

/** Zerocoin database (zerocoin/) */
class CZerocoinDB : public CLevelDBWrapper
{
public:
Expand All @@ -79,10 +80,12 @@ class CZerocoinDB : public CLevelDBWrapper
void operator=(const CZerocoinDB&);

public:
bool WriteCoinMint(const libzerocoin::PublicCoin& pubCoin, const uint256& txHash);
/** Write zPIV mints to the zerocoinDB in a batch */
bool WriteCoinMintBatch(const std::vector<std::pair<libzerocoin::PublicCoin, uint256> >& mintInfo);
bool ReadCoinMint(const CBigNum& bnPubcoin, uint256& txHash);
bool ReadCoinMint(const uint256& hashPubcoin, uint256& hashTx);
bool WriteCoinSpend(const CBigNum& bnSerial, const uint256& txHash);
/** Write zPIV spends to the zerocoinDB in a batch */
bool WriteCoinSpendBatch(const std::vector<std::pair<libzerocoin::CoinSpend, uint256> >& spendInfo);
bool ReadCoinSpend(const CBigNum& bnSerial, uint256& txHash);
bool ReadCoinSpend(const uint256& hashSerial, uint256 &txHash);
bool EraseCoinMint(const CBigNum& bnPubcoin);
Expand Down
21 changes: 19 additions & 2 deletions src/zpivchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ std::string ReindexZerocoinDB()
uiInterface.ShowProgress(_("Reindexing zerocoin database..."), 0);

CBlockIndex* pindex = chainActive[Params().Zerocoin_StartHeight()];
std::vector<std::pair<libzerocoin::CoinSpend, uint256> > vSpendInfo;
std::vector<std::pair<libzerocoin::PublicCoin, uint256> > vMintInfo;
while (pindex) {
uiInterface.ShowProgress(_("Reindexing zerocoin database..."), std::max(1, std::min(99, (int)((double)(pindex->nHeight - Params().Zerocoin_StartHeight()) / (double)(chainActive.Height() - Params().Zerocoin_StartHeight()) * 100))));

Expand All @@ -287,7 +289,7 @@ std::string ReindexZerocoinDB()
continue;

libzerocoin::CoinSpend spend = TxInToZerocoinSpend(in);
zerocoinDB->WriteCoinSpend(spend.getCoinSerialNumber(), txid);
vSpendInfo.push_back(make_pair(spend, txid));
}
}

Expand All @@ -300,16 +302,31 @@ std::string ReindexZerocoinDB()
CValidationState state;
libzerocoin::PublicCoin coin(Params().Zerocoin_Params(pindex->nHeight < Params().Zerocoin_Block_V2_Start()));
TxOutToPublicCoin(out, coin, state);
zerocoinDB->WriteCoinMint(coin, txid);
vMintInfo.push_back(make_pair(coin, txid));
}
}
}
}
}

// Flush the zerocoinDB to disk every 100 blocks
if (pindex->nHeight % 100 == 0) {
if ((!vSpendInfo.empty() && !zerocoinDB->WriteCoinSpendBatch(vSpendInfo)) || (!vMintInfo.empty() && !zerocoinDB->WriteCoinMintBatch(vMintInfo)))
return _("Error writing zerocoinDB to disk");
vSpendInfo.clear();
vMintInfo.clear();
}

pindex = chainActive.Next(pindex);
}
uiInterface.ShowProgress("", 100);

// Final flush to disk in case any remaining information exists
if ((!vSpendInfo.empty() && !zerocoinDB->WriteCoinSpendBatch(vSpendInfo)) || (!vMintInfo.empty() && !zerocoinDB->WriteCoinMintBatch(vMintInfo)))
return _("Error writing zerocoinDB to disk");

uiInterface.ShowProgress("", 100);

return "";
}

Expand Down

0 comments on commit d359c61

Please sign in to comment.