-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Actually disable BnB when there are preset inputs #12694
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
We don't want to use BnB when there are preset inputs because there is some weirdness with making that work with using the KnapsackSolver as the fallback. Currently we say that we haven't used bnb when there are preset inputs, but we don't actually disable BnB. This fixes that.
Dare I ask if you can write a test for this? |
Added a test |
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 3f97e7cc129876b3b392057151cfece44e747938
@@ -2523,6 +2523,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm | |||
{ | |||
// For now, don't use BnB if preset inputs are selected. TODO: Enable this later | |||
bnb_used = false; | |||
coin_selection_params.use_bnb = false; |
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.
In commit "Actually disable BnB when there are preset inputs"
Sorry to repeat my comment from the other PR, but I do think it'd be clearer to add explicit non-reference bool disable_bnb
parameters to SelectCoins methods, so the CoinSelectionParams
struct can remain const and not be changing on the fly. The current bug seems like evidence to me that controlling bnb through the struct is not a great idea.
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 agree that it isn't ideal, but having the caller control whether BnB should be used is just a temporary shim to work with the current coin selection. I intend for it to go away when the replacement fallback strategy is implemented (which I have already started doing so). I don't think changing it now is worth the additional review effort required when the parameter will be removed later.
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.
Since this is just temporary code anyway, keep the parameter const and make a copy:
auto params = coin_selection_params;
params.use_bnb = false;
That way this diff doesn't have to change the function signature, you don't need to change the header file, and you can have more const. Considering all of the other work this method is doing, the overhead of the copy won't even be measurable.
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.
Implemented @eklitzke's suggestion.
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.
Actually, I reverted that change. It makes this untestable.
coin_control.fAllowOtherInputs = true; | ||
coin_control.Select(COutPoint(vCoins.at(0).tx->GetHash(), vCoins.at(0).i)); | ||
BOOST_CHECK(testWallet.SelectCoins(vCoins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb, bnb_used)); | ||
BOOST_CHECK(!bnb_used && !coin_selection_params_bnb.use_bnb); |
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.
In commit "Test that BnB is not used when there are preset inputs"
Might want to split this up into two BOOST_CHECK
statements, so if one condition fails, the output shows which one is failing.
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.
Done
3f97e7c
to
081bf54
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.
utACK 081bf54, only change since the last review is splitting BOOST_CHECK
@@ -72,6 +73,7 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa | |||
} | |||
COutput output(wtx.get(), nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */); | |||
vCoins.push_back(output); | |||
testWallet.AddToWallet(*wtx.get()); |
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 the code was like this when you started, but it seems kind of dangerous to be mutating global variables in the test suite like this, because it can cause errors to propagate from one test to another. It looks like it would be pretty straightforward to change the code in the test to not use globals. Consider making these variables local to each method (maybe in a future 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.
testWallet
isn't actually used for anything in the tests except for a way to call SelectCoins
and SelectCoinsMinConf
. Furthermore the coins in the wallet are never actually used by either of those two functions, the only reason it is needed here so that we can pre-select some coins for the test that was just added. And that test is also temporary, so I think it is fine as is as this change does not have any effect on the other tests.
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.
Agree that it's fine as is, but boy scout mentality ("leave you camp site cleaner than it was before") is helpful, especially in code bases that have a lot of existing style violations (like Bitcoin).
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'd also like to see a little cleanup here, if it's not much trouble.
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 a lot of trouble to clean this up. The diff would be quite large and out of scope for this PR IMO. I think this is partially why SelectCoins
itself is never actually tested; instead all of the tests focus on SelectCoinsMinConf
.
@@ -2523,6 +2523,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm | |||
{ | |||
// For now, don't use BnB if preset inputs are selected. TODO: Enable this later | |||
bnb_used = false; | |||
coin_selection_params.use_bnb = false; |
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.
Since this is just temporary code anyway, keep the parameter const and make a copy:
auto params = coin_selection_params;
params.use_bnb = false;
That way this diff doesn't have to change the function signature, you don't need to change the header file, and you can have more const. Considering all of the other work this method is doing, the overhead of the copy won't even be measurable.
52cba62
to
081bf54
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.
utACK
@@ -72,6 +73,7 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa | |||
} | |||
COutput output(wtx.get(), nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */); | |||
vCoins.push_back(output); | |||
testWallet.AddToWallet(*wtx.get()); |
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'd also like to see a little cleanup here, if it's not much trouble.
081bf54 Test that BnB is not used when there are preset inputs (Andrew Chow) 6ef9982 Actually disable BnB when there are preset inputs (Andrew Chow) Pull request description: We don't want to use BnB when there are preset inputs because there is some weirdness with making that work with using the KnapsackSolver as the fallback. Currently we say that we haven't used bnb when there are preset inputs, but we don't actually disable BnB. This fixes that. I thought this was done originally. I guess it got lost in a rebase somewhere. Tree-SHA512: 9792c0cdd0736866bddbed20f10b8050104955dc589fba49a0bd61a582ba491c921af2cdcc2269678b7b69275dad5fcf89c71b75c28733c7bacbe52e55891b9c
@achow101 Are you keeping a coinselection todo someplace? The ability to bnb with preset inputs (less than the demanded amount) would be nice, it shouldn't be forgotten. |
081bf54 Test that BnB is not used when there are preset inputs (Andrew Chow) 6ef9982 Actually disable BnB when there are preset inputs (Andrew Chow) Pull request description: We don't want to use BnB when there are preset inputs because there is some weirdness with making that work with using the KnapsackSolver as the fallback. Currently we say that we haven't used bnb when there are preset inputs, but we don't actually disable BnB. This fixes that. I thought this was done originally. I guess it got lost in a rebase somewhere. Tree-SHA512: 9792c0cdd0736866bddbed20f10b8050104955dc589fba49a0bd61a582ba491c921af2cdcc2269678b7b69275dad5fcf89c71b75c28733c7bacbe52e55891b9c
081bf54 Test that BnB is not used when there are preset inputs (Andrew Chow) 6ef9982 Actually disable BnB when there are preset inputs (Andrew Chow) Pull request description: We don't want to use BnB when there are preset inputs because there is some weirdness with making that work with using the KnapsackSolver as the fallback. Currently we say that we haven't used bnb when there are preset inputs, but we don't actually disable BnB. This fixes that. I thought this was done originally. I guess it got lost in a rebase somewhere. Tree-SHA512: 9792c0cdd0736866bddbed20f10b8050104955dc589fba49a0bd61a582ba491c921af2cdcc2269678b7b69275dad5fcf89c71b75c28733c7bacbe52e55891b9c
We don't want to use BnB when there are preset inputs because there
is some weirdness with making that work with using the KnapsackSolver
as the fallback. Currently we say that we haven't used bnb when
there are preset inputs, but we don't actually disable BnB. This fixes
that.
I thought this was done originally. I guess it got lost in a rebase somewhere.