Replace coin selection fallback strategy with Single Random Draw#13307
Replace coin selection fallback strategy with Single Random Draw#13307achow101 wants to merge 11 commits intobitcoin:masterfrom
Conversation
src/wallet/coinselection.cpp
Outdated
There was a problem hiding this comment.
Could return true here, return false if the loop exhausts, to avoid duplicating the condition.
src/wallet/wallet.cpp
Outdated
There was a problem hiding this comment.
Could collapse this to boolean fallback at this point.
src/wallet/wallet.h
Outdated
80a9f2c to
9eea461
Compare
instagibbs
left a comment
There was a problem hiding this comment.
"Calculate the transaction fees" <--- this commit probably needs more description, not sure what it's doing.
src/wallet/coinselection.cpp
Outdated
There was a problem hiding this comment.
non_input_fees? It's not "not fees", rather "non-input". Easier for me to read.
src/wallet/wallet.cpp
Outdated
There was a problem hiding this comment.
I think this new logic means that non-BnB will be tried more often? Instead of trying all variants of BnB(6 confirms, 1 confirm, small chain, etc), we seem to be trying 6 confirms for BnB, then 6 confirms for non-BnB
There was a problem hiding this comment.
Hmm, yes, that appears to be what is happening. I guess this depends on whether we want to select an exact match for coins with less confirmatoins, or whether we want confirmations over exact match.
There was a problem hiding this comment.
This is a good point. Perhaps a solution is to add a use_bnb argument to SelectCoinsMinConf (but not as part CoinSelectionParams), and then have a sequence of attempts with and without use_bnb in SelectCoins?
There was a problem hiding this comment.
I prefer the behavior in master due to privacy reasons of change-less transactions.
There was a problem hiding this comment.
I have implemented this change.
src/wallet/wallet.cpp
Outdated
src/wallet/wallet.cpp
Outdated
|
Some thoughts. |
Reworded, hopefully it's better. |
|
nit: Somewhat better to revert the merge commit 9552dfb rather than the 2 pr commits, to be explicit that the whole PR was reverted (and which one). |
src/wallet/coinselection.cpp
Outdated
There was a problem hiding this comment.
nit: Better to document in the header, and use doxygen comment /**
There was a problem hiding this comment.
_bnb probably no longer relevant
There was a problem hiding this comment.
Removed here and elsewhere
src/wallet/wallet.cpp
Outdated
There was a problem hiding this comment.
nit: explicit precedence would be nice here: (out.nInputBytes < 0 || !use_effective)
There was a problem hiding this comment.
I thought I did this earlier. Must have gotten lost in a rebase. Fixed.
src/wallet/wallet.cpp
Outdated
src/wallet/coinselection.h
Outdated
There was a problem hiding this comment.
nit: Better to squash this change into the commit that calls for it
Done |
src/wallet/coinselection.cpp
Outdated
There was a problem hiding this comment.
Two comments:
- Requesting new entropy for each element being sorted may be slow (each call to
GetRandIntinvokes OpenSSL for randomness) (this also applies to the code you copied, but you're going to remove that anyway). - It's overkill to permute all elements, as you're likely only going to use a few.
For the first, create a FastRandomContext and use that in std::shuffle (rather than random_shuffle):
std::shuffle(utxo_pool.begin(), utxo_pool.end(), FastRandomContext());`For the second, you can permute on the fly; for example:
FastRandomContext ctx;
for (size_t i = 0; i < utxo_pool.size; ++i) {
size_t pos = i + ctx.randrange(utxo_pool.size() - i); // randomly pick one of the remaining elements
std::swap(utxo_pool[i], utxo_pool[pos]);
const CInputCoin& utxo = utxo_pool[i];
...
}
src/wallet/wallet.cpp
Outdated
There was a problem hiding this comment.
This is a good point. Perhaps a solution is to add a use_bnb argument to SelectCoinsMinConf (but not as part CoinSelectionParams), and then have a sequence of attempts with and without use_bnb in SelectCoins?
src/wallet/wallet.cpp
Outdated
efda8e0 to
05dfc65
Compare
src/wallet/coinselection.cpp
Outdated
There was a problem hiding this comment.
Travis fails because of size (instead of size()).
|
I'm not quite sure what is causing the travis failure. |
|
Fixed the test failure. |
SingleRandomDraw randomly chooses UTXOs until there is sufficient effective value.
Replaces the knapsack solver fallback with the SRD fallback. Also changes SelectCoinsMinConf to use exclusively effective value to work with BnB and SRD
Instead of the caller telling SelectCoinsMinConf when to use BnB or the fallback, have SelectCoinsMinConf do it itself. This removes the use_bnb field of coin_selection_params
We are now using effective value for coin selection, so there is no need for the loop or any of the fee checking things that were done within it. All fees ard handled by the effective value selection Move vout filling to after coins are selected so that the transaction fee is actually known to handle when users want to subtract the fee from the outputs.
bnb_used is no longer necessary since we account for fees when calculating how much change there is
For preset inputs, use their effective values
Fix tests that relied on non-deterministic coin selection to be able to handle the random coin selection.
|
Rebased |
Note to reviewers: 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. |
| Needs rebase |
| There hasn't been much activity lately and the patch still needs rebase, so I am closing this for now. Please let me know when you want to continue working on this, so the pull request can be re-opened. |
When BnB selection fails to find an exact match, we fall back to the original Bitcoin Core algorithm. This PR replaces that fallback with the Single Random Draw strategy. Additionally, because SRD uses effective values, the previous fee increasing loop thing is now removed and effective value is used everywhere.
Some tests may fail spuriously because they may rely on semi-deterministic behavior from the original coin selection algorithm. I have been able to fix the ones that fail the most, but others may still have issues. Please let me know if you see any tests fail for coin selection reasons (e.g. insufficient funds, missing inputs, etc.) and I will try to fix them.
I will be working on doing simulations this week and will post the data once I finish them.