aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2019-11-06 14:35:11 -0500
committerAndrew Chow <achow101-github@achow101.com>2021-09-23 13:33:25 -0400
commit8bf789b4b4b26082aea1d91c4d7aa8b01aedfdcf (patch)
tree5b7e6d05db8d18d78a1dd02c420ac23b3454d5e9
parent2ad3b5d2ad03f781f564ee697ef11e18b2edcea3 (diff)
downloadbitcoin-8bf789b4b4b26082aea1d91c4d7aa8b01aedfdcf.tar.xz
Add SelectCoinsSRD function
-rw-r--r--src/wallet/coinselection.cpp26
-rw-r--r--src/wallet/coinselection.h11
2 files changed, 37 insertions, 0 deletions
diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp
index 1699424657..d2f30abf23 100644
--- a/src/wallet/coinselection.cpp
+++ b/src/wallet/coinselection.cpp
@@ -5,9 +5,11 @@
#include <wallet/coinselection.h>
#include <policy/feerate.h>
+#include <util/check.h>
#include <util/system.h>
#include <util/moneystr.h>
+#include <numeric>
#include <optional>
// Descending order comparator
@@ -168,6 +170,30 @@ bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selectio
return true;
}
+std::optional<std::pair<std::set<CInputCoin>, CAmount>> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value)
+{
+ std::set<CInputCoin> out_set;
+ CAmount value_ret = 0;
+
+ std::vector<size_t> indexes;
+ indexes.resize(utxo_pool.size());
+ std::iota(indexes.begin(), indexes.end(), 0);
+ Shuffle(indexes.begin(), indexes.end(), FastRandomContext());
+
+ CAmount selected_eff_value = 0;
+ for (const size_t i : indexes) {
+ const OutputGroup& group = utxo_pool.at(i);
+ Assume(group.GetSelectionAmount() > 0);
+ selected_eff_value += group.GetSelectionAmount();
+ value_ret += group.m_value;
+ util::insert(out_set, group.m_outputs);
+ if (selected_eff_value >= target_value) {
+ return std::make_pair(out_set, value_ret);
+ }
+ }
+ return std::nullopt;
+}
+
static void ApproximateBestSubset(const std::vector<OutputGroup>& groups, const CAmount& nTotalLower, const CAmount& nTargetValue,
std::vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
{
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index 35617d455b..0f07017ef2 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -10,6 +10,8 @@
#include <primitives/transaction.h>
#include <random.h>
+#include <optional>
+
//! target minimum change amount
static constexpr CAmount MIN_CHANGE{COIN / 100};
//! final minimum change amount after paying for fees
@@ -183,6 +185,15 @@ struct OutputGroup
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
+ * outputs until the target is satisfied
+ *
+ * @param[in] utxo_pool The positive effective value OutputGroups eligible for selection
+ * @param[in] target_value The target value to select for
+ * @returns If successful, a pair of set of outputs and total selected value, otherwise, std::nullopt
+ */
+std::optional<std::pair<std::set<CInputCoin>, CAmount>> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value);
+
// Original coin selection algorithm as a fallback
bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet);