@@ -63,6 +63,17 @@ static CAmount CreateCoins(FuzzedDataProvider& fuzzed_data_provider, std::vector
6363 return total_balance;
6464}
6565
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+
6677// Returns true if the result contains an error and the message is not empty
6778static bool HasErrorMsg (const util::Result<SelectionResult>& res) { return !util::ErrorString (res).empty (); }
6879
@@ -142,6 +153,21 @@ FUZZ_TARGET(coinselection)
142153 assert (result->GetWeight () > weight);
143154 }
144155 }
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+ }
145171}
146172
147173} // namespace wallet
0 commit comments