Skip to content
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

fuzz: add target for coinselection algorithms #24602

Merged
merged 1 commit into from Mar 31, 2022

Conversation

mzumsande
Copy link
Contributor

This adds a fuzz target for the coinselection algorithms by creating random OutputGroups and running all three coin selection algorithms for them.
It does not fuzz higher-level wallet logic for selecting eligible coins (as in SelectCoins()), thought it probably would make sense to have a fuzz target for that too.

@glozow
Copy link
Member

glozow commented Mar 22, 2022

Nice, concept ACK

src/wallet/test/fuzz/coinselection.cpp Outdated Show resolved Hide resolved
src/wallet/test/fuzz/coinselection.cpp Outdated Show resolved Hide resolved
src/wallet/test/fuzz/coinselection.cpp Outdated Show resolved Hide resolved
bool valid_outputgroup{false};
for (auto& coin : coins) {
output_group.Insert(coin, /*depth=*/0, /*from_me=*/true, /*ancestors=*/0, /*descendants=*/0, positive_only);
valid_outputgroup = !positive_only || output_group.GetSelectionAmount() > 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at the body of OutputGroup::Insert() I can't see how valid_outputgroup can become false. What do I miss?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem I tried to address here is that OutputGroup::Insert() may not insert anything but just return if positive_only is true. In that case, we might have an empty OutputGroup with GetSelectionAmount() == 0 which would make SelectCoinsBnB() assert, so it cannot be submitted.
I added a comment for this.

Comment on lines 65 to 75
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
{
const int nInput{fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 10)};
const int nInputBytes{fuzzed_data_provider.ConsumeIntegralInRange<int>(100, 10000)};
const CAmount amount{fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(1, MAX_MONEY)};
AddCoin(utxo_pool, amount, nInput, nInputBytes, ++nextLockTime);
total_balance += amount;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

A few iterations of this could lead to total_balance being bigger than MAX_MONEY. Could this trigger some assert in the tested functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! I'm actually not sure. But I added a break statement to the loop for this case, which (at least I hope!) can't happen in reality and therefore doesn't need fuzzing.

src/wallet/test/fuzz/coinselection.cpp Outdated Show resolved Hide resolved
@mzumsande
Copy link
Contributor Author

Thanks for the review! I addressed the comments by @vasild and rebased on master.

@mzumsande
Copy link
Contributor Author

Needs rebase?

Definitely. Rebased after #24091 and #24494 were merged.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK 591c108

Thanks for the explanations. I tried running this for a while and did not see any failures. Also tried disabling the LIMITED_WHILE in the code to be sure that it does not brick with empty group_pos and group_all.

Copy link
Member

@maflcko maflcko 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

src/wallet/test/fuzz/coinselection.cpp Outdated Show resolved Hide resolved
src/wallet/test/fuzz/coinselection.cpp Outdated Show resolved Hide resolved
This creates random OutputGroups and runs the
existing coinselection algorithms for them.
@mzumsande
Copy link
Contributor Author

Pushed an update addressing feedback.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK 21520b9

@achow101
Copy link
Member

ACK 21520b9

@achow101 achow101 merged commit 1021e4c into bitcoin:master Mar 31, 2022
@mzumsande mzumsande deleted the 202203_fuzz_coinselection branch April 6, 2022 13:02
@bitcoin bitcoin locked and limited conversation to collaborators Apr 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants