Skip to content

Conversation

@furszy
Copy link
Member

@furszy furszy commented Dec 18, 2022

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.

@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 18, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK S3RK, Xekyo, theStack, achow101
Stale ACK aureleoules

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #26715 (Introduce MockableDatabase for wallet unit tests by achow101)

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.

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

@furszy furszy force-pushed the 2022_coin_selection_weight branch from 4c249f8 to 962b7d8 Compare January 13, 2023 16:47
@furszy furszy force-pushed the 2022_coin_selection_weight branch 2 times, most recently from 10c5df8 to f0add1d Compare January 20, 2023 01:53
@furszy
Copy link
Member Author

furszy commented Jan 20, 2023

Updated with two points:

  1. Added coverage for bnb max weight exceeded 41fb2c4.

  2. Cleaned further the coin selection test f0add1d (noticed by @aureleoules inside #25806)

Copy link
Contributor

@murchandamus murchandamus left a 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

@furszy furszy force-pushed the 2022_coin_selection_weight branch from f0add1d to 7d5a02e Compare February 11, 2023 13:07
@furszy
Copy link
Member Author

furszy commented Feb 11, 2023

Feedback tackled, thanks for the review Xekyo!
Pushed diff.

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reACK 7d5a02ecb2af934ea0fa76c9013b2a2fc968b726

@furszy
Copy link
Member Author

furszy commented Mar 7, 2023

rebased, conflicts solved.

Copy link
Contributor

@aureleoules aureleoules left a 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);
Copy link
Contributor

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

Suggested change
} else append_error(bnb_result);
} else {
append_error(bnb_result);
}

Copy link
Member Author

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

@furszy
Copy link
Member Author

furszy commented Apr 3, 2023

Thanks aureleoules for the feedback.

Sidenote, It seems this chunk of code is unused.

That chunk of code is not in master, #27227 already cleaned it.

@aureleoules
Copy link
Contributor

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!

Copy link
Contributor

@theStack theStack left a 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.

@furszy furszy force-pushed the 2022_coin_selection_weight branch from ba7970c to 488dbea Compare April 4, 2023 18:21
@furszy
Copy link
Member Author

furszy commented Apr 4, 2023

Thanks all for the feedback :). Update Diff:

  • Renamed max_weight to max_inputs_weight.
  • Deduced change output weight from the max allowed weight for Knapsack and SRD (not from BnB as it's specialized to not create change).
  • Adapted doxygen comment to current sources.

@furszy furszy force-pushed the 2022_coin_selection_weight branch from 488dbea to 2a475c4 Compare April 5, 2023 00:40
Copy link
Contributor

@S3RK S3RK left a 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

furszy and others added 7 commits April 5, 2023 09:32
…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.
@furszy furszy force-pushed the 2022_coin_selection_weight branch from 2a475c4 to 25ab147 Compare April 5, 2023 12:33
@S3RK
Copy link
Contributor

S3RK commented Apr 6, 2023

ACK 25ab147

The only change is my previous comment addressed about using correct variable to determine change output size.

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reACK 25ab147

Copy link
Contributor

@theStack theStack left a 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

@achow101
Copy link
Member

ACK 25ab147

@achow101 achow101 merged commit 395b932 into bitcoin:master Apr 20, 2023
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 21, 2023
@furszy furszy deleted the 2022_coin_selection_weight branch May 27, 2023 01:46
@bitcoin bitcoin locked and limited conversation to collaborators May 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants