Skip to content

Commit 10db9bf

Browse files
committed
[BUG] Fix ParseAndValidateZerocoinSpend(s)
considering that a tx can contain multiple spends
1 parent 59fd692 commit 10db9bf

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

src/consensus/zerocoin_verify.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,26 +250,27 @@ bool ContextualCheckZerocoinSpendNoSerialCheck(const CTransaction& tx, const lib
250250
return true;
251251
}
252252

253-
Optional<CoinSpendValues> ParseAndValidateZerocoinSpend(const Consensus::Params& consensus,
253+
Optional<CoinSpendValues> ParseAndValidateZerocoinSpends(const Consensus::Params& consensus,
254254
const CTransaction& tx, int chainHeight,
255255
CValidationState& state)
256256
{
257+
CoinSpendValues spends;
257258
for (const CTxIn& txIn : tx.vin) {
258259
bool isPublicSpend = txIn.IsZerocoinPublicSpend();
259260
bool isPrivZerocoinSpend = txIn.IsZerocoinSpend();
260261
if (!isPrivZerocoinSpend && !isPublicSpend)
261262
continue;
262263

263264
// Check enforcement
264-
if (!CheckPublicCoinSpendEnforced(chainHeight, isPublicSpend)){
265+
if (!CheckPublicCoinSpendEnforced(chainHeight, isPublicSpend)) {
265266
return nullopt;
266267
}
267268

268269
if (isPublicSpend) {
269270
libzerocoin::ZerocoinParams* params = consensus.Zerocoin_Params(false);
270271
PublicCoinSpend publicSpend(params);
271272
if (!ZPIVModule::ParseZerocoinPublicSpend(txIn, tx, state, publicSpend) ||
272-
!CheckPublicCoinSpendVersion(publicSpend.getCoinVersion())){
273+
!CheckPublicCoinSpendVersion(publicSpend.getCoinVersion())) {
273274
return nullopt;
274275
}
275276
//queue for db write after the 'justcheck' section has concluded
@@ -278,8 +279,7 @@ Optional<CoinSpendValues> ParseAndValidateZerocoinSpend(const Consensus::Params&
278279
tx.GetHash().GetHex()), REJECT_INVALID);
279280
return nullopt;
280281
}
281-
// return value
282-
return Optional<CoinSpendValues>(CoinSpendValues(publicSpend.getCoinSerialNumber(), publicSpend.getDenomination() * COIN));
282+
spends.emplace_back(publicSpend.getCoinSerialNumber(), publicSpend.getDenomination() * COIN);
283283
} else {
284284
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txIn);
285285
//queue for db write after the 'justcheck' section has concluded
@@ -288,8 +288,8 @@ Optional<CoinSpendValues> ParseAndValidateZerocoinSpend(const Consensus::Params&
288288
tx.GetHash().GetHex()), REJECT_INVALID);
289289
return nullopt;
290290
}
291-
return Optional<CoinSpendValues>(CoinSpendValues(spend.getCoinSerialNumber(), spend.getDenomination() * COIN));
291+
spends.emplace_back(spend.getCoinSerialNumber(), spend.getDenomination() * COIN);
292292
}
293293
}
294-
return nullopt;
294+
return spends.empty() ? nullopt : Optional<CoinSpendValues>(spends);
295295
}

src/consensus/zerocoin_verify.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ bool ContextualCheckZerocoinTx(const CTransactionRef& tx, CValidationState& stat
1919
bool ContextualCheckZerocoinSpend(const CTransaction& tx, const libzerocoin::CoinSpend* spend, int nHeight);
2020
bool ContextualCheckZerocoinSpendNoSerialCheck(const CTransaction& tx, const libzerocoin::CoinSpend* spend, int nHeight);
2121

22-
struct CoinSpendValues {
23-
public:
24-
explicit CoinSpendValues(const CBigNum& s, CAmount v) : serial(s), value(v) {}
22+
struct CoinSpendValue
23+
{
24+
explicit CoinSpendValue(const CBigNum& s, CAmount v) : serial(s), value(v) {}
2525
CBigNum serial;
2626
CAmount value;
2727
};
28+
typedef std::vector<CoinSpendValue> CoinSpendValues;
2829
// Returns nullopt if coin spend is invalid. Invalidity/DoS causes are treated inside the function.
29-
Optional<CoinSpendValues> ParseAndValidateZerocoinSpend(const Consensus::Params& consensus,
30+
Optional<CoinSpendValues> ParseAndValidateZerocoinSpends(const Consensus::Params& consensus,
3031
const CTransaction& tx, int chainHeight,
3132
CValidationState& state);
3233

src/validation.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,12 +1563,14 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
15631563
}
15641564

15651565
if (tx.HasZerocoinSpendInputs()) {
1566-
auto opCoinSpendValues = ParseAndValidateZerocoinSpend(consensus, tx, pindex->nHeight, state);
1566+
auto opCoinSpendValues = ParseAndValidateZerocoinSpends(consensus, tx, pindex->nHeight, state);
15671567
if (!opCoinSpendValues) {
1568-
return false; // Invalidity/DoS is handled by ParseAndValidateZerocoinSpend.
1568+
return false; // Invalidity/DoS is handled by ParseAndValidateZerocoinSpends.
1569+
}
1570+
for (const CoinSpendValue& s : *opCoinSpendValues) {
1571+
nValueIn += s.value;
1572+
vSpends.emplace_back(s.serial, tx.GetHash());
15691573
}
1570-
nValueIn += opCoinSpendValues->value;
1571-
vSpends.emplace_back(opCoinSpendValues->serial, tx.GetHash());
15721574
} else if (!tx.IsCoinBase()) {
15731575
if (!view.HaveInputs(tx)) {
15741576
return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-missingorspent");

0 commit comments

Comments
 (0)