diff options
author | Andrew Chow <achow101-github@achow101.com> | 2020-11-16 14:24:08 -0500 |
---|---|---|
committer | Andrew Chow <achow101-github@achow101.com> | 2021-12-05 13:39:41 -0500 |
commit | 9d1d86da04d5d4768975338841285e90b01130b8 (patch) | |
tree | 84a0313cb6ea9ca5f5dc6bf173d08f5e57917a6f /src | |
parent | 94d851d28cb909a8f1f8ab795f1d9fc74bebfc7f (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/wallet/coinselection.cpp | 47 | ||||
-rw-r--r-- | src/wallet/coinselection.h | 35 |
2 files changed, 82 insertions, 0 deletions
diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp index e1ca3fb379..bfe3074944 100644 --- a/src/wallet/coinselection.cpp +++ b/src/wallet/coinselection.cpp @@ -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()); +} diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h index e7d467660f..056b1bce54 100644 --- a/src/wallet/coinselection.h +++ b/src/wallet/coinselection.h @@ -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 |