Skip to content

Commit

Permalink
[Wallet][zPIV] zc public spend parse crash in wallet startup fixed.
Browse files Browse the repository at this point in the history
  • Loading branch information
furszy committed Aug 1, 2019
1 parent 2269f10 commit 12c44ca
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 25 deletions.
15 changes: 2 additions & 13 deletions src/qt/transactionrecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,8 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet*
bool fZSpendFromMe = false;

if (wtx.HasZerocoinSpendInputs()) {
// a zerocoin spend that was created by this wallet
if (wtx.HasZerocoinPublicSpendInputs()) {
libzerocoin::ZerocoinParams* params = Params().Zerocoin_Params(false);
PublicCoinSpend publicSpend(params);
CValidationState state;
if (!ZPIVModule::ParseZerocoinPublicSpend(wtx.vin[0], wtx, state, publicSpend)){
throw std::runtime_error("Error parsing zc public spend");
}
fZSpendFromMe = wallet->IsMyZerocoinSpend(publicSpend.getCoinSerialNumber());
} else {
libzerocoin::CoinSpend zcspend = TxInToZerocoinSpend(wtx.vin[0]);
fZSpendFromMe = wallet->IsMyZerocoinSpend(zcspend.getCoinSerialNumber());
}
libzerocoin::CoinSpend zcspend = wtx.HasZerocoinPublicSpendInputs() ? ZPIVModule::parseCoinSpend(wtx.vin[0]) : TxInToZerocoinSpend(wtx.vin[0]);
fZSpendFromMe = wallet->IsMyZerocoinSpend(zcspend.getCoinSerialNumber());
}

if (wtx.IsCoinStake()) {
Expand Down
27 changes: 15 additions & 12 deletions src/zpiv/zpivmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ bool PublicCoinSpend::validate() const {
&params->coinCommitmentGroup, getCoinSerialNumber(), randomness);

if (commitment.getCommitmentValue() != pubCoin.getValue()){
return error("%s: commitments values are not equal\n", __func__);
return error("%s: commitments values are not equal", __func__);
}
// Now check that the signature validates with the serial
if (!HasValidSignature()) {
return error("%s: signature invalid\n", __func__);;
return error("%s: signature invalid", __func__);;
}
return true;
}
Expand All @@ -44,12 +44,12 @@ namespace ZPIVModule {
uint8_t nVersion = mint.GetVersion();
if (nVersion < libzerocoin::PrivateCoin::PUBKEY_VERSION) {
// No v1 serials accepted anymore.
return error("%s: failed to set zPIV privkey mint version=%d\n", __func__, nVersion);
return error("%s: failed to set zPIV privkey mint version=%d", __func__, nVersion);
}

CKey key;
if (!mint.GetKeyPair(key))
return error("%s: failed to set zPIV privkey mint version=%d\n", __func__, nVersion);
return error("%s: failed to set zPIV privkey mint version=%d", __func__, nVersion);

PublicCoinSpend spend(params, mint.GetSerialNumber(), mint.GetRandomness(), key.GetPubKey());
spend.setTxOutHash(hashTxOut);
Expand All @@ -74,16 +74,19 @@ namespace ZPIVModule {
return true;
}

bool parseCoinSpend(const CTxIn &in, const CTransaction &tx, const CTxOut &prevOut, PublicCoinSpend &publicCoinSpend) {
if (!in.IsZerocoinPublicSpend() || !prevOut.IsZerocoinMint())
return error("%s: invalid argument/s\n", __func__);

PublicCoinSpend parseCoinSpend(const CTxIn &in) {
std::vector<char, zero_after_free_allocator<char> > data;
data.insert(data.end(), in.scriptSig.begin() + 4, in.scriptSig.end());
CDataStream serializedCoinSpend(data, SER_NETWORK, PROTOCOL_VERSION);
libzerocoin::ZerocoinParams *params = Params().Zerocoin_Params(false);
PublicCoinSpend spend(params, serializedCoinSpend);
return PublicCoinSpend(params, serializedCoinSpend);
}

bool parseCoinSpend(const CTxIn &in, const CTransaction &tx, const CTxOut &prevOut, PublicCoinSpend &publicCoinSpend) {
if (!in.IsZerocoinPublicSpend() || !prevOut.IsZerocoinMint())
return error("%s: invalid argument/s", __func__);

PublicCoinSpend spend = parseCoinSpend(in);
spend.outputIndex = in.prevout.n;
spend.txHash = in.prevout.hash;
CMutableTransaction txNew(tx);
Expand All @@ -93,7 +96,7 @@ namespace ZPIVModule {
// Check prev out now
CValidationState state;
if (!TxOutToPublicCoin(prevOut, spend.pubCoin, state))
return error("%s: cannot get mint from output\n", __func__);
return error("%s: cannot get mint from output", __func__);

spend.setDenom(spend.pubCoin.getDenomination());
publicCoinSpend = spend;
Expand All @@ -107,7 +110,7 @@ namespace ZPIVModule {
}
if (libzerocoin::ZerocoinDenominationToAmount(
libzerocoin::IntToZerocoinDenomination(in.nSequence)) != prevOut.nValue) {
return error("PublicCoinSpend validateInput :: input nSequence different to prevout value\n");
return error("PublicCoinSpend validateInput :: input nSequence different to prevout value");
}

return publicSpend.validate();
Expand All @@ -117,7 +120,7 @@ namespace ZPIVModule {
{
CTxOut prevOut;
if(!GetOutput(txIn.prevout.hash, txIn.prevout.n ,state, prevOut)){
return state.DoS(100, error("%s: public zerocoin spend prev output not found, prevTx %s, index %d\n",
return state.DoS(100, error("%s: public zerocoin spend prev output not found, prevTx %s, index %d",
__func__, txIn.prevout.hash.GetHex(), txIn.prevout.n));
}
if (!ZPIVModule::parseCoinSpend(txIn, tx, prevOut, publicSpend)) {
Expand Down
1 change: 1 addition & 0 deletions src/zpiv/zpivmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class CValidationState;

namespace ZPIVModule {
bool createInput(CTxIn &in, CZerocoinMint& mint, uint256 hashTxOut);
PublicCoinSpend parseCoinSpend(const CTxIn &in);
bool parseCoinSpend(const CTxIn &in, const CTransaction& tx, const CTxOut &prevOut, PublicCoinSpend& publicCoinSpend);
bool validateInput(const CTxIn &in, const CTxOut &prevOut, const CTransaction& tx, PublicCoinSpend& ret);

Expand Down

0 comments on commit 12c44ca

Please sign in to comment.