-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Smarter coordination of change and fee in CreateTransaction. #9404
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
|
Concept ACK (Tries to solve issue #4082 et al.) |
|
Concept ACK but will be simpler when rebased on #9465. |
|
Beautiful. utACK. Should be rebased on the latest nit-update of 9465 (sorry about that), I expect it will do so cleanly. We should open an issue to also resolve these behaviors when nSubtractFeeFromAmount is used; I can understand why you didn't cover those in this PR; though they should only be of comparable complexity to this change. |
|
Needs rebase on #9465 merge. |
sdaftuar
left a comment
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.
Looks good, though I guess it needs to be rebased.
src/wallet/wallet.cpp
Outdated
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 guess there's an edge case left here, where if there's no change output and the fee difference is very large, then we won't reduce the fee?
It might be nice to refactor the change-adding logic so that we could add change in that scenario, though I don't want to hold up this PR which is already a strict improvement, do you think it's worth adding a comment that points this out though for future reference?
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's pretty easy to compute exactly the amount of additional fee adding a change output would imply. So the test becomes if not subtractfrom and excessfee >= CENT/2 + changeaddfee; then set the change to excessfee-changeaddfee. Doing so without creating a hairball with change added in multiple places... less fun.
Similarly, the remove side could consider eliminating the change output, if doing so would not overpay by too much. (A conservative value would be the changeaddfee but a larger value would be a lot more useful) both both probably better done in another PR.
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.
Yes my concern is the gap between desired change amounts (CENT/2) and fee overpayments is quite big. Most of the time even if a fee overpayment was bigger than dust, it wouldn't be so big that you'd actually want to create an output with it.
I think fixing that should be combined with more robust handling of the minimum output size a wallet would create. Perhaps then there would be cases where we feel we got unlucky with coin selection and we try again to have less overpayment or more reasonable size change.
The coin selection algorithm is stupid now. Trying to find an exact match makes no sense in a world where every transaction pays fee. So I'd rather not continue adding patches and improvements before we try to improve the basic strategy. I'm happy to give that a shot after 0.14. And I think we can avoid most of these problems from the beginning...
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 53171a915e17e83814328cc3792554159a950757, though I'd prefer to have the edge cases mentioned by @sdaftuar and me documented as todos.
src/wallet/wallet.cpp
Outdated
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 might be missing something, but instead of "Do not", the comment should read "TODO". Otherwise, it would imply that it is ok for the payee to pay excessive fee whereas for the payer it is not.
src/wallet/wallet.cpp
Outdated
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.
can you explain why CENT is used instead of MIN_CHANGE, please?
src/wallet/wallet.cpp
Outdated
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.
nit: No need to mention code specific values in the comment
Once we've picked coins and dummy-signed the transaction to calculate fee, if we don't have sufficient fee, then try to meet the fee by reducing change before resorting to picking new coins.
…ler transaction. On repeated calls to SelectCoins we try to meet the fee necessary for the last transaction, the new fee required might be smaller, so increase our change by the difference if we can.
|
Rebased after #9465 and addressed comments. |
|
utACK 20449ef |
|
utACK 20449ef. Thanks for addressing the feedback so quick! |
|
utACK 20449ef |
|
re-ACK. |
|
utACK 20449ef |
|
utACK 20449ef |
|
What release will this be in? I've been losing a lot of money, to what I suspect is this bug, just $50 last transaction: $ bitcoin-cli estimatefee 4 $ bitcoin-cli listunspent | grep amount | wc -l |
Resolves #9466
I feel bad making the wallet coin selection even more spaghetti like, but I think this is a huge improvement over the existing code and it's relatively simple to understand.Essentially once you pick coins and if you have change, then try to reduce that change to meet the fee instead of repicking coins. Since we aim to have change of .01 BTC if we can't make an exact match initially, this is usually more than sufficient to be reduced only slightly to pay for the fee.
I think for 0.15, we could take on a wholesale rewrite of the algorithm, but thats too much to ask for before 0.14. This however might be worthwhile.
I'm open to suggestions on how to make this cleaner or clearer.EDIT: suggest viewing diff with
?w=1EDIT 2: This is much simpler now. Also includes another commit to remove further cases of overpaying fees.