Skip to content

Commit

Permalink
Deduplicate shift
Browse files Browse the repository at this point in the history
  • Loading branch information
murchandamus committed Jan 5, 2024
1 parent a295fda commit 05448cf
Showing 1 changed file with 28 additions and 25 deletions.
53 changes: 28 additions & 25 deletions src/wallet/coinselection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
curr_amount += utxo.GetSelectionAmount();
curr_weight += utxo.m_weight;
curr_selection.push_back(next_utxo);
++curr_try;
++next_utxo;
++curr_try;

// EVALUATE current selection, default to exploring the inclusion branch further, else do exactly one SHIFT or CUT.
if (curr_amount + lookahead[curr_selection.back()] < selection_target + change_target) {
Expand Down Expand Up @@ -340,42 +340,45 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
}

if (should_cut) {
// Redirect to exploring Omission branch of second to last selected UTXO (i.e. deselect last selected UTXO, then SHIFT)

// Neither adding to the current selection nor exploring the omission branch of the last selected UTXO can
// find any solutions. Redirect to exploring Omission branch of the penultimate selected UTXO (i.e. deselect
// last selected UTXO, then SHIFT)

should_cut = false;
deselect_last();
should_shift = true;
}

if (should_shift) {
// Set `next_utxo` to one after last selected, then deselect last selected UTXO
if (curr_selection.empty()) {
// Exhausted search space before running into attempt limit
result.SetAlgoCompleted(true);
break;
}
next_utxo = curr_selection.back() + 1;
deselect_last();
should_shift = false;
}

// Find next undecided UTXO that does not produce equivalent prefix
while (next_utxo > 0
&& (curr_selection.empty() || curr_selection.back() != next_utxo - 1)
&& utxo_pool[next_utxo - 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount()
&& utxo_pool[next_utxo - 1].fee == utxo_pool[next_utxo].fee) {
if (next_utxo < utxo_pool.size() - 1) {
// Skip if previous UTXO is equivalent and unselected
++next_utxo;
} else {
// "Skipping" end of branch: SHIFT instead
while (!is_done && should_shift) {
if (should_shift) {
// Set `next_utxo` to one after last selected, then deselect last selected UTXO
if (curr_selection.empty()) {
// Exhausted search space before running into limit
// Exhausted search space before running into attempt limit
is_done = true;
result.SetAlgoCompleted(true);
break;
}
next_utxo = curr_selection.back() + 1;
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 duplicate). 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 (!should_shift && next_utxo > 0
&& (curr_selection.empty() || curr_selection.back() != next_utxo - 1)
&& utxo_pool[next_utxo - 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount()
&& utxo_pool[next_utxo - 1].fee == utxo_pool[next_utxo].fee) {
if (next_utxo < utxo_pool.size() - 1) {
// Skip clone: previous UTXO is equivalent and unselected
++next_utxo;
} else {
// Reached end of UTXO pool skipping clones: SHIFT instead
should_shift = true;
}
}
}
}
Expand Down

0 comments on commit 05448cf

Please sign in to comment.