Skip to content

Commit 06ec8f9

Browse files
committed
wallet: make OutputGroup "positive_only" filter explicit
And not hide it inside the `OutputGroup::Insert` method. This method does not return anything if insertion fails. We can know before calling `Insert` whether the coin will be accepted or not.
1 parent 3b88c85 commit 06ec8f9

File tree

6 files changed

+20
-18
lines changed

6 files changed

+20
-18
lines changed

src/bench/coin_selection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static void add_coin(const CAmount& nValue, int nInput, std::vector<OutputGroup>
9191
tx.vout[nInput].nValue = nValue;
9292
COutput output(COutPoint(tx.GetHash(), nInput), tx.vout.at(nInput), /*depth=*/ 0, /*input_bytes=*/ -1, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, /*time=*/ 0, /*from_me=*/ true, /*fees=*/ 0);
9393
set.emplace_back();
94-
set.back().Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
94+
set.back().Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0);
9595
}
9696
// Copied from src/wallet/test/coinselector_tests.cpp
9797
static CAmount make_hard_case(int utxos, std::vector<OutputGroup>& utxo_pool)

src/wallet/coinselection.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,7 @@ std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups,
333333
334334
******************************************************************************/
335335

336-
void OutputGroup::Insert(const COutput& output, size_t ancestors, size_t descendants, bool positive_only) {
337-
// Filter for positive only here before adding the coin
338-
if (positive_only && output.GetEffectiveValue() <= 0) return;
339-
336+
void OutputGroup::Insert(const COutput& output, size_t ancestors, size_t descendants) {
340337
m_outputs.push_back(output);
341338
COutput& coin = m_outputs.back();
342339

src/wallet/coinselection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ struct OutputGroup
237237
m_subtract_fee_outputs(params.m_subtract_fee_outputs)
238238
{}
239239

240-
void Insert(const COutput& output, size_t ancestors, size_t descendants, bool positive_only);
240+
void Insert(const COutput& output, size_t ancestors, size_t descendants);
241241
bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const;
242242
CAmount GetSelectionAmount() const;
243243
};

src/wallet/spend.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -417,13 +417,14 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
417417
size_t ancestors, descendants;
418418
wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
419419

420-
// Make an OutputGroup containing just this output
421-
OutputGroup group{coin_sel_params};
422-
group.Insert(output, ancestors, descendants, positive_only);
420+
// If 'positive_only' is set, filter for positive only before adding the coin
421+
if (!positive_only || output.GetEffectiveValue() > 0) {
422+
// Make an OutputGroup containing just this output
423+
OutputGroup group{coin_sel_params};
424+
group.Insert(output, ancestors, descendants);
423425

424-
// Check the OutputGroup's eligibility. Only add the eligible ones.
425-
if (positive_only && group.GetSelectionAmount() <= 0) continue;
426-
if (group.m_outputs.size() > 0 && group.EligibleForSpending(filter)) groups_out.push_back(group);
426+
if (group.EligibleForSpending(filter)) groups_out.push_back(group);
427+
}
427428
}
428429
return groups_out;
429430
}
@@ -462,8 +463,10 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
462463
group = &groups.back();
463464
}
464465

465-
// Add the output to group
466-
group->Insert(output, ancestors, descendants, positive_only);
466+
// Filter for positive only before adding the output to group
467+
if (!positive_only || output.GetEffectiveValue() > 0) {
468+
group->Insert(output, ancestors, descendants);
469+
}
467470
}
468471

469472
// Now we go through the entire map and pull out the OutputGroups

src/wallet/test/coinselector_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void add_coin(const CAmount& nValue, int nInput, SelectionResult& result)
5353
tx.nLockTime = nextLockTime++; // so all transactions get different hashes
5454
COutput output(COutPoint(tx.GetHash(), nInput), tx.vout.at(nInput), /*depth=*/ 1, /*input_bytes=*/ -1, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, /*time=*/ 0, /*from_me=*/ false, /*fees=*/ 0);
5555
OutputGroup group;
56-
group.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ true);
56+
group.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0);
5757
result.AddInput(group);
5858
}
5959

@@ -134,7 +134,7 @@ inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& availabl
134134
static_groups.clear();
135135
for (auto& coin : available_coins) {
136136
static_groups.emplace_back();
137-
static_groups.back().Insert(coin, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
137+
static_groups.back().Insert(coin, /*ancestors=*/ 0, /*descendants=*/ 0);
138138
}
139139
return static_groups;
140140
}

src/wallet/test/fuzz/coinselection.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ static void GroupCoins(FuzzedDataProvider& fuzzed_data_provider, const std::vect
2929
auto output_group = OutputGroup(coin_params);
3030
bool valid_outputgroup{false};
3131
for (auto& coin : coins) {
32-
output_group.Insert(coin, /*ancestors=*/0, /*descendants=*/0, positive_only);
33-
// If positive_only was specified, nothing may have been inserted, leading to an empty output group
32+
if (!positive_only || (positive_only && coin.GetEffectiveValue() > 0)) {
33+
output_group.Insert(coin, /*ancestors=*/0, /*descendants=*/0);
34+
}
35+
// If positive_only was specified, nothing was inserted, leading to an empty output group
3436
// that would be invalid for the BnB algorithm
3537
valid_outputgroup = !positive_only || output_group.GetSelectionAmount() > 0;
3638
if (valid_outputgroup && fuzzed_data_provider.ConsumeBool()) {

0 commit comments

Comments
 (0)