diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 0036f7ed3..2ad9127bf 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -1226,8 +1226,9 @@ bool CPrivateSendClient::MakeCollateralAmounts(const CompactTallyItem& tallyItem LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- txid=%s\n", wtx.GetHash().GetHex()); // use the same nCachedLastSuccessBlock as for DS mixinx to prevent race - if(!pwalletMain->CommitTransaction(wtx, reservekeyChange, &connman)) { - LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- CommitTransaction failed!\n"); + CValidationState state; + if(!pwalletMain->CommitTransaction(wtx, reservekeyChange, &connman, state)) { + LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- CommitTransaction failed! Reason given: %s\n", state.GetRejectReason()); return false; } @@ -1353,8 +1354,9 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo keyHolderStorageDenom.KeepAll(); - if(!pwalletMain->CommitTransaction(wtx, reservekeyChange, &connman)) { - LogPrintf("CPrivateSendClient::CreateDenominated -- CommitTransaction failed!\n"); + CValidationState state; + if(!pwalletMain->CommitTransaction(wtx, reservekeyChange, &connman, state)) { + LogPrintf("CPrivateSendClient::CreateDenominated -- CommitTransaction failed! Reason given: %s\n", state.GetRejectReason()); return false; } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 3e192f511..aae33774e 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -6,6 +6,7 @@ #include "walletmodel.h" #include "addresstablemodel.h" +#include "consensus/validation.h" #include "guiconstants.h" #include "guiutil.h" #include "paymentserver.h" @@ -381,8 +382,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran } CReserveKey *keyChange = transaction.getPossibleKeyChange(); - - if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), recipients[0].fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)) + CValidationState state; + if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state, recipients[0].fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)) return TransactionCommitFailed; CTransaction* t = (CTransaction*)newTx; diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 20bc80ff9..4f00cbae0 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -5,6 +5,7 @@ //#define ENABLE_DASH_DEBUG #include "activemasternode.h" +#include "consensus/validation.h" #include "governance.h" #include "governance-vote.h" #include "governance-classes.h" @@ -178,7 +179,8 @@ UniValue gobject(const JSONRPCRequest& request) // -- make our change address CReserveKey reservekey(pwalletMain); // -- send the tx to the network - pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get(), NetMsgType::TX); + CValidationState state; + pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get(), state, NetMsgType::TX); DBG( cout << "gobject: prepare " << " strData = " << govobj.GetDataAsString() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 713cd4ceb..f32083492 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -7,6 +7,7 @@ #include "amount.h" #include "base58.h" #include "chain.h" +#include "consensus/validation.h" #include "core_io.h" #include "init.h" #include "instantx.h" @@ -371,8 +372,11 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); throw JSONRPCError(RPC_WALLET_ERROR, strError); } - if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of the wallet and coins were spent in the copy but not marked as spent here."); + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state, fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } } UniValue sendtoaddress(const JSONRPCRequest& request) @@ -1050,8 +1054,11 @@ UniValue sendmany(const JSONRPCRequest& request) NULL, true, fUsePrivateSend ? ONLY_DENOMINATED : ALL_COINS, fUseInstantSend); if (!fCreated) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); - if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(), fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)) - throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed"); + CValidationState state; + if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(), state, fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)) { + strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); + } return wtx.GetHash().GetHex(); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2e9ce8021..8e4339b9e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1832,7 +1832,8 @@ void CWallet::ReacceptWalletTransactions() CWalletTx& wtx = *(item.second); LOCK(mempool.cs); - wtx.AcceptToMemoryPool(maxTxFee); + CValidationState state; + wtx.AcceptToMemoryPool(maxTxFee, state); } } @@ -3613,7 +3614,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt /** * Call after CreateTransaction unless you want to abort */ -bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, std::string strCommand) +bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state, std::string strCommand) { { LOCK2(cs_main, cs_wallet); @@ -3646,9 +3647,9 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon if (fBroadcastTransactions) { // Broadcast - if (!wtxNew.AcceptToMemoryPool(maxTxFee)) { + if (!wtxNew.AcceptToMemoryPool(maxTxFee, state)) { // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); + LogPrintf("CommitTransaction(): Error: Transaction not valid, %s\n", state.GetRejectReason()); return false; } wtxNew.RelayWalletTransaction(connman, strCommand); @@ -5098,8 +5099,7 @@ int CMerkleTx::GetBlocksToMaturity() const } -bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee) +bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state) { - CValidationState state; return ::AcceptToMemoryPool(mempool, state, *this, true, NULL, false, nAbsurdFee); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 4194ddb00..e790fa48f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -254,7 +254,7 @@ public: bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; /** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */ - bool AcceptToMemoryPool(const CAmount& nAbsurdFee); + bool AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } void setAbandoned() { hashBlock = ABANDON_HASH; } @@ -895,7 +895,7 @@ public: */ bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true, AvailableCoinsType nCoinType=ALL_COINS, bool fUseInstantSend=false); - bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, std::string strCommand="tx"); + bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state, std::string strCommand="tx"); bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason); bool ConvertList(std::vector vecTxIn, std::vector& vecAmounts);