Skip to content

Commit 7139c20

Browse files
presstabFuzzbawls
authored andcommitted
Mark orphan zPIV stake input as not used.
Change listMints() to std::set. Add mapPendingSpends to track spends. -Change to set to reduce BigO complexity. -add mapPendingSpends to keep track of spends that were made so that they do not get considered as falsly marked as not used while they are in the mempool. Check mempool for pending spends.
1 parent 80435d7 commit 7139c20

17 files changed

+184
-143
lines changed

src/libzerocoin/CoinSpend.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace libzerocoin
3434
// Sanity check: let's verify that the Witness is valid with respect to
3535
// the coin and Accumulator provided.
3636
if (!(witness.VerifyWitness(a, coin.getPublicCoin()))) {
37-
std::cout << "CoinSpend: Accumulator witness does not verify\n";
37+
//std::cout << "CoinSpend: Accumulator witness does not verify\n";
3838
throw std::runtime_error("Accumulator witness does not verify");
3939
}
4040

@@ -75,28 +75,28 @@ bool CoinSpend::Verify(const Accumulator& a) const
7575
{
7676
// Double check that the version is the same as marked in the serial
7777
if (ExtractVersionFromSerial(coinSerialNumber) != version) {
78-
cout << "CoinSpend::Verify: version does not match serial=" << (int)ExtractVersionFromSerial(coinSerialNumber) << " actual=" << (int)version << endl;
78+
//cout << "CoinSpend::Verify: version does not match serial=" << (int)ExtractVersionFromSerial(coinSerialNumber) << " actual=" << (int)version << endl;
7979
return false;
8080
}
8181

8282
if (a.getDenomination() != this->denomination) {
83-
std::cout << "CoinsSpend::Verify: failed, denominations do not match\n";
83+
//std::cout << "CoinsSpend::Verify: failed, denominations do not match\n";
8484
return false;
8585
}
8686

8787
// Verify both of the sub-proofs using the given meta-data
8888
if (!commitmentPoK.Verify(serialCommitmentToCoinValue, accCommitmentToCoinValue)) {
89-
std::cout << "CoinsSpend::Verify: commitmentPoK failed\n";
89+
//std::cout << "CoinsSpend::Verify: commitmentPoK failed\n";
9090
return false;
9191
}
9292

9393
if (!accumulatorPoK.Verify(a, accCommitmentToCoinValue)) {
94-
std::cout << "CoinsSpend::Verify: accumulatorPoK failed\n";
94+
//std::cout << "CoinsSpend::Verify: accumulatorPoK failed\n";
9595
return false;
9696
}
9797

9898
if (!serialNumberSoK.Verify(coinSerialNumber, serialCommitmentToCoinValue, signatureHash())) {
99-
std::cout << "CoinsSpend::Verify: serialNumberSoK failed. sighash:" << signatureHash().GetHex() << "\n";
99+
//std::cout << "CoinsSpend::Verify: serialNumberSoK failed. sighash:" << signatureHash().GetHex() << "\n";
100100
return false;
101101
}
102102

@@ -137,7 +137,7 @@ bool CoinSpend::HasValidSignature() const
137137
//V2 serial requires that the signature hash be signed by the public key associated with the serial
138138
uint256 hashedPubkey = Hash(pubkey.begin(), pubkey.end()) >> PrivateCoin::V2_BITSHIFT;
139139
if (hashedPubkey != GetAdjustedSerial(coinSerialNumber).getuint256()) {
140-
cout << "CoinSpend::HasValidSignature() hashedpubkey is not equal to the serial!\n";
140+
//cout << "CoinSpend::HasValidSignature() hashedpubkey is not equal to the serial!\n";
141141
return false;
142142
}
143143

src/miner.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,8 +551,11 @@ bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
551551

552552
// Process this block the same as if we had received it from another node
553553
CValidationState state;
554-
if (!ProcessNewBlock(state, NULL, pblock))
554+
if (!ProcessNewBlock(state, NULL, pblock)) {
555+
if (pblock->IsZerocoinStake())
556+
pwalletMain->zpivTracker->RemovePending(pblock->vtx[1].GetHash());
555557
return error("PIVXMiner : ProcessNewBlock, block not accepted");
558+
}
556559

557560
for (CNode* node : vNodes) {
558561
node->PushInventory(CInv(MSG_BLOCK, pblock->GetHash()));

src/primitives/zerocoin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
#include "util.h"
99
#include "utilstrencodings.h"
1010

11+
bool CMintMeta::operator <(const CMintMeta& a) const
12+
{
13+
return this->hashPubcoin < a.hashPubcoin;
14+
}
15+
1116
uint256 GetSerialHash(const CBigNum& bnSerial)
1217
{
1318
CDataStream ss(SER_GETHASH, 0);

src/primitives/zerocoin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ struct CMintMeta
2424
bool isUsed;
2525
bool isArchived;
2626
bool isDeterministic;
27+
28+
bool operator <(const CMintMeta& a) const;
2729
};
2830

2931
uint256 GetSerialHash(const CBigNum& bnSerial);

src/qt/privacydialog.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ void PrivacyDialog::sendzPIV()
413413
// use mints from zPiv selector if applicable
414414
vector<CMintMeta> vMintsToFetch;
415415
vector<CZerocoinMint> vMintsSelected;
416-
if (!ZPivControlDialog::listSelectedMints.empty()) {
416+
if (!ZPivControlDialog::setSelectedMints.empty()) {
417417
vMintsToFetch = ZPivControlDialog::GetSelectedMints();
418418

419419
for (auto& meta : vMintsToFetch) {
@@ -470,7 +470,7 @@ void PrivacyDialog::sendzPIV()
470470
}
471471

472472
// Clear zpiv selector in case it was used
473-
ZPivControlDialog::listSelectedMints.clear();
473+
ZPivControlDialog::setSelectedMints.clear();
474474
ui->labelzPivSelected_int->setText(QString("0"));
475475
ui->labelQuantitySelected_int->setText(QString("0"));
476476

src/qt/walletmodel.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,10 +725,10 @@ void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
725725
}
726726

727727

728-
void WalletModel::listZerocoinMints(std::list<CMintMeta>& listMints, bool fUnusedOnly, bool fMaturedOnly, bool fUpdateStatus)
728+
void WalletModel::listZerocoinMints(std::set<CMintMeta>& setMints, bool fUnusedOnly, bool fMaturedOnly, bool fUpdateStatus)
729729
{
730-
listMints.clear();
731-
listMints = pwalletMain->zpivTracker->ListMints(fUnusedOnly, fMaturedOnly, fUpdateStatus);
730+
setMints.clear();
731+
setMints = pwalletMain->zpivTracker->ListMints(fUnusedOnly, fMaturedOnly, fUpdateStatus);
732732
}
733733

734734
void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)

src/qt/walletmodel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class WalletModel : public QObject
211211
void unlockCoin(COutPoint& output);
212212
void listLockedCoins(std::vector<COutPoint>& vOutpts);
213213

214-
void listZerocoinMints(std::list<CMintMeta>& listMints, bool fUnusedOnly = false, bool fMaturedOnly = false, bool fUpdateStatus = false);
214+
void listZerocoinMints(std::set<CMintMeta>& setMints, bool fUnusedOnly = false, bool fMaturedOnly = false, bool fUpdateStatus = false);
215215

216216
void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
217217
bool saveReceiveRequest(const std::string& sAddress, const int64_t nId, const std::string& sRequest);

src/qt/zpivcontroldialog.cpp

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@
1212
using namespace std;
1313
using namespace libzerocoin;
1414

15-
std::list<std::string> ZPivControlDialog::listSelectedMints;
16-
std::list<CMintMeta> ZPivControlDialog::listMints;
15+
std::set<std::string> ZPivControlDialog::setSelectedMints;
16+
std::set<CMintMeta> ZPivControlDialog::setMints;
1717

1818
ZPivControlDialog::ZPivControlDialog(QWidget *parent) :
1919
QDialog(parent),
2020
ui(new Ui::ZPivControlDialog),
2121
model(0)
2222
{
2323
ui->setupUi(this);
24-
listMints.clear();
24+
setMints.clear();
2525
privacyDialog = (PrivacyDialog*)parent;
2626

2727
// click on checkbox
@@ -64,23 +64,25 @@ void ZPivControlDialog::updateList()
6464
}
6565

6666
// select all unused coins - including not mature. Update status of coins too.
67-
std::list<CMintMeta> list;
68-
model->listZerocoinMints(list, true, false, true);
69-
this->listMints = list;
67+
std::set<CMintMeta> set;
68+
model->listZerocoinMints(set, true, false, true);
69+
this->setMints = set;
7070

7171
//populate rows with mint info
7272
int nBestHeight = chainActive.Height();
7373
map<CoinDenomination, int> mapMaturityHeight = GetMintMaturityHeight();
74-
for(const CMintMeta mint : listMints) {
74+
for (const CMintMeta& mint : setMints) {
7575
// assign this mint to the correct denomination in the tree view
7676
libzerocoin::CoinDenomination denom = mint.denom;
7777
QTreeWidgetItem *itemMint = new QTreeWidgetItem(ui->treeWidget->topLevelItem(mapDenomPosition.at(denom)));
7878

7979
// if the mint is already selected, then it needs to have the checkbox checked
8080
std::string strPubCoinHash = mint.hashPubcoin.GetHex();
81-
itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
82-
if(count(listSelectedMints.begin(), listSelectedMints.end(), strPubCoinHash))
81+
82+
if (setSelectedMints.count(strPubCoinHash))
8383
itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
84+
else
85+
itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
8486

8587
itemMint->setText(COLUMN_DENOMINATION, QString::number(mint.denom));
8688
itemMint->setText(COLUMN_PUBCOIN, QString::fromStdString(strPubCoinHash));
@@ -106,10 +108,8 @@ void ZPivControlDialog::updateList()
106108
itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
107109

108110
//if this mint is in the selection list, then remove it
109-
auto it = std::find(listSelectedMints.begin(), listSelectedMints.end(), mint.hashPubcoin.GetHex());
110-
if (it != listSelectedMints.end()) {
111-
listSelectedMints.erase(it);
112-
}
111+
if (setSelectedMints.count(strPubCoinHash))
112+
setSelectedMints.erase(strPubCoinHash);
113113

114114
string strReason = "";
115115
if(nConfirmations < Params().Zerocoin_MintRequiredConfirmations())
@@ -135,16 +135,15 @@ void ZPivControlDialog::updateSelection(QTreeWidgetItem* item, int column)
135135

136136
// see if this mint is already selected in the selection list
137137
std::string strPubcoin = item->text(COLUMN_PUBCOIN).toStdString();
138-
auto iter = std::find(listSelectedMints.begin(), listSelectedMints.end(), strPubcoin);
139-
bool fSelected = iter != listSelectedMints.end();
138+
bool fSelected = setSelectedMints.count(strPubcoin);
140139

141140
// set the checkbox to the proper state and add or remove the mint from the selection list
142141
if (item->checkState(COLUMN_CHECKBOX) == Qt::Checked) {
143142
if (fSelected) return;
144-
listSelectedMints.emplace_back(strPubcoin);
143+
setSelectedMints.insert(strPubcoin);
145144
} else {
146145
if (!fSelected) return;
147-
listSelectedMints.erase(iter);
146+
setSelectedMints.erase(strPubcoin);
148147
}
149148
updateLabels();
150149
}
@@ -154,27 +153,25 @@ void ZPivControlDialog::updateSelection(QTreeWidgetItem* item, int column)
154153
void ZPivControlDialog::updateLabels()
155154
{
156155
int64_t nAmount = 0;
157-
for (const CMintMeta mint : listMints) {
158-
if (count(listSelectedMints.begin(), listSelectedMints.end(), mint.hashPubcoin.GetHex())) {
156+
for (const CMintMeta& mint : setMints) {
157+
if (setSelectedMints.count(mint.hashPubcoin.GetHex()))
159158
nAmount += mint.denom;
160-
}
161159
}
162160

163161
//update this dialog's labels
164162
ui->labelZPiv_int->setText(QString::number(nAmount));
165-
ui->labelQuantity_int->setText(QString::number(listSelectedMints.size()));
163+
ui->labelQuantity_int->setText(QString::number(setSelectedMints.size()));
166164

167165
//update PrivacyDialog labels
168-
privacyDialog->setZPivControlLabels(nAmount, listSelectedMints.size());
166+
privacyDialog->setZPivControlLabels(nAmount, setSelectedMints.size());
169167
}
170168

171169
std::vector<CMintMeta> ZPivControlDialog::GetSelectedMints()
172170
{
173171
std::vector<CMintMeta> listReturn;
174-
for (const CMintMeta mint : listMints) {
175-
if (count(listSelectedMints.begin(), listSelectedMints.end(), mint.hashPubcoin.GetHex())) {
172+
for (const CMintMeta& mint : setMints) {
173+
if (setSelectedMints.count(mint.hashPubcoin.GetHex()))
176174
listReturn.emplace_back(mint);
177-
}
178175
}
179176

180177
return listReturn;
@@ -185,7 +182,7 @@ void ZPivControlDialog::ButtonAllClicked()
185182
{
186183
ui->treeWidget->blockSignals(true);
187184
Qt::CheckState state = Qt::Checked;
188-
for(int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) {
185+
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) {
189186
if(ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != Qt::Unchecked) {
190187
state = Qt::Unchecked;
191188
break;
@@ -195,11 +192,11 @@ void ZPivControlDialog::ButtonAllClicked()
195192
//much quicker to start from scratch than to have QT go through all the objects and update
196193
ui->treeWidget->clear();
197194

198-
if(state == Qt::Checked) {
199-
for(const CMintMeta mint : listMints)
200-
listSelectedMints.emplace_back(mint.hashPubcoin.GetHex());
195+
if (state == Qt::Checked) {
196+
for(const CMintMeta& mint : setMints)
197+
setSelectedMints.insert(mint.hashPubcoin.GetHex());
201198
} else {
202-
listSelectedMints.clear();
199+
setSelectedMints.clear();
203200
}
204201

205202
updateList();

src/qt/zpivcontroldialog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class ZPivControlDialog : public QDialog
2727

2828
void setModel(WalletModel* model);
2929

30-
static std::list<std::string> listSelectedMints;
31-
static std::list<CMintMeta> listMints;
30+
static std::set<std::string> setSelectedMints;
31+
static std::set<CMintMeta> setMints;
3232
static std::vector<CMintMeta> GetSelectedMints();
3333

3434
private:

src/rpcwallet.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,10 +2415,10 @@ UniValue listmintedzerocoins(const UniValue& params, bool fHelp)
24152415
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
24162416

24172417
CWalletDB walletdb(pwalletMain->strWalletFile);
2418-
list<CMintMeta> listPubCoin = pwalletMain->zpivTracker->ListMints(true, false, true);
2418+
set<CMintMeta> setMints = pwalletMain->zpivTracker->ListMints(true, false, true);
24192419

24202420
UniValue jsonList(UniValue::VARR);
2421-
for (const CMintMeta& meta : listPubCoin)
2421+
for (const CMintMeta& meta : setMints)
24222422
jsonList.push_back(meta.hashPubcoin.GetHex());
24232423

24242424
return jsonList;
@@ -2438,12 +2438,12 @@ UniValue listzerocoinamounts(const UniValue& params, bool fHelp)
24382438
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
24392439

24402440
CWalletDB walletdb(pwalletMain->strWalletFile);
2441-
list<CMintMeta> listMints = pwalletMain->zpivTracker->ListMints(true, true, true);
2441+
set<CMintMeta> setMints = pwalletMain->zpivTracker->ListMints(true, true, true);
24422442

24432443
std::map<libzerocoin::CoinDenomination, CAmount> spread;
24442444
for (const auto& denom : libzerocoin::zerocoinDenomList)
24452445
spread.insert(std::pair<libzerocoin::CoinDenomination, CAmount>(denom, 0));
2446-
for (auto& meta : listMints) spread.at(meta.denom)++;
2446+
for (auto& meta : setMints) spread.at(meta.denom)++;
24472447

24482448

24492449
UniValue jsonList(UniValue::VARR);
@@ -2684,8 +2684,8 @@ UniValue resetmintzerocoin(const UniValue& params, bool fHelp)
26842684

26852685
CWalletDB walletdb(pwalletMain->strWalletFile);
26862686
CzPIVTracker* zpivTracker = pwalletMain->zpivTracker;
2687-
list<CMintMeta> listMints = zpivTracker->ListMints(false, false, true);
2688-
vector<CMintMeta> vMintsToFind{ std::make_move_iterator(std::begin(listMints)), std::make_move_iterator(std::end(listMints)) };
2687+
set<CMintMeta> setMints = zpivTracker->ListMints(false, false, true);
2688+
vector<CMintMeta> vMintsToFind{ std::make_move_iterator(std::begin(setMints)), std::make_move_iterator(std::end(setMints)) };
26892689
vector<CMintMeta> vMintsMissing;
26902690
vector<CMintMeta> vMintsToUpdate;
26912691

@@ -2724,7 +2724,7 @@ UniValue resetspentzerocoin(const UniValue& params, bool fHelp)
27242724

27252725
CWalletDB walletdb(pwalletMain->strWalletFile);
27262726
CzPIVTracker* zpivTracker = pwalletMain->zpivTracker;
2727-
list<CMintMeta> listMints = zpivTracker->ListMints(false, false, false);
2727+
set<CMintMeta> setMints = zpivTracker->ListMints(false, false, false);
27282728
list<CZerocoinSpend> listSpends = walletdb.ListSpentCoins();
27292729
list<CZerocoinSpend> listUnconfirmedSpends;
27302730

@@ -2744,10 +2744,9 @@ UniValue resetspentzerocoin(const UniValue& params, bool fHelp)
27442744
UniValue objRet(UniValue::VOBJ);
27452745
UniValue arrRestored(UniValue::VARR);
27462746
for (CZerocoinSpend spend : listUnconfirmedSpends) {
2747-
for (auto& meta : listMints) {
2747+
for (auto& meta : setMints) {
27482748
if (meta.hashSerial == GetSerialHash(spend.GetSerial())) {
2749-
meta.isUsed = false;
2750-
zpivTracker->UpdateState(meta);
2749+
zpivTracker->SetPubcoinNotUsed(meta.hashPubcoin);
27512750
walletdb.EraseZerocoinSpendSerialEntry(spend.GetSerial());
27522751
RemoveSerialFromDB(spend.GetSerial());
27532752
UniValue obj(UniValue::VOBJ);
@@ -2833,10 +2832,10 @@ UniValue exportzerocoins(const UniValue& params, bool fHelp)
28332832
denomination = libzerocoin::IntToZerocoinDenomination(params[1].get_int());
28342833

28352834
CzPIVTracker* zpivTracker = pwalletMain->zpivTracker;
2836-
list<CMintMeta> listMints = zpivTracker->ListMints(!fIncludeSpent, false, false);
2835+
set<CMintMeta> setMints = zpivTracker->ListMints(!fIncludeSpent, false, false);
28372836

28382837
UniValue jsonList(UniValue::VARR);
2839-
for (const CMintMeta& meta : listMints) {
2838+
for (const CMintMeta& meta : setMints) {
28402839
if (denomination != libzerocoin::ZQ_ERROR && denomination != meta.denom)
28412840
continue;
28422841

0 commit comments

Comments
 (0)