Return useful error message on ATMP failure
This commit is contained in:
parent
f08222e882
commit
169bdabe14
4 changed files with 22 additions and 13 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
|
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
|
#include "consensus/validation.h"
|
||||||
#include "guiconstants.h"
|
#include "guiconstants.h"
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "paymentserver.h"
|
#include "paymentserver.h"
|
||||||
|
@ -328,7 +329,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
||||||
}
|
}
|
||||||
|
|
||||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||||
if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get()))
|
CValidationState state;
|
||||||
|
if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state))
|
||||||
return TransactionCommitFailed;
|
return TransactionCommitFailed;
|
||||||
|
|
||||||
CTransaction* t = (CTransaction*)newTx;
|
CTransaction* t = (CTransaction*)newTx;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "amount.h"
|
#include "amount.h"
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "chain.h"
|
#include "chain.h"
|
||||||
|
#include "consensus/validation.h"
|
||||||
#include "core_io.h"
|
#include "core_io.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
@ -365,8 +366,11 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr
|
||||||
strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
|
strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
}
|
}
|
||||||
if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get()))
|
CValidationState state;
|
||||||
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.");
|
if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
|
||||||
|
strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue sendtoaddress(const JSONRPCRequest& request)
|
UniValue sendtoaddress(const JSONRPCRequest& request)
|
||||||
|
@ -959,8 +963,11 @@ UniValue sendmany(const JSONRPCRequest& request)
|
||||||
bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
|
bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
|
||||||
if (!fCreated)
|
if (!fCreated)
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
||||||
if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get()))
|
CValidationState state;
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
|
if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
|
||||||
|
strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
||||||
|
}
|
||||||
|
|
||||||
return wtx.GetHash().GetHex();
|
return wtx.GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1463,7 +1463,8 @@ void CWallet::ReacceptWalletTransactions()
|
||||||
CWalletTx& wtx = *(item.second);
|
CWalletTx& wtx = *(item.second);
|
||||||
|
|
||||||
LOCK(mempool.cs);
|
LOCK(mempool.cs);
|
||||||
wtx.AcceptToMemoryPool(maxTxFee);
|
CValidationState state;
|
||||||
|
wtx.AcceptToMemoryPool(maxTxFee, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2474,7 +2475,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||||
/**
|
/**
|
||||||
* Call after CreateTransaction unless you want to abort
|
* Call after CreateTransaction unless you want to abort
|
||||||
*/
|
*/
|
||||||
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman)
|
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
@ -2502,9 +2503,9 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
|
||||||
if (fBroadcastTransactions)
|
if (fBroadcastTransactions)
|
||||||
{
|
{
|
||||||
// Broadcast
|
// Broadcast
|
||||||
if (!wtxNew.AcceptToMemoryPool(maxTxFee)) {
|
if (!wtxNew.AcceptToMemoryPool(maxTxFee, state)) {
|
||||||
// This must not fail. The transaction has already been signed and recorded.
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
wtxNew.RelayWalletTransaction(connman);
|
wtxNew.RelayWalletTransaction(connman);
|
||||||
|
@ -3649,8 +3650,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);
|
return ::AcceptToMemoryPool(mempool, state, *this, true, NULL, false, nAbsurdFee);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ public:
|
||||||
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
|
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
|
||||||
int GetBlocksToMaturity() const;
|
int GetBlocksToMaturity() const;
|
||||||
/** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */
|
/** 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 hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
||||||
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
||||||
void setAbandoned() { hashBlock = ABANDON_HASH; }
|
void setAbandoned() { hashBlock = ABANDON_HASH; }
|
||||||
|
@ -774,7 +774,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
|
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
|
||||||
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
|
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
|
||||||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman);
|
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state);
|
||||||
|
|
||||||
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
|
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
|
||||||
bool AddAccountingEntry(const CAccountingEntry&);
|
bool AddAccountingEntry(const CAccountingEntry&);
|
||||||
|
|
Loading…
Reference in a new issue