From 5248e2a60d243b3d5c77ecd9e4c335daca399a48 Mon Sep 17 00:00:00 2001 From: Murch Date: Thu, 1 Feb 2024 16:25:45 -0500 Subject: [PATCH] opt: Skip heavier UTXOs with same effective value When two successive UTXOs differ in weight but match in effective value, we can skip the second if the first is not selected, because all input sets we can generate by swapping out a lighter UTXOs with a heavier UTXO of matching effective value would be strictly worse. --- src/wallet/coinselection.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp index 9cad76574a2..1542871daf3 100644 --- a/src/wallet/coinselection.cpp +++ b/src/wallet/coinselection.cpp @@ -479,12 +479,12 @@ util::Result CoinGrinder(std::vector& utxo_pool, c deselect_last(); should_shift = false; - // After SHIFTing to an omission branch, the `next_utxo` might have the same value and same weight as the - // UTXO we just omitted (i.e. it is a "clone"). If so, selecting `next_utxo` would produce an equivalent - // selection as one we previously evaluated. In that case, increment `next_utxo` until we find a UTXO with a - // differing amount or weight. - while (utxo_pool[next_utxo - 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount() - && utxo_pool[next_utxo - 1].m_weight == utxo_pool[next_utxo].m_weight) { + // After SHIFTing to an omission branch, the `next_utxo` might have the same effective value as the UTXO we + // just omitted. Since lower weight is our tiebreaker on UTXOs with equal effective value for sorting, if it + // ties on the effective value, it _must_ have the same weight (i.e. be a "clone" of the prior UTXO) or a + // higher weight. If so, selecting `next_utxo` would produce an equivalent or worse selection as one we + // previously evaluated. In that case, increment `next_utxo` until we find a UTXO with a differing amount. + while (utxo_pool[next_utxo - 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount()) { if (next_utxo >= utxo_pool.size() - 1) { // Reached end of UTXO pool skipping clones: SHIFT instead should_shift = true;