aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2022-03-21 14:19:10 -0400
committerAndrew Chow <achow101-github@achow101.com>2022-04-14 12:40:36 -0400
commit912f1ed181161b0365776cd490b63137aaad708a (patch)
tree40a554a56263010294a661a6f75159e811b94300
parentb69fd5eaa99f84b62a49d7c7f48d8cee1227592a (diff)
wallet: track which coin selection algorithm produced a SelectionResult
-rw-r--r--src/wallet/coinselection.cpp19
-rw-r--r--src/wallet/coinselection.h16
-rw-r--r--src/wallet/spend.cpp4
-rw-r--r--src/wallet/test/coinselector_tests.cpp2
4 files changed, 33 insertions, 8 deletions
diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp
index 433759e086..0b236e2e48 100644
--- a/src/wallet/coinselection.cpp
+++ b/src/wallet/coinselection.cpp
@@ -64,7 +64,7 @@ static const size_t TOTAL_TRIES = 100000;
std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change)
{
- SelectionResult result(selection_target);
+ SelectionResult result(selection_target, SelectionAlgorithm::BNB);
CAmount curr_value = 0;
std::vector<size_t> curr_selection; // selected utxo indexes
@@ -167,7 +167,7 @@ std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_poo
std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, FastRandomContext& rng)
{
- SelectionResult result(target_value);
+ SelectionResult result(target_value, SelectionAlgorithm::SRD);
std::vector<size_t> indexes;
indexes.resize(utxo_pool.size());
@@ -249,7 +249,7 @@ static void ApproximateBestSubset(FastRandomContext& insecure_rand, const std::v
std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue,
CAmount change_target, FastRandomContext& rng)
{
- SelectionResult result(nTargetValue);
+ SelectionResult result(nTargetValue, SelectionAlgorithm::KNAPSACK);
// List of values less than target
std::optional<OutputGroup> lowest_larger;
@@ -460,4 +460,17 @@ std::string COutput::ToString() const
{
return strprintf("COutput(%s, %d, %d) [%s]", outpoint.hash.ToString(), outpoint.n, depth, FormatMoney(txout.nValue));
}
+
+std::string GetAlgorithmName(const SelectionAlgorithm algo)
+{
+ switch (algo)
+ {
+ case SelectionAlgorithm::BNB: return "bnb";
+ case SelectionAlgorithm::KNAPSACK: return "knapsack";
+ case SelectionAlgorithm::SRD: return "srd";
+ case SelectionAlgorithm::MANUAL: return "manual";
+ // No default case to allow for compiler to warn
+ }
+ assert(false);
+}
} // namespace wallet
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index c1484c0a57..44eec9a417 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -239,6 +239,16 @@ struct OutputGroup
*/
[[nodiscard]] CAmount GenerateChangeTarget(CAmount payment_value, FastRandomContext& rng);
+enum class SelectionAlgorithm : uint8_t
+{
+ BNB = 0,
+ KNAPSACK = 1,
+ SRD = 2,
+ MANUAL = 3,
+};
+
+std::string GetAlgorithmName(const SelectionAlgorithm algo);
+
struct SelectionResult
{
private:
@@ -250,10 +260,12 @@ private:
bool m_use_effective{false};
/** The computed waste */
std::optional<CAmount> m_waste;
+ /** The algorithm used to produce this result */
+ SelectionAlgorithm m_algo;
public:
- explicit SelectionResult(const CAmount target)
- : m_target(target) {}
+ explicit SelectionResult(const CAmount target, SelectionAlgorithm algo)
+ : m_target(target), m_algo(algo) {}
SelectionResult() = delete;
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index 9e508f3a32..b4b726d4fd 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -435,7 +435,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
*/
preset_inputs.Insert(out, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
}
- SelectionResult result(nTargetValue);
+ SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
result.AddInput(preset_inputs);
if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
return result;
@@ -519,7 +519,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
// permissive CoinEligibilityFilter.
std::optional<SelectionResult> res = [&] {
// Pre-selected inputs already cover the target amount.
- if (value_to_select <= 0) return std::make_optional(SelectionResult(nTargetValue));
+ if (value_to_select <= 0) return std::make_optional(SelectionResult(nTargetValue, SelectionAlgorithm::MANUAL));
// If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
// confirmations on outputs received from other wallets and only spend confirmed change.
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index 2a08c8ab57..72e749477b 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
FastRandomContext rand{};
// Setup
std::vector<COutput> utxo_pool;
- SelectionResult expected_result(CAmount(0));
+ SelectionResult expected_result(CAmount(0), SelectionAlgorithm::BNB);
/////////////////////////
// Known Outcome tests //