-
Notifications
You must be signed in to change notification settings - Fork 4
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
docs for wallet and coin selection #5
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2478,7 +2478,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm | |
} | ||
} | ||
|
||
// remove preset inputs from vCoins | ||
// remove preset inputs from vCoins so that Coin Selection doesn't pick them. | ||
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();) | ||
{ | ||
if (setPresetCoins.count(it->GetInputCoin())) | ||
|
@@ -2490,9 +2490,9 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm | |
unsigned int limit_ancestor_count = 0; | ||
unsigned int limit_descendant_count = 0; | ||
chain().getPackageLimits(limit_ancestor_count, limit_descendant_count); | ||
size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count); | ||
size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count); | ||
bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); | ||
const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count); | ||
const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count); | ||
const bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); | ||
|
||
// form groups from remaining coins; note that preset coins will not | ||
// automatically have their associated (same address) coins included | ||
|
@@ -2502,16 +2502,53 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm | |
// explicitly shuffling the outputs before processing | ||
Shuffle(vCoins.begin(), vCoins.end(), FastRandomContext()); | ||
} | ||
bool res = value_to_select <= 0 || | ||
SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(1, 6, 0), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) || | ||
SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(1, 1, 0), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) || | ||
(m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, 2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) || | ||
(m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, std::min((size_t)4, max_ancestors/3), std::min((size_t)4, max_descendants/3)), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) || | ||
(m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) || | ||
(m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1, true /* include_partial_groups */), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) || | ||
(m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), true /* include_partial_groups */), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)); | ||
|
||
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset | ||
// Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the | ||
// transaction at a target value and feerate. If an attempt fails, more attempts may be made | ||
// using a more permissive CoinEligibilityFilter. | ||
const bool res = [&] { | ||
// Pre-selected inputs already cover the target amount. | ||
if (value_to_select <= 0) return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment for this line:
|
||
|
||
// If possible, fund the transaction with confirmed UTXOs only. Prefer at least six | ||
// confirmations on outputs received from other wallets and only spend confirmed change. | ||
if (SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(1, 6, 0), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) return true; | ||
if (SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(1, 1, 0), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) return true; | ||
|
||
// Fall back to using zero confirmation change (but with as few ancestors in the mempool as | ||
// possible) if we cannot fund the transaction otherwise. We never spend unconfirmed | ||
// outputs received from other wallets. | ||
Comment on lines
+2518
to
+2520
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about: |
||
if (m_spend_zero_conf_change) { | ||
if (SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, 2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) return true; | ||
if (SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, std::min((size_t)4, max_ancestors/3), std::min((size_t)4, max_descendants/3)), | ||
vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) { | ||
return true; | ||
} | ||
if (SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), | ||
vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) { | ||
return true; | ||
} | ||
// If partial groups are allowed, relax the requirement of spending OutputGroups (groups | ||
// of UTXOs sent to the same address, which are obviously controlled by a single wallet) | ||
// in their entirety. | ||
if (SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1, true /* include_partial_groups */), | ||
vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) { | ||
return true; | ||
} | ||
// Try with unlimited ancestors/descendants. The transaction will still need to meet | ||
// mempool ancestor/descendant policy to be accepted to mempool and broadcasted, but | ||
// OutputGroups use heuristics that may overestimate ancestor/descendant counts. | ||
if (!fRejectLongChains && SelectCoinsMinConf(value_to_select, | ||
CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), true /* include_partial_groups */), | ||
vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) { | ||
return true; | ||
} | ||
} | ||
// Coin Selection failed. | ||
return false; | ||
}(); | ||
|
||
// SelectCoinsMinConf clears setCoinsRet, so add the preset inputs from coin_control to the coinset | ||
util::insert(setCoinsRet, setPresetCoins); | ||
|
||
// add preset inputs to the total value selected | ||
|
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.
Useful to clarify what kinds of outputs are sent to ourselves.