@@ -405,8 +405,8 @@ CoinsResult AvailableCoins(const CWallet& wallet,
405405 if (wtx.truc_child_in_mempool .has_value ()) continue ;
406406
407407 // this unconfirmed v3 transaction has a parent: spending would create a third generation
408- size_t ancestors, descendants ;
409- wallet.chain ().getTransactionAncestry (wtx.tx ->GetHash (), ancestors, descendants );
408+ size_t ancestors, unused_cluster_count ;
409+ wallet.chain ().getTransactionAncestry (wtx.tx ->GetHash (), ancestors, unused_cluster_count );
410410 if (ancestors > 1 ) continue ;
411411 } else {
412412 if (wtx.tx ->version == TRUC_VERSION) continue ;
@@ -866,11 +866,16 @@ util::Result<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& av
866866
867867util::Result<SelectionResult> AutomaticCoinSelection (const CWallet& wallet, CoinsResult& available_coins, const CAmount& value_to_select, const CoinSelectionParams& coin_selection_params)
868868{
869+ // Try to enforce a mixture of cluster limits and ancestor/descendant limits on transactions we create by limiting
870+ // the ancestors and the maximum cluster count of any UTXO we use. We use the ancestor/descendant limits, which are
871+ // lower than the cluster limits, to avoid exceeding any ancestor/descendant limits of legacy nodes. This filter is safe
872+ // because a transaction's ancestor or descendant count cannot be larger than its cluster count.
873+ // TODO: these limits can be relaxed in the future, and we can replace the ancestor filter with a cluster equivalent.
869874 unsigned int limit_ancestor_count = 0 ;
870875 unsigned int limit_descendant_count = 0 ;
871876 wallet.chain ().getPackageLimits (limit_ancestor_count, limit_descendant_count);
872877 const size_t max_ancestors = (size_t )std::max<int64_t >(1 , limit_ancestor_count);
873- const size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
878+ const size_t max_cluster_count = (size_t )std::max<int64_t >(1 , limit_descendant_count);
874879 const bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
875880
876881 // Cases where we have 101+ outputs all pointing to the same destination may result in
@@ -895,20 +900,21 @@ util::Result<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, Coin
895900 // possible) if we cannot fund the transaction otherwise.
896901 if (wallet.m_spend_zero_conf_change ) {
897902 ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , 2 )});
898- ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , std::min (size_t {4 }, max_ancestors/3 ), std::min (size_t {4 }, max_descendants /3 ))});
899- ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants /2 )});
903+ ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , std::min (size_t {4 }, max_ancestors/3 ), std::min (size_t {4 }, max_cluster_count /3 ))});
904+ ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_cluster_count /2 )});
900905 // If partial groups are allowed, relax the requirement of spending OutputGroups (groups
901906 // of UTXOs sent to the same address, which are obviously controlled by a single wallet)
902907 // in their entirety.
903- ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants -1 , /* include_partial=*/ true )});
908+ ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_cluster_count -1 , /* include_partial=*/ true )});
904909 // Try with unsafe inputs if they are allowed. This may spend unconfirmed outputs
905910 // received from other wallets.
906911 if (coin_selection_params.m_include_unsafe_inputs ) {
907- ordered_filters.push_back ({CoinEligibilityFilter (/* conf_mine=*/ 0 , /* conf_theirs*/ 0 , max_ancestors-1 , max_descendants -1 , /* include_partial=*/ true )});
912+ ordered_filters.push_back ({CoinEligibilityFilter (/* conf_mine=*/ 0 , /* conf_theirs*/ 0 , max_ancestors-1 , max_cluster_count -1 , /* include_partial=*/ true )});
908913 }
909- // Try with unlimited ancestors/descendants. The transaction will still need to meet
910- // mempool ancestor/descendant policy to be accepted to mempool and broadcasted, but
911- // OutputGroups use heuristics that may overestimate ancestor/descendant counts.
914+ // Try with unlimited ancestors/clusters. The transaction will still need to meet
915+ // local mempool policy (i.e. cluster limits) to be accepted to mempool and broadcasted, and
916+ // limits of other nodes (e.g. ancestor/descendant limits) to propagate, but OutputGroups
917+ // use heuristics that may overestimate.
912918 if (!fRejectLongChains ) {
913919 ordered_filters.push_back ({CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max (),
914920 std::numeric_limits<uint64_t >::max (),
@@ -925,7 +931,7 @@ util::Result<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, Coin
925931 CAmount total_unconf_long_chain = 0 ;
926932 for (const auto & group : discarded_groups) {
927933 total_discarded += group.GetSelectionAmount ();
928- if (group.m_ancestors >= max_ancestors || group.m_descendants >= max_descendants ) total_unconf_long_chain += group.GetSelectionAmount ();
934+ if (group.m_ancestors >= max_ancestors || group.m_max_cluster_count >= max_cluster_count ) total_unconf_long_chain += group.GetSelectionAmount ();
929935 }
930936
931937 if (CAmount total_amount = available_coins.GetTotalAmount () - total_discarded < value_to_select) {
0 commit comments