Skip to content

Commit

Permalink
Temporary development code. WIP.
Browse files Browse the repository at this point in the history
  • Loading branch information
presstab committed Nov 8, 2017
1 parent 138ad30 commit 9ed4253
Show file tree
Hide file tree
Showing 18 changed files with 103 additions and 30 deletions.
3 changes: 2 additions & 1 deletion src/accumulators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ bool CalculateAccumulatorCheckpoint(int nHeight, uint256& nCheckpoint)

//set the accumulators to last checkpoint value
AccumulatorMap mapAccumulators;
if(!mapAccumulators.Load(chainActive[nHeight - 1]->nAccumulatorCheckpoint)) {
if (!mapAccumulators.Load(chainActive[nHeight - 1]->nAccumulatorCheckpoint)) {
if (chainActive[nHeight - 1]->nAccumulatorCheckpoint == 0) {
//Before zerocoin is fully activated so set to init state
mapAccumulators.Reset();
Expand Down Expand Up @@ -157,6 +157,7 @@ bool CalculateAccumulatorCheckpoint(int nHeight, uint256& nCheckpoint)
LogPrint("zero","%s: failed to read block from disk\n", __func__);
return false;
}

std::list<PublicCoin> listPubcoins;
if(!BlockToPubcoinList(block, listPubcoins)) {
LogPrint("zero","%s: failed to get zerocoin mintlist from block %n\n", __func__, pindex->nHeight);
Expand Down
4 changes: 4 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ class CMainParams : public CChainParams
nDefaultSecurityLevel = 100; //full security level for accumulators
nZerocoinHeaderVersion = 4; //Block headers must be this version once zerocoin is active
nBudget_Fee_Confirmations = 6; // Number of confirmations for the finalization fee
nBlockEnforceSerialRange = 895400; //Enforce serial range starting this block
nBlockRecalculateAccumulators = 9896000; //Trigger a recalculation of accumulators

This comment has been minimized.

Copy link
@Fuzzbawls

Fuzzbawls Nov 9, 2017

Collaborator

@presstab is this really supposed to be 9896000? seems a bit high of a block number

This comment has been minimized.

Copy link
@presstab

presstab Nov 10, 2017

Author

Yes. This is so is wouldn't be triggered. I didn't want to go through and delete a bunch of code that was in progress, so I just set this to a very high block.

nBlockFirstFraudulent = 891737; //First block that bad serials emerged
nBlockLastGoodCheckpoint = 891730; //Last valid accumulator checkpoint
}

const Checkpoints::CCheckpointData& Checkpoints() const
Expand Down
8 changes: 8 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ class CChainParams
int ModifierUpgradeBlock() const { return nModifierUpdateBlock; }
int LAST_POW_BLOCK() const { return nLastPOWBlock; }
int Zerocoin_StartHeight() const { return nZerocoinStartHeight; }
int Zerocoin_Block_EnforceSerialRange() const { return nBlockEnforceSerialRange; }
int Zerocoin_Block_RecalculateAccumulators() const { return nBlockRecalculateAccumulators; }
int Zerocoin_Block_FirstFraudulent() const { return nBlockFirstFraudulent; }
int Zerocoin_Block_LastGoodCheckpoint() const { return nBlockLastGoodCheckpoint; }

protected:
CChainParams() {}
Expand Down Expand Up @@ -166,6 +170,10 @@ class CChainParams
int nZerocoinHeaderVersion;
int64_t nBudget_Fee_Confirmations;
int nZerocoinStartHeight;
int nBlockEnforceSerialRange;
int nBlockRecalculateAccumulators;
int nBlockFirstFraudulent;
int nBlockLastGoodCheckpoint;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ class CCoins
//! check whether a particular output is still available
bool IsAvailable(unsigned int nPos) const
{
return (nPos < vout.size() && !vout[nPos].IsNull());
return (nPos < vout.size() && !vout[nPos].IsNull() && !vout[nPos].scriptPubKey.IsZerocoinMint());
}

//! check whether the entire CCoins is spent
Expand Down
5 changes: 5 additions & 0 deletions src/libzerocoin/CoinSpend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ const uint256 CoinSpend::signatureHash() const
return h.GetHash();
}

bool CoinSpend::HasValidSerial(ZerocoinParams* params) const
{
return coinSerialNumber > 0 && coinSerialNumber < params->coinCommitmentGroup.groupOrder;
}

} /* namespace libzerocoin */
4 changes: 4 additions & 0 deletions src/libzerocoin/CoinSpend.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,12 @@ class CoinSpend
* @return the txout hash
*/
uint256 getTxOutHash() const { return ptxHash; }
CBigNum getAccCommitment() const { return accCommitmentToCoinValue; }
CBigNum getSerialComm() const { return serialCommitmentToCoinValue; }

bool Verify(const Accumulator& a) const;
bool HasValidSerial(ZerocoinParams* params) const;

ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
Expand Down
34 changes: 28 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ bool CheckZerocoinSpend(const CTransaction tx, bool fVerifySignature, CValidatio
return state.DoS(100, error("CheckZerocoinSpend(): Zerocoin transactions are not allowed yet"));

//max needed non-mint outputs should be 2 - one for redemption address and a possible 2nd for change
if (tx.vout.size() > 2){
if (tx.vout.size() > 2) {
int outs = 0;
for (const CTxOut out : tx.vout) {
if (out.IsZerocoinMint())
Expand Down Expand Up @@ -1402,7 +1402,7 @@ bool CheckZerocoinSpend(const CTransaction tx, bool fVerifySignature, CValidatio
return fValidated;
}

bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, CValidationState& state)
bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fRejectBadUTXO, CValidationState& state)
{
// Basic checks that don't depend on any context
if (tx.vin.empty())
Expand Down Expand Up @@ -1468,7 +1468,7 @@ bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, CValidationS
// Check for duplicate inputs
set<COutPoint> vInOutPoints;
set<CBigNum> vZerocoinSpendSerials;
BOOST_FOREACH (const CTxIn& txin, tx.vin) {
for (const CTxIn& txin : tx.vin) {
if (vInOutPoints.count(txin.prevout))
return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
REJECT_INVALID, "bad-txns-inputs-duplicate");
Expand Down Expand Up @@ -1560,7 +1560,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
if (pfMissingInputs)
*pfMissingInputs = false;

if (!CheckTransaction(tx, GetAdjustedTime() > GetSporkValue(SPORK_17_ENABLE_ZEROCOIN), state))
//Temporarily disable zerocoin
if (tx.ContainsZerocoins())
return state.DoS(100, error("AcceptToMemoryPool : Zerocoin transactions temporarily disabled"));

if (!CheckTransaction(tx, GetAdjustedTime() > GetSporkValue(SPORK_17_ENABLE_ZEROCOIN), true, state))
return state.DoS(100, error("AcceptToMemoryPool: : CheckTransaction failed"), REJECT_INVALID, "bad-tx");

// Coinbase is only valid in a block, not as a loose transaction
Expand Down Expand Up @@ -1634,6 +1638,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
if (IsSerialInBlockchain(spend.getCoinSerialNumber(), nHeightTx))
return state.Invalid(error("%s : zPiv spend with serial %s is already in block %d\n",
__func__, spend.getCoinSerialNumber().GetHex(), nHeightTx));

//Is serial in the acceptable range
if (!spend.HasValidSerial(Params().Zerocoin_Params()))
return state.Invalid(error("%s : zPiv spend with serial %s from tx %s is not in valid range\n",
__func__, spend.getCoinSerialNumber().GetHex(), tx.GetHash().GetHex()));
}
} else {
LOCK(pool.cs);
Expand Down Expand Up @@ -1780,7 +1789,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact
if (pfMissingInputs)
*pfMissingInputs = false;

if (!CheckTransaction(tx, GetAdjustedTime() > GetSporkValue(SPORK_17_ENABLE_ZEROCOIN), state))
if (!CheckTransaction(tx, GetAdjustedTime() > GetSporkValue(SPORK_17_ENABLE_ZEROCOIN), true, state))
return error("AcceptableInputs: : CheckTransaction failed");

// Coinbase is only valid in a block, not as a loose transaction
Expand Down Expand Up @@ -2930,6 +2939,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return state.DoS(100, error("ConnectBlock() : too many sigops"),
REJECT_INVALID, "bad-blk-sigops");

//Temporarily shut off zerocoin transactions
if (pindex->nHeight >= Params().Zerocoin_Block_EnforceSerialRange() && tx.ContainsZerocoins())
return state.DoS(100, error("ConnectBlock() : zerocoin transactions are disabled"));

if (tx.IsZerocoinSpend()) {
int nHeightTx = 0;
if (IsTransactionInChain(tx.GetHash(), nHeightTx)) {
Expand All @@ -2947,6 +2960,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CoinSpend spend = TxInToZerocoinSpend(txIn);
int nHeightTx = 0;

// Make sure that the serial number is in valid range
if (!spend.HasValidSerial(Params().Zerocoin_Params())) {
string strError = strprintf("%s : txid=%s in block %d contains invalid serial %s\n", __func__, tx.GetHash().GetHex(), pindex->nHeight, spend.getCoinSerialNumber());
if (pindex->nHeight >= Params().Zerocoin_Block_EnforceSerialRange())
return state.DoS(100, error(strError.c_str()));
strError = "NOT ENFORCING : " + strError;
LogPrintf(strError.c_str());
}

uint256 hashTxFromDB;
if (zerocoinDB->ReadCoinSpend(spend.getCoinSerialNumber(), hashTxFromDB)) {
if(IsSerialInBlockchain(spend.getCoinSerialNumber(), nHeightTx)) {
Expand Down Expand Up @@ -4057,7 +4079,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
bool fZerocoinActive = block.nTime > GetSporkValue(SPORK_17_ENABLE_ZEROCOIN);
vector<CBigNum> vBlockSerials;
for (const CTransaction& tx : block.vtx) {
if (!CheckTransaction(tx, fZerocoinActive, state))
if (!CheckTransaction(tx, fZerocoinActive, chainActive.Height() + 1 >= Params().Zerocoin_Block_EnforceSerialRange(), state))
return error("CheckBlock() : CheckTransaction failed");

// double check that there are no double spent zPiv spends in this block
Expand Down
3 changes: 2 additions & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsVi
void UpdateCoins(const CTransaction& tx, CValidationState& state, CCoinsViewCache& inputs, CTxUndo& txundo, int nHeight);

/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, CValidationState& state);
bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fRejectBadUTXO, CValidationState& state);
bool CheckZerocoinMint(const uint256& txHash, const CTxOut& txout, CValidationState& state, bool fCheckOnly = false);
bool CheckZerocoinSpend(const CTransaction tx, bool fVerifySignature, CValidationState& state);
libzerocoin::CoinSpend TxInToZerocoinSpend(const CTxIn& txin);
Expand All @@ -368,6 +368,7 @@ int GetZerocoinStartHeight();
bool IsTransactionInChain(uint256 txId, int& nHeightTx);
bool IsBlockHashInChain(const uint256& hashBlock);


/**
* Check if transaction will be final in the next block to be created.
*
Expand Down
4 changes: 3 additions & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin();
mi != mempool.mapTx.end(); ++mi) {
const CTransaction& tx = mi->second.GetTx();
if (tx.IsCoinBase() || tx.IsCoinStake() || !IsFinalTx(tx, nHeight))
if (tx.IsCoinBase() || tx.IsCoinStake() || !IsFinalTx(tx, nHeight) || tx.ContainsZerocoins())
continue;

COrphan* porphan = NULL;
Expand Down Expand Up @@ -316,6 +316,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
for (const CTxIn txIn : tx.vin) {
if (txIn.scriptSig.IsZerocoinSpend()) {
libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txIn);
if (!spend.HasValidSerial(Params().Zerocoin_Params()))
fDoubleSerial = true;
if (count(vBlockSerials.begin(), vBlockSerials.end(), spend.getCoinSerialNumber()))
fDoubleSerial = true;
if (count(vTxSerials.begin(), vTxSerials.end(), spend.getCoinSerialNumber()))
Expand Down
20 changes: 20 additions & 0 deletions src/primitives/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "main.h"
#include "tinyformat.h"
#include "utilstrencodings.h"
#include "transaction.h"

#include <boost/foreach.hpp>

Expand Down Expand Up @@ -161,6 +162,25 @@ CAmount CTransaction::GetZerocoinMinted() const
return CAmount(0);
}

bool CTransaction::UsesUTXO(const COutPoint out)
{
for (const CTxIn in : vin) {
if (in.prevout == out)
return true;
}

return false;
}

std::list<COutPoint> CTransaction::GetOutPoints() const
{
std::list<COutPoint> listOutPoints;
uint256 txHash = GetHash();
for (unsigned int i = 0; i < vout.size(); i++)
listOutPoints.emplace_back(COutPoint(txHash, i));
return listOutPoints;
}

CAmount CTransaction::GetZerocoinSpent() const
{
if(!IsZerocoinSpend())
Expand Down
5 changes: 5 additions & 0 deletions src/primitives/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "serialize.h"
#include "uint256.h"

#include <list>

class CTransaction;

/** An outpoint - a combination of a transaction hash and an index n into its vout */
Expand Down Expand Up @@ -278,6 +280,9 @@ class CTransaction
CAmount GetZerocoinSpent() const;
int GetZerocoinMintCount() const;

bool UsesUTXO(const COutPoint out);
std::list<COutPoint> GetOutPoints() const;

bool IsCoinBase() const
{
return (vin.size() == 1 && vin[0].prevout.IsNull() && !ContainsZerocoins());
Expand Down
16 changes: 8 additions & 8 deletions src/qt/privacydialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ void PrivacyDialog::on_pushButtonMintzPIV_clicked()
if (!walletModel || !walletModel->getOptionsModel())
return;

if (GetAdjustedTime() < GetSporkValue(SPORK_17_ENABLE_ZEROCOIN)) {
QMessageBox::information(this, tr("Mint Zerocoin"), tr("Zerocoin functionality is not enabled on the PIVX network yet."), QMessageBox::Ok, QMessageBox::Ok);
return;
}

QMessageBox::information(this, tr("Mint Zerocoin"), tr("Zerocoin functionality is not enabled on the PIVX network."), QMessageBox::Ok, QMessageBox::Ok);
return;


// Reset message text
ui->TEMintStatus->setPlainText(tr("Mint Status: Okay"));
Expand Down Expand Up @@ -247,10 +247,10 @@ void PrivacyDialog::on_pushButtonSpendzPIV_clicked()
if (!walletModel || !walletModel->getOptionsModel() || !pwalletMain)
return;

if (GetAdjustedTime() < GetSporkValue(SPORK_17_ENABLE_ZEROCOIN)) {
QMessageBox::information(this, tr("Spend Zerocoin"), tr("Zerocoin functionality is not enabled on the PIVX network yet."), QMessageBox::Ok, QMessageBox::Ok);
return;
}

QMessageBox::information(this, tr("Spend Zerocoin"), tr("Zerocoin functionality is not enabled on the PIVX network."), QMessageBox::Ok, QMessageBox::Ok);
return;


// Request unlock if wallet was locked or unlocked for mixing:
WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus();
Expand Down
3 changes: 3 additions & 0 deletions src/rpcmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ Value getinfo(const Array& params, bool fHelp)
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
obj.push_back(Pair("moneysupply",ValueFromAmount(chainActive.Tip()->nMoneySupply)));
obj.push_back(Pair("zerocoinsupply",ValueFromAmount(chainActive.Tip()->GetZerocoinSupply())));
for (auto denom : libzerocoin::zerocoinDenomList) {
obj.push_back(Pair(to_string(denom), ValueFromAmount(chainActive.Tip()->mapZerocoinSupply.at(denom) * (denom*COIN))));
}

#ifdef ENABLE_WALLET
if (pwalletMain) {
Expand Down
6 changes: 2 additions & 4 deletions src/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2405,8 +2405,7 @@ Value mintzerocoin(const Array& params, bool fHelp)

int64_t nTime = GetTimeMillis();

if (GetAdjustedTime() < GetSporkValue(SPORK_17_ENABLE_ZEROCOIN))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Zerocoin functionality is not enabled on the PIVX network yet.");
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Zerocoin functionality is not enabled on the PIVX network.");

if (pwalletMain->IsLocked())
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
Expand Down Expand Up @@ -2451,8 +2450,7 @@ Value spendzerocoin(const Array& params, bool fHelp)
"an address is required"
+ HelpRequiringPassphrase());

if (GetAdjustedTime() < GetSporkValue(SPORK_17_ENABLE_ZEROCOIN))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Zerocoin functionality is not enabled on the PIVX network yet.");
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Zerocoin functionality is not enabled on the PIVX network.");

int64_t nTimeStart = GetTimeMillis();
if (pwalletMain->IsLocked())
Expand Down
2 changes: 1 addition & 1 deletion src/test/sighash_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
stream >> tx;

CValidationState state;
BOOST_CHECK_MESSAGE(CheckTransaction(tx, false, state), strTest);
BOOST_CHECK_MESSAGE(CheckTransaction(tx, false, false, state), strTest);
BOOST_CHECK(state.IsValid());

std::vector<unsigned char> raw = ParseHex(raw_script);
Expand Down
8 changes: 4 additions & 4 deletions src/test/transaction_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
stream >> tx;

CValidationState state;
BOOST_CHECK_MESSAGE(CheckTransaction(tx, false, state), strTest);
BOOST_CHECK_MESSAGE(CheckTransaction(tx, false, false, state), strTest);
BOOST_CHECK(state.IsValid());

for (unsigned int i = 0; i < tx.vin.size(); i++)
Expand Down Expand Up @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
stream >> tx;

CValidationState state;
fValid = CheckTransaction(tx, false, state) && state.IsValid();
fValid = CheckTransaction(tx, false, false, state) && state.IsValid();

for (unsigned int i = 0; i < tx.vin.size() && fValid; i++)
{
Expand Down Expand Up @@ -237,11 +237,11 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests)
CMutableTransaction tx;
stream >> tx;
CValidationState state;
BOOST_CHECK_MESSAGE(CheckTransaction(tx, false, state) && state.IsValid(), "Simple deserialized transaction should be valid.");
BOOST_CHECK_MESSAGE(CheckTransaction(tx, false, false, state) && state.IsValid(), "Simple deserialized transaction should be valid.");

// Check that duplicate txins fail
tx.vin.push_back(tx.vin[0]);
BOOST_CHECK_MESSAGE(!CheckTransaction(tx, false, state) || !state.IsValid(), "Transaction with duplicate txins should be invalid.");
BOOST_CHECK_MESSAGE(!CheckTransaction(tx, false, false, state) || !state.IsValid(), "Transaction with duplicate txins should be invalid.");
}

//
Expand Down
4 changes: 2 additions & 2 deletions src/txdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ bool CZerocoinDB::EraseCoinSpend(const CBigNum& bnSerial)

bool CZerocoinDB::WriteAccumulatorValue(const uint32_t& nChecksum, const CBigNum& bnValue)
{
LogPrint("zero","*** %s checksum:%d val:%s\n", __func__, nChecksum, bnValue.GetHex());
LogPrint("zero","%s : checksum:%d val:%s\n", __func__, nChecksum, bnValue.GetHex());
return Write(make_pair('a', nChecksum), bnValue);
}

Expand All @@ -359,6 +359,6 @@ bool CZerocoinDB::ReadAccumulatorValue(const uint32_t& nChecksum, CBigNum& bnVal

bool CZerocoinDB::EraseAccumulatorValue(const uint32_t& nChecksum)
{
LogPrintf("*** %s checksum:%d\n", __func__, nChecksum);
LogPrint("zero", "%s : checksum:%d\n", __func__, nChecksum);
return Erase(make_pair('a', nChecksum));
}
2 changes: 1 addition & 1 deletion src/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CW
ssValue >> wtx;
CValidationState state;
// false because there is no reason to go through the zerocoin checks for our own wallet
if (!(CheckTransaction(wtx, false, state) && (wtx.GetHash() == hash) && state.IsValid()))
if (!(CheckTransaction(wtx, false, false, state) && (wtx.GetHash() == hash) && state.IsValid()))
return false;

// Undo serialize changes in 31600
Expand Down

0 comments on commit 9ed4253

Please sign in to comment.