-
Notifications
You must be signed in to change notification settings - Fork 327
refactor: interfaces, make 'createTransaction' less error-prone #807
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
base: master
Are you sure you want to change the base?
Changes from all commits
900e5ed
a4007a4
9cd8462
0b92ee2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| #include <psbt.h> | ||
| #include <util/translation.h> | ||
| #include <wallet/coincontrol.h> | ||
| #include <wallet/types.h> | ||
| #include <wallet/wallet.h> // for CRecipient | ||
|
|
||
| #include <stdint.h> | ||
|
|
@@ -153,6 +154,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(); | ||
|
|
@@ -204,27 +207,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) | ||
| { | ||
| if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) | ||
| { | ||
| return SendCoinsReturn(AmountWithFeeExceedsBalance); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In commit "gui: remove unreachable AmountWithFeeExceedsBalance error" (355199c) This is a nice catch noticing that this code doesn't work. But I think the fact that it doesn't work is a pretty unfortunate problem, and the current PR will make fixing it harder. It seems like bitcoin/bitcoin#20640 unintentionally introduced a bug where the more accurate error message "The total exceeds your balance when the %1 transaction fee is included" can never trigger, and instead only less informative "Insufficient funds" or "The amount exceeds your balance" errors will be shown. It looks like there are few ways this could be fixed:
Against that background, I think this PR (as of edc3f9a) makes some nice cleanups, but I don't like the current changes because I think they make all of the fixes above except maybe the last one harder to implement. So I don't think I would ACK this PR currently, I'd happily ACK it if it either (1) fixed the problem, maybe using one of the easier fixes suggested above, or (2) did not fix the problem, but at least did not make it harder to fix in the future. This could be implemented by keeping most of the changes in the PR, but not deleting this GUI code in this commit and not deleting the |
||
| } | ||
| 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(res->change_pos ? int(*res->change_pos) : -1); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In commit "refactor: interfaces, make 'createTransaction' less error-prone" (0b92ee2) Might be better to replace |
||
| } | ||
|
|
||
| // 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). | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure why this is needed.