| 866 | } |
| 867 | |
| 868 | util::Result<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, CoinsResult& available_coins, const CAmount& value_to_select, const CoinSelectionParams& coin_selection_params) |
| 869 | { |
| 870 | // Try to enforce a mixture of cluster limits and ancestor/descendant limits on transactions we create by limiting |
| 871 | // the ancestors and the maximum cluster count of any UTXO we use. We use the ancestor/descendant limits, which are |
| 872 | // lower than the cluster limits, to avoid exceeding any ancestor/descendant limits of legacy nodes. This filter is safe |
| 873 | // because a transaction's ancestor or descendant count cannot be larger than its cluster count. |
| 874 | // TODO: these limits can be relaxed in the future, and we can replace the ancestor filter with a cluster equivalent. |
| 875 | unsigned int limit_ancestor_count = 0; |
| 876 | unsigned int limit_descendant_count = 0; |
| 877 | wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count); |
| 878 | const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count); |
| 879 | const size_t max_cluster_count = (size_t)std::max<int64_t>(1, limit_descendant_count); |
| 880 | const bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); |
| 881 | |
| 882 | // Cases where we have 101+ outputs all pointing to the same destination may result in |
| 883 | // privacy leaks as they will potentially be deterministically sorted. We solve that by |
| 884 | // explicitly shuffling the outputs before processing |
| 885 | if (coin_selection_params.m_avoid_partial_spends && available_coins.Size() > OUTPUT_GROUP_MAX_ENTRIES) { |
| 886 | available_coins.Shuffle(coin_selection_params.rng_fast); |
| 887 | } |
| 888 | |
| 889 | // Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the |
| 890 | // transaction at a target feerate. If an attempt fails, more attempts may be made using a more |
| 891 | // permissive CoinEligibilityFilter. |
| 892 | { |
| 893 | // Place coins eligibility filters on a scope increasing order. |
| 894 | std::vector<SelectionFilter> ordered_filters{ |
| 895 | // If possible, fund the transaction with confirmed UTXOs only. Prefer at least six |
| 896 | // confirmations on outputs received from other wallets and only spend confirmed change. |
| 897 | {CoinEligibilityFilter(1, 6, 0), /*allow_mixed_output_types=*/false}, |
| 898 | {CoinEligibilityFilter(1, 1, 0)}, |
| 899 | }; |
| 900 | // Fall back to using zero confirmation change (but with as few ancestors in the mempool as |
| 901 | // possible) if we cannot fund the transaction otherwise. |
| 902 | if (wallet.m_spend_zero_conf_change) { |
| 903 | ordered_filters.push_back({CoinEligibilityFilter(0, 1, 2)}); |
| 904 | ordered_filters.push_back({CoinEligibilityFilter(0, 1, std::min(size_t{4}, max_ancestors/3), std::min(size_t{4}, max_cluster_count/3))}); |
| 905 | ordered_filters.push_back({CoinEligibilityFilter(0, 1, max_ancestors/2, max_cluster_count/2)}); |
| 906 | // If partial groups are allowed, relax the requirement of spending OutputGroups (groups |
| 907 | // of UTXOs sent to the same address, which are obviously controlled by a single wallet) |
| 908 | // in their entirety. |
| 909 | ordered_filters.push_back({CoinEligibilityFilter(0, 1, max_ancestors-1, max_cluster_count-1, /*include_partial=*/true)}); |
| 910 | // Try with unsafe inputs if they are allowed. This may spend unconfirmed outputs |
| 911 | // received from other wallets. |
| 912 | if (coin_selection_params.m_include_unsafe_inputs) { |
| 913 | ordered_filters.push_back({CoinEligibilityFilter(/*conf_mine=*/0, /*conf_theirs=*/0, max_ancestors-1, max_cluster_count-1, /*include_partial=*/true)}); |
| 914 | } |
| 915 | // Try with unlimited ancestors/clusters. The transaction will still need to meet |
| 916 | // local mempool policy (i.e. cluster limits) to be accepted to mempool and broadcasted, and |
| 917 | // limits of other nodes (e.g. ancestor/descendant limits) to propagate, but OutputGroups |
| 918 | // use heuristics that may overestimate. |
| 919 | if (!fRejectLongChains) { |
| 920 | ordered_filters.push_back({CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max(), |
| 921 | std::numeric_limits<uint64_t>::max(), |
| 922 | /*include_partial=*/true)}); |
| 923 | } |
| 924 | } |
| 925 |
no test coverage detected