Skip to content

Commit

Permalink
draft: add test for lighter utxos
Browse files Browse the repository at this point in the history
  • Loading branch information
yancyribbens committed Jan 27, 2025
1 parent 9b3a7bc commit 43fcf37
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/coin_grinder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use bitcoin::Weight;
use bitcoin::amount::CheckedSum;

/// Performs a Branch Bound search that prioritizes input weight instead of amount. That is,
/// select the set of utxos that at least meets the target amount and has the lowest input
/// select the set of utxos that meets the target amount and has the lowest input
/// weight.
///
/// See also: <https://github.com/bitcoin/bitcoin/blob/62bd61de110b057cbfd6e31e4d0b727d93119c72/src/wallet/coinselection.cpp#L204>
Expand Down Expand Up @@ -124,12 +124,13 @@ pub fn select_coins<Utxo: WeightedUtxo>(
weighted_utxos: &[Utxo],
) -> Option<std::vec::IntoIter<&Utxo>> {
let mut w_utxos = calc_effective_values::<Utxo>(weighted_utxos, fee_rate);

let available_value = w_utxos.clone().into_iter().map(|(ev, _)| ev).checked_sum()?;

// descending sort by effective_value using weight as tie breaker.
// descending sort by effective_value using satisfaction weight as tie breaker.
w_utxos.sort_by(|a, b| {
b.0.cmp(&a.0)
.then(b.1.satisfaction_weight().cmp(&a.1.satisfaction_weight()))
.then(b.1.weight().cmp(&a.1.weight()))
});

let lookahead = build_lookahead(w_utxos.clone(), available_value);
Expand Down Expand Up @@ -163,6 +164,7 @@ pub fn select_coins<Utxo: WeightedUtxo>(

amount_sum += eff_value;
weight_sum += u.weight();

selection.push(next_utxo_index);
next_utxo_index += 1;

Expand Down Expand Up @@ -433,4 +435,23 @@ mod tests {

assert_coin_select_params(&params, Some(&expected));
}

#[test]
fn select_lighter_utxos() {
// Two UTXOs with a combined lower weight are selected over a singel UTXO where the single
// UTXO is heavier than the combined two less valuable UTXOs.
let params = ParamsStr {
target: "1.9 BTC",
change_target: "1000000 sats",
max_weight: "400000",
fee_rate: "5",
weighted_utxos: vec![
"2 BTC/592",
"1 BTC/272",
"1 BTC/272",
]
};

assert_coin_select_params(&params, Some(&["1 BTC", "1 BTC"]));
}
}

0 comments on commit 43fcf37

Please sign in to comment.