-
Notifications
You must be signed in to change notification settings - Fork 38.7k
wallet: coin selection, don't return results that exceed the max allowed weight #26720
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. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. 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. |
7663cbd to
b4510ce
Compare
9392eaa to
4c249f8
Compare
murchandamus
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.
Concept ACK
4c249f8 to
962b7d8
Compare
10c5df8 to
f0add1d
Compare
|
Updated with two points:
|
murchandamus
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.
crACK w/ nits f0add1d0a7507e5601d7da54f62fe9ab272b3281
f0add1d to
7d5a02e
Compare
|
Feedback tackled, thanks for the review Xekyo! |
murchandamus
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.
reACK 7d5a02ecb2af934ea0fa76c9013b2a2fc968b726
|
rebased, conflicts solved. |
aureleoules
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.
ACK 1284223 - I verified the tests are correct and the code looks good to me.
Sidenote, It seems this chunk of code is unused.
Unused code
diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp
index 92d33bd38..26405d63a 100644
--- a/src/wallet/coinselection.cpp
+++ b/src/wallet/coinselection.cpp
@@ -448,13 +448,6 @@ void OutputGroupTypeMap::Push(const OutputGroup& group, OutputType type, bool in
}
}
-std::optional<Groups> OutputGroupTypeMap::Find(OutputType type)
-{
- auto it_by_type = groups_by_type.find(type);
- if (it_by_type == groups_by_type.end()) return std::nullopt;
- return it_by_type->second;
-}
-
CAmount GetSelectionWaste(const std::set<std::shared_ptr<COutput>>& inputs, CAmount change_cost, CAmount target, bool use_effective_value)
{
// This function should not be called with empty inputs as that would mean the selection failed| if (auto bnb_result{SelectCoinsBnB(groups.positive_group, nTargetValue, coin_selection_params.m_cost_of_change)}) { | ||
| results.push_back(*bnb_result); | ||
| } | ||
| } else append_error(bnb_result); |
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.
1284223 (same below)
If an if only has a single-statement then-clause, it can appear on the same line as the if, without braces. In every other case, braces are required, and the then and else clauses must appear correctly indented on a new line.
https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md#coding-style-c
| } else append_error(bnb_result); | |
| } else { | |
| append_error(bnb_result); | |
| } |
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.
Hmm, what about something like this furszy@0ddd8f4
|
Thanks aureleoules for the feedback.
That chunk of code is not in master, #27227 already cleaned it. |
Ah great, I'm not up-to-date with all the recently merged PRs, it's been a while since I reviewed any! |
theStack
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.
Concept ACK
Changes look good at a first glance 👌, will do a second round tomorrow.
ba7970c to
488dbea
Compare
|
Thanks all for the feedback :). Update Diff:
|
488dbea to
2a475c4
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.
Almost Code Review ACK 2a475c4
modulo one comment
…exceeds max tx size The simplest scenario where this is useful is on the 'check_max_weight' unit test already: We create 1515 UTXOs with 0.033 BTC each, and 1 UTXO with 50 BTC. Then perform Coin Selection. As the selection of the 1515 small UTXOs exceeds the max allowed tx size, the expectation here is to receive a selection result that only contain the big UTXO (which is not happening for the reasons stated below). As knapsack returns a result that exceeds the max allowed transaction size, we fallback to SRD, which selects coins randomly up until the target is met. So we end up with a selection result with lot more coins than what is needed.
…x weight Uses a min-effective-value heap, so we can remove the least valuable input/s while the selected weight exceeds the maximum allowed weight. Co-authored-by: Murch <[email protected]>
Now the coin selection algorithms contemplate the maximum allowed weight internally and return std::nullopt if their result exceeds it.
Basic positive and negative scenarios
same lines of code repeated across the entire file over and over.
2a475c4 to
25ab147
Compare
|
ACK 25ab147 The only change is my previous comment addressed about using correct variable to determine change output size. |
murchandamus
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.
reACK 25ab147
theStack
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.
Code-review ACK 25ab147
|
ACK 25ab147 |
Coming from the following comment #25729 (comment).
The reason why we are adding hundreds of UTXO from different sources when the target
amount is covered only by one of them is because only SRD returns a usable result.
Context:
In the test, we create 1515 UTXOs with 0.033 BTC each, and 1 UTXO with 50 BTC. Then
perform Coin Selection to fund 49.5 BTC.
As the selection of the 1515 small UTXOs exceeds the max allowed tx size, the
expectation here is to receive a selection result that only contain the big UTXO.
Which is not happening for the following reason:
Knapsack returns a result that exceeds the max allowed transaction size, when
it should return the closest utxo above the target, so we fallback to SRD who
selects coins randomly up until the target is met. So we end up with a selection
result with lot more coins than what is needed.