Skip to content

Commit 9d1d86d

Browse files
committed
Introduce SelectionResult struct
Introduces a SelectionResult struct which contains the set of selected inputs and the total transaction fee for the transaction. This will be used by the various SelectCoins* functions. Additionally helpers are provided to compute the total input value and result comparisons.
1 parent 94d851d commit 9d1d86d

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/wallet/coinselection.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,50 @@ CAmount GetSelectionWaste(const std::set<CInputCoin>& inputs, CAmount change_cos
395395

396396
return waste;
397397
}
398+
399+
void SelectionResult::ComputeAndSetWaste(CAmount change_cost)
400+
{
401+
m_waste = GetSelectionWaste(m_selected_inputs, change_cost, m_target, m_use_effective);
402+
}
403+
404+
CAmount SelectionResult::GetWaste() const
405+
{
406+
Assume(m_waste != std::nullopt);
407+
return *m_waste;
408+
}
409+
410+
CAmount SelectionResult::GetSelectedValue() const
411+
{
412+
return std::accumulate(m_selected_inputs.cbegin(), m_selected_inputs.cend(), CAmount{0}, [](CAmount sum, const auto& coin) { return sum + coin.txout.nValue; });
413+
}
414+
415+
void SelectionResult::Clear()
416+
{
417+
m_selected_inputs.clear();
418+
m_waste.reset();
419+
}
420+
421+
void SelectionResult::AddInput(const OutputGroup& group)
422+
{
423+
util::insert(m_selected_inputs, group.m_outputs);
424+
}
425+
426+
const std::set<CInputCoin>& SelectionResult::GetInputSet() const
427+
{
428+
return m_selected_inputs;
429+
}
430+
431+
std::vector<CInputCoin> SelectionResult::GetShuffledInputVector() const
432+
{
433+
std::vector<CInputCoin> coins(m_selected_inputs.begin(), m_selected_inputs.end());
434+
Shuffle(coins.begin(), coins.end(), FastRandomContext());
435+
return coins;
436+
}
437+
438+
bool SelectionResult::operator<(SelectionResult other) const
439+
{
440+
Assume(m_waste != std::nullopt);
441+
Assume(other.m_waste != std::nullopt);
442+
// As this operator is only used in std::min_element, we want the result that has more inputs when waste are equal.
443+
return *m_waste < *other.m_waste || (*m_waste == *other.m_waste && m_selected_inputs.size() > other.m_selected_inputs.size());
444+
}

src/wallet/coinselection.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,41 @@ struct OutputGroup
197197
*/
198198
[[nodiscard]] CAmount GetSelectionWaste(const std::set<CInputCoin>& inputs, CAmount change_cost, CAmount target, bool use_effective_value = true);
199199

200+
struct SelectionResult
201+
{
202+
/** Set of inputs selected by the algorithm to use in the transaction */
203+
std::set<CInputCoin> m_selected_inputs;
204+
/** The target the algorithm selected for. Note that this may not be equal to the recipient amount as it can include non-input fees */
205+
const CAmount m_target;
206+
/** Whether the input values for calculations should be the effective value (true) or normal value (false) */
207+
bool m_use_effective{false};
208+
/** The computed waste */
209+
std::optional<CAmount> m_waste;
210+
211+
explicit SelectionResult(const CAmount target)
212+
: m_target(target) {}
213+
214+
SelectionResult() = delete;
215+
216+
/** Get the sum of the input values */
217+
[[nodiscard]] CAmount GetSelectedValue() const;
218+
219+
void Clear();
220+
221+
void AddInput(const OutputGroup& group);
222+
223+
/** Calculates and stores the waste for this selection via GetSelectionWaste */
224+
void ComputeAndSetWaste(CAmount change_cost);
225+
[[nodiscard]] CAmount GetWaste() const;
226+
227+
/** Get m_selected_inputs */
228+
const std::set<CInputCoin>& GetInputSet() const;
229+
/** Get the vector of CInputCoins that will be used to fill in a CTransaction's vin */
230+
std::vector<CInputCoin> GetShuffledInputVector() const;
231+
232+
bool operator<(SelectionResult other) const;
233+
};
234+
200235
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret);
201236

202237
/** Select coins by Single Random Draw. OutputGroups are selected randomly from the eligible

0 commit comments

Comments
 (0)