Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wallet: Remove return value from CommitTransaction #17154

Merged
merged 4 commits into from Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 3 additions & 10 deletions src/interfaces/wallet.cpp
Expand Up @@ -5,7 +5,6 @@
#include <interfaces/wallet.h>

#include <amount.h>
#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
#include <policy/feerate.h>
Expand Down Expand Up @@ -218,19 +217,13 @@ class WalletImpl : public Wallet
}
return tx;
}
bool commitTransaction(CTransactionRef tx,
void commitTransaction(CTransactionRef tx,
WalletValueMap value_map,
WalletOrderForm order_form,
std::string& reject_reason) override
WalletOrderForm order_form) override
{
auto locked_chain = m_wallet->chain().lock();
LOCK(m_wallet->cs_wallet);
CValidationState state;
if (!m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form), state)) {
reject_reason = state.GetRejectReason();
return false;
}
return true;
m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form));
}
bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); }
bool abandonTransaction(const uint256& txid) override
Expand Down
5 changes: 2 additions & 3 deletions src/interfaces/wallet.h
Expand Up @@ -141,10 +141,9 @@ class Wallet
std::string& fail_reason) = 0;

//! Commit transaction.
virtual bool commitTransaction(CTransactionRef tx,
virtual void commitTransaction(CTransactionRef tx,
WalletValueMap value_map,
WalletOrderForm order_form,
std::string& reject_reason) = 0;
WalletOrderForm order_form) = 0;

//! Return whether transaction can be abandoned.
virtual bool transactionCanBeAbandoned(const uint256& txid) = 0;
Expand Down
7 changes: 1 addition & 6 deletions src/qt/sendcoinsdialog.cpp
Expand Up @@ -558,8 +558,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
msgParams.second = CClientUIInterface::MSG_WARNING;

// This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
// WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
// all others are used only in WalletModel::prepareTransaction()
// All status values are used only in WalletModel::prepareTransaction()
switch(sendCoinsReturn.status)
{
case WalletModel::InvalidAddress:
Expand All @@ -581,10 +580,6 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
msgParams.first = tr("Transaction creation failed!");
msgParams.second = CClientUIInterface::MSG_ERROR;
break;
case WalletModel::TransactionCommitFailed:
msgParams.first = tr("The transaction was rejected with the following reason: %1").arg(sendCoinsReturn.reasonCommitFailed);
msgParams.second = CClientUIInterface::MSG_ERROR;
break;
case WalletModel::AbsurdFee:
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->wallet().getDefaultMaxTxFee()));
break;
Expand Down
4 changes: 1 addition & 3 deletions src/qt/walletmodel.cpp
Expand Up @@ -260,9 +260,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
}

auto& newTx = transaction.getWtx();
std::string rejectReason;
if (!wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm), rejectReason))
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(rejectReason));
wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm));

CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << *newTx;
Expand Down
1 change: 0 additions & 1 deletion src/qt/walletmodel.h
Expand Up @@ -139,7 +139,6 @@ class WalletModel : public QObject
AmountWithFeeExceedsBalance,
DuplicateAddress,
TransactionCreationFailed, // Error returned when wallet is still locked
TransactionCommitFailed,
AbsurdFee,
PaymentRequestExpired
};
Expand Down
16 changes: 2 additions & 14 deletions src/wallet/feebumper.cpp
Expand Up @@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <wallet/coincontrol.h>
#include <wallet/feebumper.h>
Expand Down Expand Up @@ -393,21 +392,10 @@ Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransacti
mapValue_t mapValue = oldWtx.mapValue;
mapValue["replaces_txid"] = oldWtx.GetHash().ToString();

CValidationState state;
if (!wallet.CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm, state)) {
// NOTE: CommitTransaction never returns false, so this should never happen.
errors.push_back(strprintf("The transaction was rejected: %s", FormatStateMessage(state)));
return Result::WALLET_ERROR;
}

bumped_txid = tx->GetHash();
if (state.IsInvalid()) {
// This can happen if the mempool rejected the transaction. Report
// what happened in the "errors" response.
errors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state)));
}
wallet.CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm);

// mark the original tx as bumped
bumped_txid = tx->GetHash();
if (!wallet.MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
// TODO: see if JSON-RPC has a standard way of returning a response
// along with an exception. It would be good to return information about
Expand Down
14 changes: 2 additions & 12 deletions src/wallet/rpcwallet.cpp
Expand Up @@ -4,7 +4,6 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <amount.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <init.h>
#include <interfaces/chain.h>
Expand Down Expand Up @@ -342,11 +341,7 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
CValidationState state;
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
return tx;
}

Expand Down Expand Up @@ -927,12 +922,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
bool fCreated = pwallet->CreateTransaction(*locked_chain, vecSend, tx, nFeeRequired, nChangePosRet, strFailReason, coin_control);
if (!fCreated)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
CValidationState state;
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
}

pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
return tx->GetHash().GetHex();
}

Expand Down
4 changes: 1 addition & 3 deletions src/wallet/test/wallet_tests.cpp
Expand Up @@ -8,7 +8,6 @@
#include <stdint.h>
#include <vector>

#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <policy/policy.h>
#include <rpc/server.h>
Expand Down Expand Up @@ -451,8 +450,7 @@ class ListCoinsTestingSetup : public TestChain100Setup
auto locked_chain = m_chain->lock();
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, fee, changePos, error, dummy));
}
CValidationState state;
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, state));
wallet->CommitTransaction(tx, {}, {});
CMutableTransaction blocktx;
{
LOCK(wallet->cs_wallet);
Expand Down
67 changes: 30 additions & 37 deletions src/wallet/wallet.cpp
Expand Up @@ -3286,51 +3286,44 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
return true;
}

/**
* Call after CreateTransaction unless you want to abort
*/
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CValidationState& state)
void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm)
{
{
auto locked_chain = chain().lock();
LOCK(cs_wallet);
auto locked_chain = chain().lock();
LOCK(cs_wallet);

CWalletTx wtxNew(this, std::move(tx));
wtxNew.mapValue = std::move(mapValue);
wtxNew.vOrderForm = std::move(orderForm);
wtxNew.fTimeReceivedIsTxTime = true;
wtxNew.fFromMe = true;
CWalletTx wtxNew(this, std::move(tx));
wtxNew.mapValue = std::move(mapValue);
wtxNew.vOrderForm = std::move(orderForm);
wtxNew.fTimeReceivedIsTxTime = true;
wtxNew.fFromMe = true;

WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */
{
WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */

// Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history.
AddToWallet(wtxNew);
// Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history.
AddToWallet(wtxNew);

// Notify that old coins are spent
for (const CTxIn& txin : wtxNew.tx->vin)
{
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
coin.BindWallet(this);
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
}
}
// Notify that old coins are spent
for (const CTxIn& txin : wtxNew.tx->vin) {
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
coin.BindWallet(this);
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
}

// Get the inserted-CWalletTx from mapWallet so that the
// fInMempool flag is cached properly
CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
// Get the inserted-CWalletTx from mapWallet so that the
// fInMempool flag is cached properly
CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());

if (fBroadcastTransactions)
{
std::string err_string;
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
}
}
if (!fBroadcastTransactions) {
// Don't submit tx to the mempool
return;
}

std::string err_string;
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
}
return true;
}

DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
Expand Down
11 changes: 10 additions & 1 deletion src/wallet/wallet.h
Expand Up @@ -1147,7 +1147,16 @@ class CWallet final : public FillableSigningProvider, private interfaces::Chain:
*/
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut,
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true);
bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CValidationState& state);
/**
* Submit the transaction to the node's mempool and then relay to peers.
* Should be called after CreateTransaction unless you want to abort
* broadcasting the transaction.
*
* @param tx[in] The transaction to be broadcast.
* @param mapValue[in] key-values to be set on the transaction.
* @param orderForm[in] BIP 70 / BIP 21 order form details to be set on the transaction.
*/
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);

bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
{
Expand Down