Skip to content

Commit 8bf789b

Browse files
committed
Add SelectCoinsSRD function
1 parent 2ad3b5d commit 8bf789b

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/wallet/coinselection.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
#include <wallet/coinselection.h>
66

77
#include <policy/feerate.h>
8+
#include <util/check.h>
89
#include <util/system.h>
910
#include <util/moneystr.h>
1011

12+
#include <numeric>
1113
#include <optional>
1214

1315
// Descending order comparator
@@ -168,6 +170,30 @@ bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selectio
168170
return true;
169171
}
170172

173+
std::optional<std::pair<std::set<CInputCoin>, CAmount>> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value)
174+
{
175+
std::set<CInputCoin> out_set;
176+
CAmount value_ret = 0;
177+
178+
std::vector<size_t> indexes;
179+
indexes.resize(utxo_pool.size());
180+
std::iota(indexes.begin(), indexes.end(), 0);
181+
Shuffle(indexes.begin(), indexes.end(), FastRandomContext());
182+
183+
CAmount selected_eff_value = 0;
184+
for (const size_t i : indexes) {
185+
const OutputGroup& group = utxo_pool.at(i);
186+
Assume(group.GetSelectionAmount() > 0);
187+
selected_eff_value += group.GetSelectionAmount();
188+
value_ret += group.m_value;
189+
util::insert(out_set, group.m_outputs);
190+
if (selected_eff_value >= target_value) {
191+
return std::make_pair(out_set, value_ret);
192+
}
193+
}
194+
return std::nullopt;
195+
}
196+
171197
static void ApproximateBestSubset(const std::vector<OutputGroup>& groups, const CAmount& nTotalLower, const CAmount& nTargetValue,
172198
std::vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
173199
{

src/wallet/coinselection.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <primitives/transaction.h>
1111
#include <random.h>
1212

13+
#include <optional>
14+
1315
//! target minimum change amount
1416
static constexpr CAmount MIN_CHANGE{COIN / 100};
1517
//! final minimum change amount after paying for fees
@@ -183,6 +185,15 @@ struct OutputGroup
183185

184186
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret);
185187

188+
/** Select coins by Single Random Draw. OutputGroups are selected randomly from the eligible
189+
* outputs until the target is satisfied
190+
*
191+
* @param[in] utxo_pool The positive effective value OutputGroups eligible for selection
192+
* @param[in] target_value The target value to select for
193+
* @returns If successful, a pair of set of outputs and total selected value, otherwise, std::nullopt
194+
*/
195+
std::optional<std::pair<std::set<CInputCoin>, CAmount>> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value);
196+
186197
// Original coin selection algorithm as a fallback
187198
bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet);
188199

0 commit comments

Comments
 (0)