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.
This commit is contained in:
Andrew Chow 2020-11-16 14:24:08 -05:00
parent 94d851d28c
commit 9d1d86da04
2 changed files with 82 additions and 0 deletions

View File

@ -395,3 +395,50 @@ CAmount GetSelectionWaste(const std::set<CInputCoin>& inputs, CAmount change_cos
return waste;
}
void SelectionResult::ComputeAndSetWaste(CAmount change_cost)
{
m_waste = GetSelectionWaste(m_selected_inputs, change_cost, m_target, m_use_effective);
}
CAmount SelectionResult::GetWaste() const
{
Assume(m_waste != std::nullopt);
return *m_waste;
}
CAmount SelectionResult::GetSelectedValue() const
{
return std::accumulate(m_selected_inputs.cbegin(), m_selected_inputs.cend(), CAmount{0}, [](CAmount sum, const auto& coin) { return sum + coin.txout.nValue; });
}
void SelectionResult::Clear()
{
m_selected_inputs.clear();
m_waste.reset();
}
void SelectionResult::AddInput(const OutputGroup& group)
{
util::insert(m_selected_inputs, group.m_outputs);
}
const std::set<CInputCoin>& SelectionResult::GetInputSet() const
{
return m_selected_inputs;
}
std::vector<CInputCoin> SelectionResult::GetShuffledInputVector() const
{
std::vector<CInputCoin> coins(m_selected_inputs.begin(), m_selected_inputs.end());
Shuffle(coins.begin(), coins.end(), FastRandomContext());
return coins;
}
bool SelectionResult::operator<(SelectionResult other) const
{
Assume(m_waste != std::nullopt);
Assume(other.m_waste != std::nullopt);
// As this operator is only used in std::min_element, we want the result that has more inputs when waste are equal.
return *m_waste < *other.m_waste || (*m_waste == *other.m_waste && m_selected_inputs.size() > other.m_selected_inputs.size());
}

View File

@ -197,6 +197,41 @@ struct OutputGroup
*/
[[nodiscard]] CAmount GetSelectionWaste(const std::set<CInputCoin>& inputs, CAmount change_cost, CAmount target, bool use_effective_value = true);
struct SelectionResult
{
/** Set of inputs selected by the algorithm to use in the transaction */
std::set<CInputCoin> m_selected_inputs;
/** The target the algorithm selected for. Note that this may not be equal to the recipient amount as it can include non-input fees */
const CAmount m_target;
/** Whether the input values for calculations should be the effective value (true) or normal value (false) */
bool m_use_effective{false};
/** The computed waste */
std::optional<CAmount> m_waste;
explicit SelectionResult(const CAmount target)
: m_target(target) {}
SelectionResult() = delete;
/** Get the sum of the input values */
[[nodiscard]] CAmount GetSelectedValue() const;
void Clear();
void AddInput(const OutputGroup& group);
/** Calculates and stores the waste for this selection via GetSelectionWaste */
void ComputeAndSetWaste(CAmount change_cost);
[[nodiscard]] CAmount GetWaste() const;
/** Get m_selected_inputs */
const std::set<CInputCoin>& GetInputSet() const;
/** Get the vector of CInputCoins that will be used to fill in a CTransaction's vin */
std::vector<CInputCoin> GetShuffledInputVector() const;
bool operator<(SelectionResult other) const;
};
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret);
/** Select coins by Single Random Draw. OutputGroups are selected randomly from the eligible