refactor: interfaces, make 'createTransaction' less error-prone

Bundle all function's outputs inside the util::Result returned object.

Reasons for the refactoring:
- The 'change_pos' ref argument has been a source of bugs in the past.
- The 'fee' ref argument is currently only set when the transaction creation process succeeds.
This commit is contained in:
furszy committed 2026-02-06 18:15:59 -05:00
1 parent e2c3ec9bf4
commit 4c0d4f6f93
3 files changed
+19 -25

No files matched your search

+13 -11
View File
@@ -23,6 +23,7 @@
#include <psbt.h>
#include <util/translation.h>
#include <wallet/coincontrol.h>
#include <wallet/types.h>
#include <wallet/wallet.h>
#include <cstdint>
@@ -149,6 +150,8 @@ bool WalletModel::validateAddress(const QString& address) const
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl)
{
transaction.getWtx() = nullptr; // reset tx output
CAmount total = 0;
bool fSubtractFeeFromAmount = false;
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
@@ -199,22 +202,21 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
}
try {
CAmount nFeeRequired = 0;
int nChangePosRet = -1;
auto& newTx = transaction.getWtx();
const auto& res = m_wallet->createTransaction(vecSend, coinControl, /*sign=*/!wallet().privateKeysDisabled(), nChangePosRet, nFeeRequired);
newTx = res ? *res : nullptr;
transaction.setTransactionFee(nFeeRequired);
if (fSubtractFeeFromAmount && newTx)
transaction.reassignAmounts(nChangePosRet);
if (!newTx) {
const auto& res = m_wallet->createTransaction(vecSend, coinControl, /*sign=*/!wallet().privateKeysDisabled(), /*change_pos=*/std::nullopt);
if (!res) {
Q_EMIT message(tr("Send Coins"), QString::fromStdString(util::ErrorString(res).translated),
CClientUIInterface::MSG_ERROR);
CClientUIInterface::MSG_ERROR);
return TransactionCreationFailed;
}
newTx = res->tx;
CAmount nFeeRequired = res->fee;
transaction.setTransactionFee(nFeeRequired);
if (fSubtractFeeFromAmount && newTx) {
transaction.reassignAmounts(static_cast<int>(res->change_pos.value_or(-1)));
}
// Reject absurdly high fee. (This can never happen because the
// wallet never creates transactions with fee greater than
// m_default_max_tx_fee. This merely a belt-and-suspenders check).