@@ -63,6 +63,17 @@ static CAmount CreateCoins(FuzzedDataProvider& fuzzed_data_provider, std::vector
63
63
return total_balance;
64
64
}
65
65
66
+ static SelectionResult ManualSelection (std::vector<COutput>& utxos, const CAmount& total_amount, const bool & subtract_fee_outputs)
67
+ {
68
+ SelectionResult result (total_amount, SelectionAlgorithm::MANUAL);
69
+ std::set<std::shared_ptr<COutput>> utxo_pool;
70
+ for (const auto & utxo : utxos) {
71
+ utxo_pool.insert (std::make_shared<COutput>(utxo));
72
+ }
73
+ result.AddInputs (utxo_pool, subtract_fee_outputs);
74
+ return result;
75
+ }
76
+
66
77
// Returns true if the result contains an error and the message is not empty
67
78
static bool HasErrorMsg (const util::Result<SelectionResult>& res) { return !util::ErrorString (res).empty (); }
68
79
@@ -142,6 +153,21 @@ FUZZ_TARGET(coinselection)
142
153
assert (result->GetWeight () > weight);
143
154
}
144
155
}
156
+
157
+ std::vector<COutput> manual_inputs;
158
+ CAmount manual_balance{CreateCoins (fuzzed_data_provider, manual_inputs, coin_params, next_locktime)};
159
+ if (manual_balance == 0 ) return ;
160
+ auto manual_selection{ManualSelection (manual_inputs, manual_balance, coin_params.m_subtract_fee_outputs )};
161
+ for (auto & result : results) {
162
+ if (!result) continue ;
163
+ const CAmount old_target{result->GetTarget ()};
164
+ const std::set<std::shared_ptr<COutput>> input_set{result->GetInputSet ()};
165
+ const int old_weight{result->GetWeight ()};
166
+ result->Merge (manual_selection);
167
+ assert (result->GetInputSet ().size () == input_set.size () + manual_inputs.size ());
168
+ assert (result->GetTarget () == old_target + manual_selection.GetTarget ());
169
+ assert (result->GetWeight () == old_weight + manual_selection.GetWeight ());
170
+ }
145
171
}
146
172
147
173
} // namespace wallet
0 commit comments