diff --git a/src/rpc/server.h b/src/rpc/server.h index 78d4f546e32f5..fd4a118cba86b 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -179,7 +179,7 @@ extern std::string HelpExampleCli(std::string methodname, std::string args); extern std::string HelpExampleRpc(std::string methodname, std::string args); extern void EnsureWalletIsUnlocked(bool fAllowAnonOnly = false); -extern UniValue DoZpivSpend(const CAmount nAmount, bool fMintChange, bool fMinimizeChange, vector& vMintsSelected, std::string address_str); +extern UniValue DoZpivSpend(const CAmount nAmount, bool fMintChange, bool fMinimizeChange, vector& vMintsSelected, std::string address_str, bool isPublicSpend = true); extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpc/net.cpp extern UniValue getpeerinfo(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 50a8d3ce0fac1..03ef1408ff4b1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2853,6 +2853,7 @@ UniValue spendzerocoin(const UniValue& params, bool fHelp) "3. minimizechange (boolean, required) Try to minimize the returning change [false]\n" "4. \"address\" (string, optional, default=change) Send to specified address or to a new change address.\n" " If there is change then an address is required\n" + "5. ispublicspend (boolean, optional, default=true) create a public zc spend instead of use the old code (only for regression tests)" "\nResult:\n" "{\n" @@ -2892,10 +2893,15 @@ UniValue spendzerocoin(const UniValue& params, bool fHelp) bool fMintChange = params[1].get_bool(); // Mint change to zPIV bool fMinimizeChange = params[2].get_bool(); // Minimize change std::string address_str = params.size() > 3 ? params[3].get_str() : ""; + bool ispublicspend = params.size() > 4 ? params[3].get_bool() : true; vector vMintsSelected; - return DoZpivSpend(nAmount, fMintChange, fMinimizeChange, vMintsSelected, address_str); + if (!ispublicspend && Params().NetworkID() != CBaseChainParams::REGTEST) { + throw JSONRPCError(RPC_WALLET_ERROR, "zPIV old spend only available in regtest for tests purposes"); + } + + return DoZpivSpend(nAmount, fMintChange, fMinimizeChange, vMintsSelected, address_str, ispublicspend); } @@ -2993,7 +2999,7 @@ UniValue spendzerocoinmints(const UniValue& params, bool fHelp) } -extern UniValue DoZpivSpend(const CAmount nAmount, bool fMintChange, bool fMinimizeChange, vector& vMintsSelected, std::string address_str) +extern UniValue DoZpivSpend(const CAmount nAmount, bool fMintChange, bool fMinimizeChange, vector& vMintsSelected, std::string address_str, bool ispublicspend) { int64_t nTimeStart = GetTimeMillis(); CBitcoinAddress address = CBitcoinAddress(); // Optional sending address. Dummy initialization here. @@ -3005,9 +3011,9 @@ extern UniValue DoZpivSpend(const CAmount nAmount, bool fMintChange, bool fMinim address = CBitcoinAddress(address_str); if(!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address"); - fSuccess = pwalletMain->SpendZerocoin(nAmount, wtx, receipt, vMintsSelected, fMintChange, fMinimizeChange, &address); + fSuccess = pwalletMain->SpendZerocoin(nAmount, wtx, receipt, vMintsSelected, fMintChange, fMinimizeChange, &address, ispublicspend); } else // Spend to newly generated local address - fSuccess = pwalletMain->SpendZerocoin(nAmount, wtx, receipt, vMintsSelected, fMintChange, fMinimizeChange); + fSuccess = pwalletMain->SpendZerocoin(nAmount, wtx, receipt, vMintsSelected, fMintChange, fMinimizeChange, nullptr, ispublicspend); if (!fSuccess) throw JSONRPCError(RPC_WALLET_ERROR, receipt.GetStatusMessage()); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8b575d7a04ca9..fad19e337834d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4706,14 +4706,28 @@ bool CWallet::CheckCoinSpend(libzerocoin::CoinSpend& spend, libzerocoin::Accumul return true; } -bool CWallet::MintToTxIn(CZerocoinMint mint, const uint256& hashTxOut, CTxIn& newTxIn, CZerocoinSpendReceipt& receipt, libzerocoin::SpendType spendType, CBlockIndex* pindexCheckpoint) +bool CWallet::MintToTxIn( + CZerocoinMint mint, + const uint256& hashTxOut, + CTxIn& newTxIn, + CZerocoinSpendReceipt& receipt, + libzerocoin::SpendType spendType, + CBlockIndex* pindexCheckpoint, + bool publicCoinSpend) { std::map mapMints; mapMints.insert(std::make_pair(mint.GetValue(), mint)); std::vector vin; - if (MintsToInputVectorPublicSpend(mapMints, hashTxOut, vin, receipt, spendType, pindexCheckpoint)) { - newTxIn = vin[0]; - return true; + if (publicCoinSpend) { + if (MintsToInputVectorPublicSpend(mapMints, hashTxOut, vin, receipt, spendType, pindexCheckpoint)) { + newTxIn = vin[0]; + return true; + } + } else { + if (MintsToInputVector(mapMints, hashTxOut, vin, receipt, spendType, pindexCheckpoint)) { + newTxIn = vin[0]; + return true; + } } return false; @@ -4901,7 +4915,17 @@ bool CWallet::MintsToInputVectorPublicSpend(std::map& ma return true; } -bool CWallet::CreateZerocoinSpendTransaction(CAmount nValue, CWalletTx& wtxNew, CReserveKey& reserveKey, CZerocoinSpendReceipt& receipt, vector& vSelectedMints, vector& vNewMints, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* address) +bool CWallet::CreateZerocoinSpendTransaction( + CAmount nValue, + CWalletTx& wtxNew, + CReserveKey& reserveKey, + CZerocoinSpendReceipt& receipt, + vector& vSelectedMints, + vector& vNewMints, + bool fMintChange, + bool fMinimizeChange, + CBitcoinAddress* address, + bool isPublicSpend) { // Check available funds int nStatus = ZPIV_TRX_FUNDS_PROBLEMS; @@ -5095,8 +5119,15 @@ bool CWallet::CreateZerocoinSpendTransaction(CAmount nValue, CWalletTx& wtxNew, //add all of the mints to the transaction as inputs std::vector vin; - if (!MintsToInputVectorPublicSpend(mapSelectedMints, hashTxOut, vin, receipt, libzerocoin::SpendType::SPEND, pindexCheckpoint)) - return false; + if (isPublicSpend) { + if (!MintsToInputVectorPublicSpend(mapSelectedMints, hashTxOut, vin, receipt, + libzerocoin::SpendType::SPEND, pindexCheckpoint)) + return false; + } else { + if (!MintsToInputVector(mapSelectedMints, hashTxOut, vin, receipt, + libzerocoin::SpendType::SPEND, pindexCheckpoint)) + return false; + } txNew.vin = vin; // Limit size @@ -5402,7 +5433,7 @@ string CWallet::MintZerocoin(CAmount nValue, CWalletTx& wtxNew, vector& vMintsSelected, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* addressTo) +bool CWallet::SpendZerocoin(CAmount nAmount, CWalletTx& wtxNew, CZerocoinSpendReceipt& receipt, vector& vMintsSelected, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* addressTo, bool isPublicSpend) { // Default: assume something goes wrong. Depending on the problem this gets more specific below int nStatus = ZPIV_SPEND_ERROR; @@ -5414,7 +5445,7 @@ bool CWallet::SpendZerocoin(CAmount nAmount, CWalletTx& wtxNew, CZerocoinSpendRe CReserveKey reserveKey(this); vector vNewMints; - if (!CreateZerocoinSpendTransaction(nAmount, wtxNew, reserveKey, receipt, vMintsSelected, vNewMints, fMintChange, fMinimizeChange, addressTo)) { + if (!CreateZerocoinSpendTransaction(nAmount, wtxNew, reserveKey, receipt, vMintsSelected, vNewMints, fMintChange, fMinimizeChange, addressTo, isPublicSpend)) { return false; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 8cfc4d0334fe3..2e55f44e6373d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -209,9 +209,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface // Zerocoin additions bool CreateZerocoinMintTransaction(const CAmount nValue, CMutableTransaction& txNew, vector& vDMints, CReserveKey* reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl = NULL, const bool isZCSpendChange = false); - bool CreateZerocoinSpendTransaction(CAmount nValue, CWalletTx& wtxNew, CReserveKey& reserveKey, CZerocoinSpendReceipt& receipt, vector& vSelectedMints, vector& vNewMints, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* address = NULL); + bool CreateZerocoinSpendTransaction(CAmount nValue, CWalletTx& wtxNew, CReserveKey& reserveKey, CZerocoinSpendReceipt& receipt, vector& vSelectedMints, vector& vNewMints, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* address = NULL, bool isPublicSpend = true); bool CheckCoinSpend(libzerocoin::CoinSpend& spend, libzerocoin::Accumulator& accumulator, CZerocoinSpendReceipt& receipt); - bool MintToTxIn(CZerocoinMint mint, const uint256& hashTxOut, CTxIn& newTxIn, CZerocoinSpendReceipt& receipt, libzerocoin::SpendType spendType, CBlockIndex* pindexCheckpoint = nullptr); + bool MintToTxIn(CZerocoinMint mint, const uint256& hashTxOut, CTxIn& newTxIn, CZerocoinSpendReceipt& receipt, libzerocoin::SpendType spendType, CBlockIndex* pindexCheckpoint = nullptr, bool publicCoinSpend = true); bool MintsToInputVector(std::map& mapMintsSelected, const uint256& hashTxOut, std::vector& vin, CZerocoinSpendReceipt& receipt, libzerocoin::SpendType spendType, CBlockIndex* pindexCheckpoint = nullptr); @@ -221,7 +221,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface std::string MintZerocoinFromOutPoint(CAmount nValue, CWalletTx& wtxNew, std::vector& vDMints, const vector vOutpts); std::string MintZerocoin(CAmount nValue, CWalletTx& wtxNew, vector& vDMints, const CCoinControl* coinControl = NULL); - bool SpendZerocoin(CAmount nValue, CWalletTx& wtxNew, CZerocoinSpendReceipt& receipt, vector& vMintsSelected, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* addressTo = NULL); + bool SpendZerocoin(CAmount nValue, CWalletTx& wtxNew, CZerocoinSpendReceipt& receipt, vector& vMintsSelected, bool fMintChange, bool fMinimizeChange, CBitcoinAddress* addressTo = NULL, bool isPublicSpend = true); std::string ResetMintZerocoin(); std::string ResetSpentZerocoin(); void ReconsiderZerocoins(std::list& listMintsRestored, std::list& listDMintsRestored);