From 55916b8d9dc413e814422a43cfeebac8d8ecae04 Mon Sep 17 00:00:00 2001 From: gmart7t2 <49558347+gmart7t2@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:10:45 -0400 Subject: [PATCH] Select further away coins which meet target (#2724) --- src/subcommand/wallet/transaction_builder.rs | 62 +++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/subcommand/wallet/transaction_builder.rs b/src/subcommand/wallet/transaction_builder.rs index ebdecf6a79..fcfb322e76 100644 --- a/src/subcommand/wallet/transaction_builder.rs +++ b/src/subcommand/wallet/transaction_builder.rs @@ -697,7 +697,13 @@ impl TransactionBuilder { current_value >= target_value && is_closer }; - if is_preference_and_closer || not_preference_but_closer { + let newly_meets_preference = if prefer_under { + best_value > target_value && current_value <= target_value + } else { + best_value < target_value && current_value >= target_value + }; + + if is_preference_and_closer || not_preference_but_closer || newly_meets_preference { best_match = Some((*utxo, current_value)) } } @@ -1979,4 +1985,58 @@ mod tests { outpoint(2), ); } + + #[test] + fn prefer_further_away_utxos_if_they_are_newly_under_target() { + let utxos = vec![ + (outpoint(1), Amount::from_sat(510)), + (outpoint(2), Amount::from_sat(400)), + ]; + + let mut tx_builder = TransactionBuilder::new( + satpoint(0, 0), + BTreeMap::new(), + utxos.into_iter().collect(), + BTreeSet::new(), + recipient(), + [change(0), change(1)], + FeeRate::try_from(1.0).unwrap(), + Target::Value(Amount::from_sat(10_000)), + ); + + assert_eq!( + tx_builder + .select_cardinal_utxo(Amount::from_sat(500), true) + .unwrap() + .0, + outpoint(2), + ); + } + + #[test] + fn prefer_further_away_utxos_if_they_are_newly_over_target() { + let utxos = vec![ + (outpoint(1), Amount::from_sat(490)), + (outpoint(2), Amount::from_sat(600)), + ]; + + let mut tx_builder = TransactionBuilder::new( + satpoint(0, 0), + BTreeMap::new(), + utxos.into_iter().collect(), + BTreeSet::new(), + recipient(), + [change(0), change(1)], + FeeRate::try_from(1.0).unwrap(), + Target::Value(Amount::from_sat(10_000)), + ); + + assert_eq!( + tx_builder + .select_cardinal_utxo(Amount::from_sat(500), false) + .unwrap() + .0, + outpoint(2), + ); + } }