Skip to content

Commit 912f1ed

Browse files
committed
wallet: track which coin selection algorithm produced a SelectionResult
1 parent b69fd5e commit 912f1ed

File tree

4 files changed

+33
-8
lines changed

4 files changed

+33
-8
lines changed

src/wallet/coinselection.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ static const size_t TOTAL_TRIES = 100000;
6464

6565
std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change)
6666
{
67-
SelectionResult result(selection_target);
67+
SelectionResult result(selection_target, SelectionAlgorithm::BNB);
6868
CAmount curr_value = 0;
6969
std::vector<size_t> curr_selection; // selected utxo indexes
7070

@@ -167,7 +167,7 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
167167

168168
std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, FastRandomContext& rng)
169169
{
170-
SelectionResult result(target_value);
170+
SelectionResult result(target_value, SelectionAlgorithm::SRD);
171171

172172
std::vector<size_t> indexes;
173173
indexes.resize(utxo_pool.size());
@@ -249,7 +249,7 @@ static void ApproximateBestSubset(FastRandomContext& insecure_rand, const std::v
249249
std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
250250
CAmount change_target, FastRandomContext& rng)
251251
{
252-
SelectionResult result(nTargetValue);
252+
SelectionResult result(nTargetValue, SelectionAlgorithm::KNAPSACK);
253253

254254
// List of values less than target
255255
std::optional<OutputGroup> lowest_larger;
@@ -460,4 +460,17 @@ std::string COutput::ToString() const
460460
{
461461
return strprintf("COutput(%s, %d, %d) [%s]", outpoint.hash.ToString(), outpoint.n, depth, FormatMoney(txout.nValue));
462462
}
463+
464+
std::string GetAlgorithmName(const SelectionAlgorithm algo)
465+
{
466+
switch (algo)
467+
{
468+
case SelectionAlgorithm::BNB: return "bnb";
469+
case SelectionAlgorithm::KNAPSACK: return "knapsack";
470+
case SelectionAlgorithm::SRD: return "srd";
471+
case SelectionAlgorithm::MANUAL: return "manual";
472+
// No default case to allow for compiler to warn
473+
}
474+
assert(false);
475+
}
463476
} // namespace wallet

src/wallet/coinselection.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,16 @@ struct OutputGroup
239239
*/
240240
[[nodiscard]] CAmount GenerateChangeTarget(CAmount payment_value, FastRandomContext& rng);
241241

242+
enum class SelectionAlgorithm : uint8_t
243+
{
244+
BNB = 0,
245+
KNAPSACK = 1,
246+
SRD = 2,
247+
MANUAL = 3,
248+
};
249+
250+
std::string GetAlgorithmName(const SelectionAlgorithm algo);
251+
242252
struct SelectionResult
243253
{
244254
private:
@@ -250,10 +260,12 @@ struct SelectionResult
250260
bool m_use_effective{false};
251261
/** The computed waste */
252262
std::optional<CAmount> m_waste;
263+
/** The algorithm used to produce this result */
264+
SelectionAlgorithm m_algo;
253265

254266
public:
255-
explicit SelectionResult(const CAmount target)
256-
: m_target(target) {}
267+
explicit SelectionResult(const CAmount target, SelectionAlgorithm algo)
268+
: m_target(target), m_algo(algo) {}
257269

258270
SelectionResult() = delete;
259271

src/wallet/spend.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
435435
*/
436436
preset_inputs.Insert(out, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
437437
}
438-
SelectionResult result(nTargetValue);
438+
SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
439439
result.AddInput(preset_inputs);
440440
if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
441441
return result;
@@ -519,7 +519,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
519519
// permissive CoinEligibilityFilter.
520520
std::optional<SelectionResult> res = [&] {
521521
// Pre-selected inputs already cover the target amount.
522-
if (value_to_select <= 0) return std::make_optional(SelectionResult(nTargetValue));
522+
if (value_to_select <= 0) return std::make_optional(SelectionResult(nTargetValue, SelectionAlgorithm::MANUAL));
523523

524524
// If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
525525
// confirmations on outputs received from other wallets and only spend confirmed change.

src/wallet/test/coinselector_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
168168
FastRandomContext rand{};
169169
// Setup
170170
std::vector<COutput> utxo_pool;
171-
SelectionResult expected_result(CAmount(0));
171+
SelectionResult expected_result(CAmount(0), SelectionAlgorithm::BNB);
172172

173173
/////////////////////////
174174
// Known Outcome tests //

0 commit comments

Comments
 (0)