mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-13 11:25:02 -05:00
Merge #17154: wallet: Remove return value from CommitTransaction
9e95931865
[wallet] Remove `state` argument from CWallet::CommitTransaction (John Newbery)d1734f9a3b
[wallet] Remove return value from CommitTransaction() (John Newbery)b6f486a02b
[wallet] Add doxygen comment to CWallet::CommitTransaction() (John Newbery)8bba91b22d
[wallet] Fix whitespace in CWallet::CommitTransaction() (John Newbery) Pull request description: `CommitTransaction()` returns a bool to indicate success, but since commitb3a7410
(#9302) it only returns true, even if the transaction was not successfully broadcast. This commit changes CommitTransaction() to return void. All dead code in `if (!CommitTransaction())` branches has been removed. Two additional commits fix up the idiosyncratic whitespace in `CommitTransaction` and add a doxygen comment for the function. ACKs for top commit: laanwj: ACK9e95931865
Tree-SHA512: a55a2c20369a45222fc0e02d0891495655a926e71c4f52cb72624768dd7b9c1dca716ea67d38420afb90f40c6e0fd448caa60c18fd693bb10ecb110b641820e6
This commit is contained in:
commit
8a191148db
10 changed files with 54 additions and 92 deletions
|
@ -5,7 +5,6 @@
|
||||||
#include <interfaces/wallet.h>
|
#include <interfaces/wallet.h>
|
||||||
|
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <consensus/validation.h>
|
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <interfaces/handler.h>
|
#include <interfaces/handler.h>
|
||||||
#include <policy/fees.h>
|
#include <policy/fees.h>
|
||||||
|
@ -216,19 +215,13 @@ public:
|
||||||
}
|
}
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
bool commitTransaction(CTransactionRef tx,
|
void commitTransaction(CTransactionRef tx,
|
||||||
WalletValueMap value_map,
|
WalletValueMap value_map,
|
||||||
WalletOrderForm order_form,
|
WalletOrderForm order_form) override
|
||||||
std::string& reject_reason) override
|
|
||||||
{
|
{
|
||||||
auto locked_chain = m_wallet->chain().lock();
|
auto locked_chain = m_wallet->chain().lock();
|
||||||
LOCK(m_wallet->cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
CValidationState state;
|
m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form));
|
||||||
if (!m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form), state)) {
|
|
||||||
reject_reason = state.GetRejectReason();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); }
|
bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); }
|
||||||
bool abandonTransaction(const uint256& txid) override
|
bool abandonTransaction(const uint256& txid) override
|
||||||
|
|
|
@ -141,10 +141,9 @@ public:
|
||||||
std::string& fail_reason) = 0;
|
std::string& fail_reason) = 0;
|
||||||
|
|
||||||
//! Commit transaction.
|
//! Commit transaction.
|
||||||
virtual bool commitTransaction(CTransactionRef tx,
|
virtual void commitTransaction(CTransactionRef tx,
|
||||||
WalletValueMap value_map,
|
WalletValueMap value_map,
|
||||||
WalletOrderForm order_form,
|
WalletOrderForm order_form) = 0;
|
||||||
std::string& reject_reason) = 0;
|
|
||||||
|
|
||||||
//! Return whether transaction can be abandoned.
|
//! Return whether transaction can be abandoned.
|
||||||
virtual bool transactionCanBeAbandoned(const uint256& txid) = 0;
|
virtual bool transactionCanBeAbandoned(const uint256& txid) = 0;
|
||||||
|
|
|
@ -558,8 +558,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
|
||||||
msgParams.second = CClientUIInterface::MSG_WARNING;
|
msgParams.second = CClientUIInterface::MSG_WARNING;
|
||||||
|
|
||||||
// This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
|
// This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
|
||||||
// WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
|
// All status values are used only in WalletModel::prepareTransaction()
|
||||||
// all others are used only in WalletModel::prepareTransaction()
|
|
||||||
switch(sendCoinsReturn.status)
|
switch(sendCoinsReturn.status)
|
||||||
{
|
{
|
||||||
case WalletModel::InvalidAddress:
|
case WalletModel::InvalidAddress:
|
||||||
|
@ -581,10 +580,6 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
|
||||||
msgParams.first = tr("Transaction creation failed!");
|
msgParams.first = tr("Transaction creation failed!");
|
||||||
msgParams.second = CClientUIInterface::MSG_ERROR;
|
msgParams.second = CClientUIInterface::MSG_ERROR;
|
||||||
break;
|
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:
|
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()));
|
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->wallet().getDefaultMaxTxFee()));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -260,9 +260,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& newTx = transaction.getWtx();
|
auto& newTx = transaction.getWtx();
|
||||||
std::string rejectReason;
|
wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm));
|
||||||
if (!wallet().commitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm), rejectReason))
|
|
||||||
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(rejectReason));
|
|
||||||
|
|
||||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ssTx << *newTx;
|
ssTx << *newTx;
|
||||||
|
|
|
@ -138,7 +138,6 @@ public:
|
||||||
AmountWithFeeExceedsBalance,
|
AmountWithFeeExceedsBalance,
|
||||||
DuplicateAddress,
|
DuplicateAddress,
|
||||||
TransactionCreationFailed, // Error returned when wallet is still locked
|
TransactionCreationFailed, // Error returned when wallet is still locked
|
||||||
TransactionCommitFailed,
|
|
||||||
AbsurdFee,
|
AbsurdFee,
|
||||||
PaymentRequestExpired
|
PaymentRequestExpired
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <consensus/validation.h>
|
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <wallet/coincontrol.h>
|
#include <wallet/coincontrol.h>
|
||||||
#include <wallet/feebumper.h>
|
#include <wallet/feebumper.h>
|
||||||
|
@ -393,21 +392,10 @@ Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransacti
|
||||||
mapValue_t mapValue = oldWtx.mapValue;
|
mapValue_t mapValue = oldWtx.mapValue;
|
||||||
mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
|
mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
|
||||||
|
|
||||||
CValidationState state;
|
wallet.CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm);
|
||||||
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)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark the original tx as bumped
|
// mark the original tx as bumped
|
||||||
|
bumped_txid = tx->GetHash();
|
||||||
if (!wallet.MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
|
if (!wallet.MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
|
||||||
// TODO: see if JSON-RPC has a standard way of returning a response
|
// 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
|
// along with an exception. It would be good to return information about
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <consensus/validation.h>
|
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
|
@ -341,11 +340,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));
|
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
}
|
}
|
||||||
CValidationState state;
|
pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
|
||||||
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);
|
|
||||||
}
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,12 +921,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
|
||||||
bool fCreated = pwallet->CreateTransaction(*locked_chain, vecSend, tx, nFeeRequired, nChangePosRet, strFailReason, coin_control);
|
bool fCreated = pwallet->CreateTransaction(*locked_chain, vecSend, tx, nFeeRequired, nChangePosRet, strFailReason, coin_control);
|
||||||
if (!fCreated)
|
if (!fCreated)
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
||||||
CValidationState state;
|
pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
|
||||||
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
|
|
||||||
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
|
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tx->GetHash().GetHex();
|
return tx->GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <consensus/validation.h>
|
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
|
@ -451,8 +450,7 @@ public:
|
||||||
auto locked_chain = m_chain->lock();
|
auto locked_chain = m_chain->lock();
|
||||||
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, fee, changePos, error, dummy));
|
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, fee, changePos, error, dummy));
|
||||||
}
|
}
|
||||||
CValidationState state;
|
wallet->CommitTransaction(tx, {}, {});
|
||||||
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, state));
|
|
||||||
CMutableTransaction blocktx;
|
CMutableTransaction blocktx;
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
|
|
|
@ -3284,12 +3284,8 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
{
|
|
||||||
auto locked_chain = chain().lock();
|
auto locked_chain = chain().lock();
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
|
@ -3300,35 +3296,32 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||||
wtxNew.fFromMe = 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,
|
// Add tx to wallet, because if it has change it's also ours,
|
||||||
// otherwise just for transaction history.
|
// otherwise just for transaction history.
|
||||||
AddToWallet(wtxNew);
|
AddToWallet(wtxNew);
|
||||||
|
|
||||||
// Notify that old coins are spent
|
// Notify that old coins are spent
|
||||||
for (const CTxIn& txin : wtxNew.tx->vin)
|
for (const CTxIn& txin : wtxNew.tx->vin) {
|
||||||
{
|
|
||||||
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
|
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
|
||||||
coin.BindWallet(this);
|
coin.BindWallet(this);
|
||||||
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
|
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Get the inserted-CWalletTx from mapWallet so that the
|
// Get the inserted-CWalletTx from mapWallet so that the
|
||||||
// fInMempool flag is cached properly
|
// fInMempool flag is cached properly
|
||||||
CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
|
CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
|
||||||
|
|
||||||
if (fBroadcastTransactions)
|
if (!fBroadcastTransactions) {
|
||||||
{
|
// Don't submit tx to the mempool
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string err_string;
|
std::string err_string;
|
||||||
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
|
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
|
||||||
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
|
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.
|
// 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)
|
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||||
|
|
|
@ -1146,7 +1146,16 @@ public:
|
||||||
*/
|
*/
|
||||||
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut,
|
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);
|
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
|
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue