Skip to content

Commit

Permalink
[Zerocoin] remove CTransaction::IsZerocoinSpend and CTransaction::IsZ…
Browse files Browse the repository at this point in the history
…erocoinMint

- uniform IsZerocoinSpend/IsZerocoinMint CScript functions
- refactor CTxIn::IsZerocoinSpend / CTxOut::IsZerocoinMint encapsulating CScript methods
- add CTransaction methods: HasZerocoinMintOutputs / HasZerocoinSpendInputs
- refactor CTransaction::ContainsZerocoins from previous 'HasZerocoin' functions
- fix implementation of CTransaction::GetZerocoinMinted (from CTxOut)
- remove extra checks for empty scripts (as those are done in CScript functions)
  • Loading branch information
random-zebra committed May 8, 2019
1 parent ec7993e commit f14569f
Show file tree
Hide file tree
Showing 24 changed files with 209 additions and 188 deletions.
2 changes: 1 addition & 1 deletion src/blocksignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ bool CheckBlockSignature(const CBlock& block)
* UTXO: The public key that signs must match the public key associated with the first utxo of the coinstake tx.
*/
CPubKey pubkey;
bool fzPIVStake = block.vtx[1].IsZerocoinSpend();
bool fzPIVStake = block.vtx[1].vin[0].IsZerocoinSpend();
if (fzPIVStake) {
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(block.vtx[1].vin[0]);
pubkey = spend.getPubKey();
Expand Down
2 changes: 1 addition & 1 deletion src/bloom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
opcodetype opcode;
if (!txin.scriptSig.GetOp(pc, opcode, data))
break;
if (txin.scriptSig.IsZerocoinSpend()){
if (txin.IsZerocoinSpend()) {
CDataStream s(vector<unsigned char>(txin.scriptSig.begin() + 44, txin.scriptSig.end()),
SER_NETWORK, PROTOCOL_VERSION);

Expand Down
4 changes: 2 additions & 2 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const
return 0;

//todo are there any security precautions to take here?
if (tx.IsZerocoinSpend())
if (tx.HasZerocoinSpendInputs())
return tx.GetZerocoinSpent();

CAmount nResult = 0;
Expand All @@ -236,7 +236,7 @@ CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const

bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsCoinBase() && !tx.IsZerocoinSpend()) {
if (!tx.IsCoinBase() && !tx.HasZerocoinSpendInputs()) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
const COutPoint& prevout = tx.vin[i].prevout;
const CCoins* coins = AccessCoins(prevout.hash);
Expand Down
2 changes: 1 addition & 1 deletion src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class CCoins
//! check whether a particular output is still available
bool IsAvailable(unsigned int nPos) const
{
return (nPos < vout.size() && !vout[nPos].IsNull() && !vout[nPos].scriptPubKey.IsZerocoinMint());
return (nPos < vout.size() && !vout[nPos].IsNull() && !vout[nPos].IsZerocoinMint());
}

//! check whether the entire CCoins is spent
Expand Down
2 changes: 1 addition & 1 deletion src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake, std::uniqu
const CTxIn& txin = tx.vin[0];

//Construct the stakeinput object
if (tx.IsZerocoinSpend()) {
if (txin.IsZerocoinSpend()) {
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txin);
if (spend.getSpendType() != libzerocoin::SpendType::STAKE)
return error("%s: spend is using the wrong SpendType (%d)", __func__, (int)spend.getSpendType());
Expand Down
190 changes: 93 additions & 97 deletions src/main.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/masternode-payments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew)
nMasternode_Drift_Count = mnodeman.size() + Params().MasternodeCountDrift();
}

CAmount requiredMasternodePayment = GetMasternodePayment(nBlockHeight, nReward, nMasternode_Drift_Count, txNew.IsZerocoinSpend());
CAmount requiredMasternodePayment = GetMasternodePayment(nBlockHeight, nReward, nMasternode_Drift_Count, txNew.HasZerocoinSpendInputs());

//require at least 6 signatures
BOOST_FOREACH (CMasternodePayee& payee, vecPayments)
Expand Down
14 changes: 8 additions & 6 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
CAmount nTotalIn = 0;
bool fMissingInputs = false;
uint256 txid = tx.GetHash();
bool hasZerocoinSpends = tx.HasZerocoinSpendInputs();
if (hasZerocoinSpends)
nTotalIn = tx.GetZerocoinSpent();

for (const CTxIn& txin : tx.vin) {
//zerocoinspend has special vin
if (tx.IsZerocoinSpend()) {
nTotalIn = tx.GetZerocoinSpent();

if (hasZerocoinSpends) {
//Give a high priority to zerocoinspends to get into the next block
//Priority = (age^6+100000)*amount - gives higher priority to zpivs that have been in mempool long
//and higher priority to zpivs that are large in value
Expand Down Expand Up @@ -346,7 +348,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
double dPriorityDelta = 0;
CAmount nFeeDelta = 0;
mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
if (!tx.IsZerocoinSpend() && fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
if (!tx.HasZerocoinSpendInputs() && fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
continue;

// Prioritise by fee once past the priority size or we run out of high-priority
Expand All @@ -362,14 +364,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
continue;

// double check that there are no double spent zPIV spends in this block or tx
if (tx.IsZerocoinSpend()) {
if (tx.HasZerocoinSpendInputs()) {
int nHeightTx = 0;
if (IsTransactionInChain(tx.GetHash(), nHeightTx))
continue;

bool fDoubleSerial = false;
for (const CTxIn& txIn : tx.vin) {
if (txIn.scriptSig.IsZerocoinSpend()) {
if (txIn.IsZerocoinSpend()) {
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txIn);
bool fUseV1Params = libzerocoin::ExtractVersionFromSerial(spend.getCoinSerialNumber()) < libzerocoin::PrivateCoin::PUBKEY_VERSION;
if (!spend.HasValidSerial(Params().Zerocoin_Params(fUseV1Params)))
Expand Down
4 changes: 2 additions & 2 deletions src/primitives/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,5 @@ void CBlock::print() const

bool CBlock::IsZerocoinStake() const
{
return IsProofOfStake() && vtx[1].IsZerocoinSpend();
}
return IsProofOfStake() && vtx[1].HasZerocoinSpendInputs();
}
57 changes: 44 additions & 13 deletions src/primitives/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,18 @@ CTxIn::CTxIn(const libzerocoin::CoinSpend& spend, libzerocoin::CoinDenomination
nSequence = denom;
}

bool CTxIn::IsZerocoinSpend() const
{
return prevout.hash == 0 && scriptSig.IsZerocoinSpend();
}

std::string CTxIn::ToString() const
{
std::string str;
str += "CTxIn(";
str += prevout.ToString();
if (prevout.IsNull())
if(scriptSig.IsZerocoinSpend())
if(IsZerocoinSpend())
str += strprintf(", zerocoinspend %s...", HexStr(scriptSig).substr(0, 25));
else
str += strprintf(", coinbase %s", HexStr(scriptSig));
Expand Down Expand Up @@ -98,6 +103,19 @@ uint256 CTxOut::GetHash() const
return SerializeHash(*this);
}

bool CTxOut::IsZerocoinMint() const
{
return scriptPubKey.IsZerocoinMint();
}

CAmount CTxOut::GetZerocoinMinted() const
{
if (!IsZerocoinMint())
return CAmount(0);

return nValue;
}

std::string CTxOut::ToString() const
{
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
Expand Down Expand Up @@ -146,17 +164,35 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) {
return *this;
}

bool CTransaction::HasZerocoinSpendInputs() const
{
for (const CTxIn& txin: vin) {
if (txin.IsZerocoinSpend())
return true;
}
return false;
}

bool CTransaction::HasZerocoinMintOutputs() const
{
for(const CTxOut& txout : vout) {
if (txout.IsZerocoinMint())
return true;
}
return false;
}

bool CTransaction::IsCoinStake() const
{
if (vin.empty())
return false;

// ppcoin: the coin stake transaction is marked with the first output empty
bool fAllowNull = vin[0].scriptSig.IsZerocoinSpend();
bool fAllowNull = vin[0].IsZerocoinSpend();
if (vin[0].prevout.IsNull() && !fAllowNull)
return false;

return (vin.size() > 0 && vout.size() >= 2 && vout[0].IsEmpty());
return (vout.size() >= 2 && vout[0].IsEmpty());
}

CAmount CTransaction::GetValueOut() const
Expand All @@ -178,14 +214,12 @@ CAmount CTransaction::GetValueOut() const

CAmount CTransaction::GetZerocoinMinted() const
{
CAmount nValueOut = 0;
for (const CTxOut& txOut : vout) {
if(!txOut.scriptPubKey.IsZerocoinMint())
continue;

return txOut.nValue;
nValueOut += txOut.GetZerocoinMinted();
}

return CAmount(0);
return nValueOut;
}

bool CTransaction::UsesUTXO(const COutPoint out)
Expand All @@ -209,12 +243,9 @@ std::list<COutPoint> CTransaction::GetOutPoints() const

CAmount CTransaction::GetZerocoinSpent() const
{
if(!IsZerocoinSpend())
return 0;

CAmount nValueOut = 0;
for (const CTxIn& txin : vin) {
if(!txin.scriptSig.IsZerocoinSpend())
if(!txin.IsZerocoinSpend())
continue;

nValueOut += txin.nSequence * COIN;
Expand All @@ -227,7 +258,7 @@ int CTransaction::GetZerocoinMintCount() const
{
int nCount = 0;
for (const CTxOut& out : vout) {
if (out.scriptPubKey.IsZerocoinMint())
if (out.IsZerocoinMint())
nCount++;
}
return nCount;
Expand Down
24 changes: 7 additions & 17 deletions src/primitives/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class CTxIn
return (nSequence == std::numeric_limits<uint32_t>::max());
}

bool IsZerocoinSpend() const;

friend bool operator==(const CTxIn& a, const CTxIn& b)
{
return (a.prevout == b.prevout &&
Expand Down Expand Up @@ -173,10 +175,8 @@ class CTxOut
return (nValue < 3*minRelayTxFee.GetFee(nSize));
}

bool IsZerocoinMint() const
{
return !scriptPubKey.empty() && scriptPubKey.IsZerocoinMint();
}
bool IsZerocoinMint() const;
CAmount GetZerocoinMinted() const;

friend bool operator==(const CTxOut& a, const CTxOut& b)
{
Expand Down Expand Up @@ -259,23 +259,13 @@ class CTransaction
// Compute modified tx size for priority calculation (optionally given tx size)
unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;

bool IsZerocoinSpend() const
{
return (vin.size() > 0 && vin[0].prevout.hash == 0 && vin[0].scriptSig[0] == OP_ZEROCOINSPEND);
}
bool HasZerocoinSpendInputs() const;

bool IsZerocoinMint() const
{
for(const CTxOut& txout : vout) {
if (txout.scriptPubKey.IsZerocoinMint())
return true;
}
return false;
}
bool HasZerocoinMintOutputs() const;

bool ContainsZerocoins() const
{
return IsZerocoinSpend() || IsZerocoinMint();
return HasZerocoinSpendInputs() || HasZerocoinMintOutputs();
}

CAmount GetZerocoinMinted() const;
Expand Down
2 changes: 1 addition & 1 deletion src/qt/privacydialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ void PrivacyDialog::sendzPIV()

strStats += tr("address: ");
CTxDestination dest;
if(txout.scriptPubKey.IsZerocoinMint())
if(txout.IsZerocoinMint())
strStats += tr("zPIV Mint");
else if(ExtractDestination(txout.scriptPubKey, dest))
strStats += tr(CBitcoinAddress(dest).ToString().c_str());
Expand Down
12 changes: 6 additions & 6 deletions src/qt/transactionrecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet*
std::map<std::string, std::string> mapValue = wtx.mapValue;
bool fZSpendFromMe = false;

if (wtx.IsZerocoinSpend()) {
if (wtx.HasZerocoinSpendInputs()) {
// a zerocoin spend that was created by this wallet
libzerocoin::CoinSpend zcspend = TxInToZerocoinSpend(wtx.vin[0]);
fZSpendFromMe = wallet->IsMyZerocoinSpend(zcspend.getCoinSerialNumber());
Expand All @@ -51,10 +51,10 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet*
if (wtx.IsCoinStake()) {
TransactionRecord sub(hash, nTime);
CTxDestination address;
if (!wtx.IsZerocoinSpend() && !ExtractDestination(wtx.vout[1].scriptPubKey, address))
if (!wtx.HasZerocoinSpendInputs() && !ExtractDestination(wtx.vout[1].scriptPubKey, address))
return parts;

if (wtx.IsZerocoinSpend() && (fZSpendFromMe || wallet->zpivTracker->HasMintTx(hash))) {
if (wtx.HasZerocoinSpendInputs() && (fZSpendFromMe || wallet->zpivTracker->HasMintTx(hash))) {
//zPIV stake reward
sub.involvesWatchAddress = false;
sub.type = TransactionRecord::StakeZPIV;
Expand Down Expand Up @@ -85,7 +85,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet*
}

parts.append(sub);
} else if (wtx.IsZerocoinSpend()) {
} else if (wtx.HasZerocoinSpendInputs()) {
//zerocoin spend outputs
bool fFeeAssigned = false;
for (const CTxOut& txout : wtx.vout) {
Expand Down Expand Up @@ -245,7 +245,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet*
sub.credit = nCredit - nChange;
parts.append(sub);
parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
} else if (fAllFromMe || wtx.IsZerocoinMint()) {
} else if (fAllFromMe || wtx.HasZerocoinMintOutputs()) {
//
// Debit
//
Expand All @@ -267,7 +267,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet*
if (ExtractDestination(txout.scriptPubKey, address)) {
//This is most likely only going to happen when resyncing deterministic wallet without the knowledge of the
//private keys that the change was sent to. Do not display a "sent to" here.
if (wtx.IsZerocoinMint())
if (wtx.HasZerocoinMintOutputs())
continue;
// Sent to PIVX Address
sub.type = TransactionRecord::SendToAddress;
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ UniValue getfeeinfo(const UniValue& params, bool fHelp)
continue;

for (unsigned int j = 0; j < tx.vin.size(); j++) {
if (tx.vin[j].scriptSig.IsZerocoinSpend()) {
if (tx.vin[j].IsZerocoinSpend()) {
nValueIn += tx.vin[j].nSequence * COIN;
continue;
}
Expand Down Expand Up @@ -1446,7 +1446,7 @@ UniValue getserials(const UniValue& params, bool fHelp) {
}
// loop through each input
for (const CTxIn& txin : tx.vin) {
if (txin.scriptSig.IsZerocoinSpend()) {
if (txin.IsZerocoinSpend()) {
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txin);
std::string serial_str = spend.getCoinSerialNumber().ToString(16);
if (!fVerbose) {
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ UniValue getspentzerocoinamount(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter for transaction input");

const CTxIn& input = tx.vin[inputIndex];
if (!input.scriptSig.IsZerocoinSpend())
if (!input.IsZerocoinSpend())
return -1;

libzerocoin::CoinSpend spend = TxInToZerocoinSpend(input);
Expand Down
14 changes: 7 additions & 7 deletions src/script/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,19 +248,19 @@ bool CScript::IsPayToScriptHash() const
this->at(22) == OP_EQUAL);
}

bool CScript::StartsWithOpcode(const opcodetype opcode) const
{
return (!this->empty() && this->at(0) == opcode);
}

bool CScript::IsZerocoinMint() const
{
//fast test for Zerocoin Mint CScripts
return (this->size() > 0 &&
this->at(0) == OP_ZEROCOINMINT);
return StartsWithOpcode(OP_ZEROCOINMINT);
}

bool CScript::IsZerocoinSpend() const
{
if (this->empty())
return false;

return (this->at(0) == OP_ZEROCOINSPEND);
return StartsWithOpcode(OP_ZEROCOINSPEND);
}

bool CScript::IsPushOnly(const_iterator pc) const
Expand Down
Loading

0 comments on commit f14569f

Please sign in to comment.