-
Notifications
You must be signed in to change notification settings - Fork 37.7k
wallet: Cleanup and refactor CreateTransactionInternal #22008
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
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
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.
utACK 6c0cb3c (the 9 commits in this PR)
Linter seems upset (about indentation?) in the scripted diff commit.
Maybe also move CreateTransactionInternal out of the header?
For code archaeologists wondering about 472e42c why "Dummy fill vin" was added in the first place: it was introduced in #12699, but it's not clear to me why. @instagibbs?
6c0cb3c to
263ed9a
Compare
|
With #17331 now merged, this is ready for review. |
263ed9a to
a2dd0db
Compare
|
re-utACK a2dd0db |
a2dd0db to
c2a5bd6
Compare
|
tACK c2a5bd6 The rebase ate my most pressing comment. Thanks @instagibbs for #22042. ❤️ |
|
The last rebase broke the fee estimation test on CI, though perhaps a coincidence; I can't reproduce: c2a5bd6 looks like a correct rebase |
|
Code review ACK c2a5bd6. I like |
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.
utACK c2a5bd6
A few minor suggestions
c2a5bd6 to
ca46cdc
Compare
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.
It isn't necessary to not lock parts of this function. Just lock the whole thing and get rid of an indent.
ca46cdc to
96c2c95
Compare
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.
reACK 96c2c95
| const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size); | ||
| CAmount nValueToSelect = nValue + not_input_fees; | ||
| // Shuffle selected coins and fill in final vin | ||
| std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end()); |
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.
In b583f73 Move vin filling to before final fee setting (but not super relevant to this PR)
Question: is there a reason setCoins (and setCoinsRet, etc. in the coin selection solvers) needs to be a std::set instead of a std::vector? It doesn't seem like we get much benefit out of using a set, and we convert to vector here anyway?
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.
No reason other than it's always been that way. setCoinsRet can be traced back to 0.1.0.
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.
Code review ACK 96c2c95. No significant changes since last review, just rebase, moving lock and negative amounts check and fixing up some comments
|
Maybe another cleanup for later, but the separate diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index c8ded4c51e2..45a02f59a18 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -756,9 +756,8 @@ bool CWallet::CreateTransactionInternal(
nFeeRet = coin_selection_params.m_effective_feerate.GetFee(nBytes);
// Subtract fee from the change output if not subtracting it from recipient outputs
- CAmount fee_needed = nFeeRet;
if (!coin_selection_params.m_subtract_fee_outputs) {
- change_position->nValue -= fee_needed;
+ change_position->nValue -= nFeeRet;
}
// We want to drop the change to fees if:
@@ -774,17 +773,12 @@ bool CWallet::CreateTransactionInternal(
// Because we have dropped this change, the tx size and required fee will be different, so let's recalculate those
tx_sizes = CalculateMaximumSignedTxSize(CTransaction(txNew), this, coin_control.fAllowWatchOnly);
nBytes = tx_sizes.vsize;
- fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes);
- }
-
- // Update nFeeRet in case fee_needed changed due to dropping the change output
- if (fee_needed <= change_and_fee - change_amount) {
- nFeeRet = change_and_fee - change_amount;
+ nFeeRet = coin_selection_params.m_effective_feerate.GetFee(nBytes);
}
// Reduce output values for subtractFeeFromAmount
if (coin_selection_params.m_subtract_fee_outputs) {
- CAmount to_reduce = fee_needed + change_amount - change_and_fee;
+ CAmount to_reduce = nFeeRet + change_amount - change_and_fee;
int i = 0;
bool fFirst = true;
for (const auto& recipient : vecSend)
@@ -816,7 +810,15 @@ bool CWallet::CreateTransactionInternal(
}
++i;
}
- nFeeRet = fee_needed;
+ } else if (nFeeRet <= change_and_fee - change_amount) {
+ // If dropping the change output covered the fee, update the returned
+ // fee amount. Note that that in subtract-fee-from-recipients case
+ // above, if the change output is dropped, the change dust value will
+ // be paid to recipients, rather than to the miner (`to_reduce` above
+ // will be negative). In that case, the dust amount sent is an
+ // additional cost of the transaction, but it's not considered part of
+ // the fee since it isn't paid to the miner, so nFeeRet doesn't change here.
+ nFeeRet = change_and_fee - change_amount;
}
// Give up if change keypool ran out and change is required
|
|
@ryanofsky I agree that By simply removing |
69f4aed to
303a664
Compare
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.
Reluctant code review ACK 303a664 because it does what is described, but I would prefer previous push 96c2c95 over this push, and then addressing fee_needed behavior and cleanup in a followup PR, ideally including a unit test so we are sure this continues to function as intended.
I wouldn't completely object to changing the behavior like 303a664 does, since the difference is only for small amounts (the cost of a change output) and only in the-subtract-from-recipient case, so I don't think it is too important. But I do think the current behavior does make sense, and I preserved it intentionally in #22008 (comment) and not by accident. Thinking about use-cases, if I enable subtracting-from-recipient, it seems likely I'm transferring funds internally and not making an external payment, and so would prefer to keep my funds instead of overpaying the miner. Even if this is an external payment, then the subtract-from-recipient option already implies the recipient is not sensitive to the exact amount, and so if I'm topping up an external account or a channel, or paying for an online service, again the new behavior would be throwing away my own money/credits to give to a miner.
The one part of current behavior that is perhaps is less than ideal is the fact that the returned nFeeRet doesn't reflect the full cost of sending the transaction. I would fix this just by changing the else if (nFeeRet.. to if (nFeeRet... and dropping the long "note" in #22008 (comment)
src/wallet/spend.cpp
Outdated
| } | ||
|
|
||
| // Update nFeeRet in case fee_needed changed due to dropping the change output | ||
| if (fee_needed <= change_and_fee - change_amount) { | ||
| // Update nFeeRet in case it changed due to dropping the change output |
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.
In commit "Remove unneeded fee_needed variable" (303a664)
I think this comment is a big vague and maybe even misleading because this code isn't just updating the return value but also increasing the fee paid in the subtract-from-outputs case. I would maybe say something like "// Increase nFeeRet to reflect extra fee paid by giving up the small change amount which is smaller than the cost of the change output."
303a664 to
96c2c95
Compare
|
I've reverted back to 96c2c95 I think we should discuss the intended behavior of subtract fee from recipients during the wallet meeting today. |
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.
Code review ACK 96c2c95 also acked previously (was reverted).
Will check out the IRC. I will say I don't see a need to tackle fee_needed in this PR since the PR is already doing a bunch of things and has already had a good amount of review. fee_needed logic also seems more tied to removing the while loop in #17331 than anything done here. And especially if it will change behavior, I think it could be better as standalone PR so it can be discussed and understood without having wade through a ton of refactoring.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
|
re: #22008 (comment)
fee_needed cleanup was discussed more in IRC and is addressed in #22155 for now adding by a unit test to exercise and check the relevant behavior, since there isn't other test coverage |
|
This is probably close to ready to being merged Up to date ACKs glozow #22008 (review) Previous ACKS Sjors #22008 (review) |
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
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.
re-utACK 96c2c95
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This commit does not change behavior in any way. It just removes a variable and adds a comment to explain nFeeRet return value better. The fee_needed variable became redundant after commit 9d3bd74 removed looping in CreateTransactionInternal. This change was originally posted bitcoin#22008 (comment) and discussed in the thread of that PR and in IRC. It might be followed up with more changes later to alter subtract from recipient behavior, but this commit just cleans up and documents the existing code.
This isn't nearly as bad as it looks -- use `git diff -w` to see past the indentation changes.
#17331 did some refactors and cleanup of
CreateTransactionInternalto make it easier to understand, however it is still a bit convoluted even though it doesn't have to be. This PR does additional cleanup and refactoring toCreateTransactionInternalso that it is easier to understand. Some unnecessary code was removed, some variables moved around to where they matter, and several indents removed.