-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Revert "bnb: exit selection when best_waste is 0" #25495
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
This reverts commit 9b5950d. Waste can be negative. At feerates lower than long_term_feerate this means that a waste of 0 may be a suboptimal solution and this causes the search to exit prematurely. Only when the feerate is equal to the long_term_feerate would achieving a waste of 0 indicate that we have achieved an optimal solution, because it would mean that the excess is 0. It seems unlikely that this would ever occur outside of test cases, and even then we should prefer solutions with more inputs over solutions with fewer according to previous decisions—but solutions with more inputs are found later in the branch exploration. The "optimization" described in bitcoin#18257 and implemented in bitcoin#18262 is therefore a premature exit on a suboptimal solution and should be reverted.
|
utACK af56d63 (I looked just at the diff, and guessed why the original code was wrong without looking at the description) |
|
utACK af56d63 Agree we should continue searching even solution with zero waste was found. Didn't test |
glozow
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.
utACK af56d63, agree it is incorrect to stop here unless we could rule out the possibility of a better solution with negative waste. SelectCoinsBnB doesn't know what long term feerate and effective feerate are (and probably shouldn't) so it's better to have no exit early condition at all.
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsNo conflicts as of last run. |
|
ACK af56d63 Oops, yes, waste can be negative. |
98ea43d test: add tests for negative waste during coin selection (ishaanam) Pull request description: #25495 mentions that waste can be negative when the current feerate is less than the long term feerate. There are currently no waste tests for negative waste, so this PR adds two of them. ACKs for top commit: achow101: ACK 98ea43d glozow: light code review ACK 98ea43d, good to have tests for negative waste Tree-SHA512: d194d370f1257975959d3c601fea9f82c30c1aabc3e8bedc997c62659283fe681cc527e59df1a0187b3c91e8067c60374dd5ce0237561bd882edafe6a575a9b9
|
@xekyo Can you point me to why this decision is so or where this discussion happened?
In your paper, section 3.1.4 discusses conflicting goals, although it isn't all-together clear to me that we should maximize the number of UTXOs used. If however, we do want to maximize the number of UTXOs used, I think the sort should be reversed here so the selection process starts with the smallest (non-dust) utxos? |
|
@yancyribbens: The code had an early exit when an input set happened to achieve a E.g. at 1 s/vB, we would prefer a solution with two P2PKH (2×148 B × (1 s/vB - 10 s/vB) = -2664 s) inputs over a solution with three P2WPKH inputs (3×68 vB × (1 s/vB - 10 s/vB) = -1836 s), and a solution with three P2WPKH inputs over a solution with two P2WPKH inputs (2×68 vB × (1 s/vB - 10 s/vB) = -1224 s). On the other hand, at high feerates say 60 s/vB, we'll prefer a solution with one P2PKH input (148 B × (60 s/vB - 10 s/vB) = 7400 s) over one with three P2WPKH inputs (148 B < 3×68 vB), but prefer two P2WPKH inputs over one P2PKH input (2×68 vB < 148 B), and obviously one P2WPKH over a solution with two P2WPKH inputs. Over the course of many transactions, this causes our wallet to opportunistically use more and heavier UTXOs at low feerates, which reduces our overall transaction fees, while preventing runaway UTXO pool bloat as we have seen from strategies that always try to minimize the input set (e.g. largest first selection). So, we don't want to maximize the UTXOs used, but we just want to prefer spending them at lower feerates when it is opportune. By starting with the biggest UTXOs, we'll find one solution as quick as possible, but the algorithm hypothetically enumerates all possible input set (except that we stop after trying 100,000 combinations). While the reverse sort order would also enumerate all, I would expect that it performs much worse to find the first solution. It would be like trying to fill a bucket with sand and rocks where we currently put the rocks first, then pour the sand, and then instead pour the sand first and then try to fit the big rocks: the smaller pieces are much more likely to fit a remaining gap. |
|
@xekyo thanks, I read your blog post. I understand the strategy where when fees are cheap, keep adding utxos to the selection and if fees are expensive go for a minimal utxo selection set. The thing that I think is confusing is the terminology, specifically "negative waste". Personally, I think "weight" is a better word that we should be aiming to minimize. For example: We therefore try to minimize the selection weight, and waste is always the excess (positive) amount. |
|
Thanks for the feedback that the terminology is confusing. Would consequently referring to it as |
|
Thanks BTW for writing up the terminology in your blog post. It's much easier to understand than trying to read the reference implementation. In your post you describe
Which I think is a bit confusing since you're defining weight in terms of itself. Reading the history of weight it looks like it can also be called I understand not wanting to overload the term "weight", however in terms of graph theory, I think "weight" is typical terminology used to describe the value assigned to an edge. In the case of DFS, using graph terminology feels fitting. I think |
Oh, I'm explaining what the components of the formula, not defining terms.
I guess I could have added a bit more detail here in my blog post. There are four terms referring to different expressions of transaction size in Bitcoin:
The formula works out when using weight and the feerate is given in
It's not clear to me what you're proposing here, given that |
|
Thanks for the explanation.
I had thought
The use of |
|
As a follow-up to clarify perhaps: |
I understand that. Originally, I had proposed re-defining
Now that I understand better what block weight is, I agree that overloading the term would be confusing.
I'm not sure what is meant by this. Could you clarify what you mean? |
|
Let's say you're building a transaction that pays two recipients to a P2SH and a P2WSH output. Your UTXO pool consists only of segwit UTXOs, and let's say we only find two input set candidates, one with a single P2SH-P2WSH input and one with two P2WSH inputs. The weight of the transaction with two P2WSH inputs is: and the weight of the transaction with one P2SH-P2WSH input is: As you can see, whatever the current feerate in that calculation the cost stemming from the transaction header and the two outputs ( |
|
Alright, I see what you mean. The point is that the difference in feerate does not need to take into account the difference in feerate for different transaction types. It's only important that the difference in fee changes the waste score in a way that sways the UTXO selection process, but shifting by a fixed value IE the difference in transaction weight isn't important for the selection to work. Back to the earlier conversation, maybe we can settle on a code change PR which changes the terminology to |
I'm not sure I understand what you mean. The targeted feerate is fixed across the complete transaction building process. It's a user input before we start picking inputs.
The different weights of different input types do matter, larger outputs have a more negative waste score at low feerates and a higher waste score at high feerates—so legacy outputs get picked preferentially at low feerates, while they get selected less at high feerates.
TBH, I'm not convinced that renaming |
That makes sense, I see what you mean now.
Alright. Thanks for entertaining the possibility. |
This reverts commit 9b5950d.
Waste can be negative. At feerates lower than long_term_feerate this
means that a waste of 0 may be a suboptimal solution and this causes the
search to exit prematurely.
Only when the feerate is equal to the long_term_feerate would achieving
a waste of 0 indicate that we have achieved an optimal solution,
because it would mean that the excess is 0. It seems unlikely
that this would ever occur outside of test cases, and even then we
should prefer solutions with more inputs over solutions with fewer
according to previous decisions—but solutions with more inputs are found
later in the branch exploration.
The "optimization" described in #18257 and implemented in #18262 is
therefore a premature exit on a suboptimal solution and should be reverted.