Skip to content

Conversation

instagibbs
Copy link
Member

@instagibbs instagibbs commented Apr 23, 2018

This section of code loops over the same coins twice, in two different ways depending on whether other inputs are allowed, even though the net effect is just an early return in one case. One used the available coins list(pruned to just preselected coins) and the other the preselected coins directly. Instead just do it once, and return early if no other inputs are allowed.

Note that by definition coin control is in use, so "fSpendable" will always be true, so filtering for this is a NOP.

Added basic unit test case as well.

@@ -2537,6 +2523,11 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
return false; // TODO: Allow non-wallet inputs
}

if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs)
{
return (nValueRet >= nTargetValue);
Copy link
Member

Choose a reason for hiding this comment

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

What about setCoinsRet?

Copy link
Contributor

Choose a reason for hiding this comment

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

nValueRet is never updated, so this will always return false.

Copy link
Member

@laanwj laanwj Apr 23, 2018

Choose a reason for hiding this comment

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

So it will always fail when coin_control.fAllowOtherInputs is not set? I don't think that's supposed to be the behavior.

@Empact
Copy link
Contributor

Empact commented Apr 23, 2018

NACK 4aaa5ba - this code isn't redundant, the out args are used by caller CWallet::CreateTransaction

@Empact
Copy link
Contributor

Empact commented Apr 23, 2018

The fact that the test suite passes with this removal is a smell though - how about a test for CreateTransaction or SelectCoins that fails with this removal?

@instagibbs
Copy link
Member Author

instagibbs commented Apr 23, 2018 via email

@laanwj
Copy link
Member

laanwj commented Apr 24, 2018

The fact that the test suite passes with this removal is a smell though - how about a test for CreateTransaction or SelectCoins that fails with this removal?

This is what I was afraid of - I don't think we test the part of the wallet code that is used by the GUI coin selection very well.

@instagibbs instagibbs force-pushed the selectedcoins branch 2 times, most recently from d45a954 to ebc1934 Compare April 24, 2018 14:50
@instagibbs instagibbs changed the title remove redundant pre-selected coin code refactor pre-selected coin code Apr 24, 2018
@instagibbs
Copy link
Member Author

did some additional refactoring to make flow easier to follow(early return if you captured enough value with presets), and added a basic unit test that should have failed with previous broken iteration

coin_control2.ListSelected(coin_list);
BOOST_CHECK(setCoinsRet.size() == coin_list.size());
// "over-selected" since these were mandatory
BOOST_CHECK(nValueRet == (5+6+11) * CENT);
Copy link
Contributor

Choose a reason for hiding this comment

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

BOOST_CHECK_EQUAL here and above?

for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
{
if (setPresetCoins.count(CInputCoin(it->tx->tx, it->i)))
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this could be a const_iterator

Copy link
Member Author

Choose a reason for hiding this comment

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

no, it's deleting entries?

Copy link
Contributor

@Empact Empact Apr 26, 2018

Choose a reason for hiding this comment

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

The vector is deleting entries, the COutputs themselves are unmodified.

Copy link
Member Author

Choose a reason for hiding this comment

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

ah, I assume const_iterator was const for everything, including the underlying vector. TIL

(m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, nMaxChainLength/2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
(m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, nMaxChainLength), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
(m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
CAmount amount_to_select = nTargetValue - nValueFromPresetInputs;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: const

@instagibbs instagibbs force-pushed the selectedcoins branch 3 times, most recently from 1928a6f to 228469b Compare April 26, 2018 19:32
@instagibbs instagibbs force-pushed the selectedcoins branch 3 times, most recently from 0a2fca8 to c25c442 Compare June 11, 2018 20:06
@instagibbs
Copy link
Member Author

rebased, and did a tiny bit more refactoring for more readability.

@Empact
Copy link
Contributor

Empact commented Jun 12, 2018

You have some whitespace inconsistencies, clang-format would be good.

(m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
(m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
(m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
const CAmount amount_to_select = nTargetValue - nValueFromPresetInputs;
Copy link
Contributor

Choose a reason for hiding this comment

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

This loses the early return if nTargetValue <= nValueFromPresetInputs

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, thanks, in that case how about moving this assignment up to tie the two together?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

SelectCoinsMinConf(amount_to_select, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
SelectCoinsMinConf(amount_to_select, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
(!fRejectLongChains && SelectCoinsMinConf(amount_to_select, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
}
Copy link
Contributor

@Empact Empact Jun 12, 2018

Choose a reason for hiding this comment

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

nit: I like not having repeated tests of m_spend_zero_conf_change, but I would keep it as a single assignment.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@instagibbs instagibbs force-pushed the selectedcoins branch 3 times, most recently from 92572a0 to 31a0170 Compare June 12, 2018 00:44
@instagibbs
Copy link
Member Author

rebased

@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 13, 2019

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

Conflicts

No conflicts as of last run.

@DrahtBot
Copy link
Contributor

The last travis run for this pull request was 277 days ago and is thus outdated. To trigger a fresh travis build, this pull request should be closed and re-opened.

@DrahtBot DrahtBot closed this Apr 28, 2019
@DrahtBot DrahtBot reopened this Apr 28, 2019
@Empact
Copy link
Contributor

Empact commented Apr 29, 2019

utACK 4f0111e but this would be easier to review if it focused around the fix e.g.: Empact@3bcd12d

@instagibbs instagibbs closed this Jul 8, 2019
@laanwj
Copy link
Member

laanwj commented Jul 8, 2019

Any specific reason for closing this?

@instagibbs
Copy link
Member Author

No particular reason. Just something I didn't feel like pursuing review on.

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
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.

6 participants