Line data Source code
1 : // Copyright (c) 2021 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include <coinjoin/common.h>
6 : #include <coinjoin/options.h>
7 : #include <consensus/consensus.h>
8 : #include <consensus/validation.h>
9 : #include <evo/dmn_types.h>
10 : #include <interfaces/chain.h>
11 : #include <policy/policy.h>
12 : #include <script/signingprovider.h>
13 : #include <util/check.h>
14 : #include <util/fees.h>
15 : #include <util/moneystr.h>
16 : #include <util/trace.h>
17 : #include <util/translation.h>
18 : #include <wallet/coincontrol.h>
19 : #include <wallet/fees.h>
20 : #include <wallet/receive.h>
21 : #include <wallet/spend.h>
22 : #include <wallet/transaction.h>
23 : #include <wallet/wallet.h>
24 :
25 : #include <cmath>
26 :
27 : using interfaces::FoundBlock;
28 :
29 : namespace wallet {
30 : static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES{100};
31 :
32 112410 : int CalculateMaximumSignedInputSize(const CTxOut& txout, const COutPoint outpoint, const SigningProvider* provider, const CCoinControl* coin_control)
33 : {
34 112410 : CMutableTransaction txn;
35 112410 : txn.vin.push_back(CTxIn(outpoint));
36 112410 : if (!provider || !DummySignInput(*provider, txn.vin[0], txout, coin_control)) {
37 110008 : return -1;
38 : }
39 2402 : return ::GetSerializeSize(txn.vin[0], PROTOCOL_VERSION);
40 112410 : }
41 :
42 110826 : int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet, const CCoinControl* coin_control)
43 : {
44 110826 : const std::unique_ptr<SigningProvider> provider = wallet->GetSolvingProvider(txout.scriptPubKey);
45 110826 : return CalculateMaximumSignedInputSize(txout, COutPoint(), provider.get(), coin_control);
46 110826 : }
47 :
48 : // txouts needs to be in the order of tx.vin
49 262 : int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control)
50 : {
51 262 : CMutableTransaction txNew(tx);
52 262 : if (!wallet->DummySignTx(txNew, txouts, coin_control)) {
53 0 : return -1;
54 : }
55 262 : return ::GetSerializeSize(txNew, PROTOCOL_VERSION);
56 262 : }
57 :
58 262 : int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const CCoinControl* coin_control)
59 : {
60 262 : std::vector<CTxOut> txouts;
61 : // Look up the inputs. The inputs are either in the wallet, or in coin_control.
62 1380 : for (const CTxIn& input : tx.vin) {
63 1118 : const auto mi = wallet->mapWallet.find(input.prevout.hash);
64 : // Can not estimate size without knowing the input details
65 1118 : if (mi != wallet->mapWallet.end()) {
66 1118 : assert(input.prevout.n < mi->second.tx->vout.size());
67 1118 : txouts.emplace_back(mi->second.tx->vout.at(input.prevout.n));
68 1118 : } else if (coin_control) {
69 0 : const auto txout{coin_control->GetExternalOutput(input.prevout)};
70 0 : if (!txout) {
71 0 : return -1;
72 : }
73 0 : txouts.emplace_back(*txout);
74 0 : } else {
75 0 : return -1;
76 : }
77 : }
78 262 : return CalculateMaximumSignedTxSize(tx, wallet, txouts, coin_control);
79 262 : }
80 :
81 5721 : uint64_t CoinsResult::size() const
82 : {
83 5721 : return legacy.size() + other.size();
84 : }
85 :
86 5677 : std::vector<COutput> CoinsResult::all() const
87 : {
88 5677 : std::vector<COutput> all;
89 5677 : all.reserve(this->size());
90 5677 : all.insert(all.end(), legacy.begin(), legacy.end());
91 5677 : all.insert(all.end(), other.begin(), other.end());
92 5677 : return all;
93 5677 : }
94 :
95 709 : void CoinsResult::clear()
96 : {
97 709 : legacy.clear();
98 709 : other.clear();
99 709 : }
100 :
101 235 : CoinsResult AvailableCoins(const CWallet& wallet,
102 : const CCoinControl* coinControl,
103 : std::optional<CFeeRate> feerate,
104 : const CAmount& nMinimumAmount,
105 : const CAmount& nMaximumAmount,
106 : const CAmount& nMinimumSumAmount,
107 : const uint64_t nMaximumCount,
108 : bool only_spendable)
109 : {
110 235 : AssertLockHeld(wallet.cs_wallet);
111 :
112 235 : CoinType nCoinType = coinControl ? coinControl->nCoinType : CoinType::ALL_COINS;
113 :
114 235 : CoinsResult result;
115 : // Either the WALLET_FLAG_AVOID_REUSE flag is not set (in which case we always allow), or we default to avoiding, and only in the case where
116 : // a coin control object is provided, and has the avoid address reuse flag set to false, do we allow already used addresses
117 235 : bool allow_used_addresses = !wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE) || (coinControl && !coinControl->m_avoid_address_reuse);
118 235 : const int min_depth = {coinControl ? coinControl->m_min_depth : DEFAULT_MIN_DEPTH};
119 235 : const int max_depth = {coinControl ? coinControl->m_max_depth : DEFAULT_MAX_DEPTH};
120 235 : const bool only_safe = {coinControl ? !coinControl->m_include_unsafe_inputs : true};
121 :
122 235 : std::set<uint256> trusted_parents;
123 24245 : for (const auto* pwtx : wallet.GetSpendableTXs()) {
124 24010 : const uint256& wtxid = pwtx->GetHash();
125 24010 : const CWalletTx& wtx = *pwtx;
126 :
127 24010 : if (wallet.IsTxImmatureCoinBase(wtx))
128 22891 : continue;
129 :
130 1119 : int nDepth = wallet.GetTxDepthInMainChain(wtx);
131 :
132 : // We should not consider coins which aren't at least in our mempool
133 : // It's possible for these to be conflicted via ancestors which we may never be able to detect
134 1119 : if (nDepth == 0 && !wtx.InMempool())
135 1 : continue;
136 :
137 1118 : bool safeTx = CachedTxIsTrusted(wallet, wtx, trusted_parents);
138 :
139 1118 : if (only_safe && !safeTx) {
140 1 : continue;
141 : }
142 :
143 1117 : if (nDepth < min_depth || nDepth > max_depth) {
144 0 : continue;
145 : }
146 :
147 1117 : bool tx_from_me = CachedTxIsFromMe(wallet, wtx, ISMINE_ALL);
148 :
149 5094 : for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
150 3977 : const CTxOut& output = wtx.tx->vout[i];
151 3977 : const COutPoint outpoint(wtxid, i);
152 :
153 3977 : bool found = false;
154 3977 : switch (nCoinType) {
155 : case CoinType::ONLY_FULLY_MIXED: {
156 39 : found = CoinJoin::IsDenominatedAmount(output.nValue) &&
157 0 : wallet.IsFullyMixed(outpoint);
158 39 : break;
159 : }
160 : case CoinType::ONLY_READY_TO_MIX: {
161 0 : found = CoinJoin::IsDenominatedAmount(output.nValue) &&
162 0 : !wallet.IsFullyMixed(outpoint);
163 0 : break;
164 : }
165 : case CoinType::ONLY_NONDENOMINATED: {
166 : // NOTE: do not use collateral amounts
167 67 : found = !CoinJoin::IsCollateralAmount(output.nValue) &&
168 28 : !CoinJoin::IsDenominatedAmount(output.nValue);
169 39 : break;
170 : }
171 : case CoinType::ONLY_MASTERNODE_COLLATERAL: {
172 0 : found = dmn_types::IsCollateralAmount(output.nValue);
173 0 : break;
174 : }
175 : case CoinType::ONLY_COINJOIN_COLLATERAL: {
176 0 : found = CoinJoin::IsCollateralAmount(output.nValue);
177 0 : break;
178 : }
179 : case CoinType::ALL_COINS: {
180 3899 : found = true;
181 3899 : break;
182 : }
183 : } // no default case, so the compiler can warn about missing cases
184 3977 : if (!found) continue;
185 :
186 3927 : if (output.nValue < nMinimumAmount || output.nValue > nMaximumAmount)
187 0 : continue;
188 :
189 3927 : if (coinControl && coinControl->HasSelected() && !coinControl->m_allow_other_inputs && !coinControl->IsSelected(outpoint))
190 1208 : continue;
191 :
192 2719 : if (wallet.IsLockedCoin(outpoint) && nCoinType != CoinType::ONLY_MASTERNODE_COLLATERAL)
193 627 : continue;
194 :
195 2092 : if (wallet.IsSpent(outpoint))
196 503 : continue;
197 :
198 1589 : isminetype mine = wallet.IsMine(output);
199 :
200 1589 : if (mine == ISMINE_NO) {
201 5 : continue;
202 : }
203 :
204 1584 : if (!allow_used_addresses && wallet.IsSpentKey(output.scriptPubKey)) {
205 0 : continue;
206 : }
207 :
208 1584 : std::unique_ptr<SigningProvider> provider = wallet.GetSolvingProvider(output.scriptPubKey);
209 :
210 1584 : int input_bytes = CalculateMaximumSignedInputSize(output, COutPoint(), provider.get(), coinControl);
211 : // Because CalculateMaximumSignedInputSize just uses ProduceSignature and makes a dummy signature,
212 : // it is safe to assume that this input is solvable if input_bytes is greater -1.
213 1584 : bool solvable = input_bytes > -1;
214 1584 : bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
215 :
216 : // Filter by spendable outputs only
217 1584 : if (!spendable && only_spendable) continue;
218 :
219 : // When parsing a scriptPubKey, Solver returns the parsed pubkeys or hashes (depending on the script)
220 : // We don't need those here, so we are leaving them in return_values_unused
221 1584 : std::vector<std::vector<uint8_t>> return_values_unused;
222 : TxoutType type;
223 :
224 : // If the Output is P2SH and spendable, we want to know if it is
225 : // a P2SH (legacy). We can determine this from the redeemScript.
226 : // If the Output is not spendable, it will be classified as a P2SH (legacy),
227 : // since we have no way of knowing otherwise without the redeemScript
228 1584 : if (output.scriptPubKey.IsPayToScriptHash() && solvable) {
229 0 : CScript redeemScript;
230 0 : CTxDestination destination;
231 0 : if (!ExtractDestination(output.scriptPubKey, destination))
232 0 : continue;
233 0 : const CScriptID& hash = CScriptID(std::get<ScriptHash>(destination));
234 0 : if (!provider->GetCScript(hash, redeemScript))
235 0 : continue;
236 0 : type = Solver(redeemScript, return_values_unused);
237 0 : } else {
238 1584 : type = Solver(output.scriptPubKey, return_values_unused);
239 : }
240 :
241 1584 : COutput coin(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.GetTxTime(), tx_from_me, feerate);
242 1584 : switch (type) {
243 : case TxoutType::SCRIPTHASH:
244 : case TxoutType::PUBKEYHASH:
245 1477 : result.legacy.push_back(coin);
246 1477 : break;
247 : default:
248 107 : result.other.push_back(coin);
249 107 : };
250 :
251 : // Cache total amount as we go
252 1584 : result.total_amount += output.nValue;
253 : // Checks the sum amount of all UTXO's.
254 1584 : if (nMinimumSumAmount != MAX_MONEY) {
255 0 : if (result.total_amount >= nMinimumSumAmount) {
256 0 : return result;
257 : }
258 0 : }
259 :
260 : // Checks the maximum number of UTXO's.
261 1584 : if (nMaximumCount > 0 && result.size() >= nMaximumCount) {
262 0 : return result;
263 : }
264 1584 : }
265 : }
266 :
267 235 : return result;
268 235 : }
269 :
270 7 : CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount)
271 : {
272 7 : return AvailableCoins(wallet, coinControl, /*feerate=*/ std::nullopt, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, /*only_spendable=*/false);
273 : }
274 :
275 4 : CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl)
276 : {
277 4 : LOCK(wallet.cs_wallet);
278 8 : return AvailableCoins(wallet, coinControl,
279 4 : /*feerate=*/ std::nullopt,
280 4 : /*nMinimumAmount=*/ 1,
281 : /*nMaximumAmount=*/ MAX_MONEY,
282 : /*nMinimumSumAmount=*/ MAX_MONEY,
283 : /*nMaximumCount=*/ 0
284 4 : ).total_amount;
285 4 : }
286 :
287 5 : const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output)
288 : {
289 5 : AssertLockHeld(wallet.cs_wallet);
290 5 : const CTransaction* ptx = &tx;
291 5 : int n = output;
292 7 : while (OutputIsChange(wallet, ptx->vout[n]) && ptx->vin.size() > 0) {
293 2 : const COutPoint& prevout = ptx->vin[0].prevout;
294 2 : auto it = wallet.mapWallet.find(prevout.hash);
295 2 : if (it == wallet.mapWallet.end() || it->second.tx->vout.size() <= prevout.n ||
296 2 : !wallet.IsMine(it->second.tx->vout[prevout.n])) {
297 0 : break;
298 : }
299 2 : ptx = it->second.tx.get();
300 2 : n = prevout.n;
301 : }
302 5 : return ptx->vout[n];
303 : }
304 :
305 3 : const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint)
306 : {
307 3 : AssertLockHeld(wallet.cs_wallet);
308 3 : return FindNonChangeParentOutput(wallet, *wallet.GetWalletTx(outpoint.hash)->tx, outpoint.n);
309 : }
310 :
311 3 : std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet)
312 : {
313 3 : AssertLockHeld(wallet.cs_wallet);
314 :
315 3 : std::map<CTxDestination, std::vector<COutput>> result;
316 :
317 6 : for (COutput& coin : AvailableCoinsListUnspent(wallet).all()) {
318 3 : CTxDestination address;
319 6 : if ((coin.spendable || (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && coin.solvable)) &&
320 3 : ExtractDestination(FindNonChangeParentOutput(wallet, coin.outpoint).scriptPubKey, address)) {
321 3 : result[address].emplace_back(std::move(coin));
322 3 : }
323 : }
324 :
325 : // Include watch-only for LegacyScriptPubKeyMan wallets without private keys
326 3 : const bool include_watch_only = wallet.GetLegacyScriptPubKeyMan() && wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
327 3 : const isminetype is_mine_filter = include_watch_only ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
328 5 : for (const COutPoint& output : wallet.setLockedCoins) {
329 2 : auto it = wallet.mapWallet.find(output.hash);
330 2 : if (it != wallet.mapWallet.end()) {
331 2 : const auto& wtx = it->second;
332 2 : int depth = wallet.GetTxDepthInMainChain(wtx);
333 4 : if (depth >= 0 && output.n < wtx.tx->vout.size() &&
334 2 : wallet.IsMine(wtx.tx->vout[output.n]) == is_mine_filter
335 : ) {
336 2 : CTxDestination address;
337 2 : if (ExtractDestination(FindNonChangeParentOutput(wallet, *wtx.tx, output.n).scriptPubKey, address)) {
338 2 : const auto out = wtx.tx->vout.at(output.n);
339 4 : result[address].emplace_back(
340 2 : COutPoint(wtx.GetHash(), output.n), out, depth, CalculateMaximumSignedInputSize(out, &wallet, /*coin_control=*/nullptr), /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), CachedTxIsFromMe(wallet, wtx, ISMINE_ALL));
341 2 : }
342 2 : }
343 2 : }
344 : }
345 :
346 3 : return result;
347 3 : }
348 :
349 598529 : static bool isGroupISLocked(const OutputGroup& group, interfaces::Chain& chain)
350 : {
351 1197058 : return std::all_of(group.m_outputs.begin(), group.m_outputs.end(), [&chain](const auto& output) {
352 598529 : return chain.isInstantSendLockedTx(output.outpoint.hash);
353 : });
354 : }
355 :
356 4036 : std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<COutput>& outputs, const CoinSelectionParams& coin_sel_params, const CoinEligibilityFilter& filter, bool positive_only)
357 : {
358 4036 : std::vector<OutputGroup> groups_out;
359 :
360 4036 : if (!coin_sel_params.m_avoid_partial_spends) {
361 : // Allowing partial spends means no grouping. Each COutput gets its own OutputGroup.
362 601627 : for (const COutput& output : outputs) {
363 : // Skip outputs we cannot spend
364 597713 : if (!output.spendable) continue;
365 :
366 : size_t ancestors, descendants;
367 597713 : wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
368 :
369 : // Make an OutputGroup containing just this output
370 597713 : OutputGroup group{coin_sel_params};
371 597713 : group.Insert(output, ancestors, descendants, positive_only);
372 :
373 : // Check the OutputGroup's eligibility. Only add the eligible ones.
374 597713 : if (positive_only && group.GetSelectionAmount() <= 0) continue;
375 597711 : bool isISLocked = isGroupISLocked(group, wallet.chain());
376 597711 : if (group.m_outputs.size() > 0 && group.EligibleForSpending(filter, isISLocked)) groups_out.push_back(group);
377 597713 : }
378 3914 : return groups_out;
379 : }
380 :
381 : // We want to combine COutputs that have the same scriptPubKey into single OutputGroups
382 : // except when there are more than OUTPUT_GROUP_MAX_ENTRIES COutputs grouped in an OutputGroup.
383 : // To do this, we maintain a map where the key is the scriptPubKey and the value is a vector of OutputGroups.
384 : // For each COutput, we check if the scriptPubKey is in the map, and if it is, the COutput is added
385 : // to the last OutputGroup in the vector for the scriptPubKey. When the last OutputGroup has
386 : // OUTPUT_GROUP_MAX_ENTRIES COutputs, a new OutputGroup is added to the end of the vector.
387 122 : std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
388 952 : for (const auto& output : outputs) {
389 : // Skip outputs we cannot spend
390 830 : if (!output.spendable) continue;
391 :
392 : size_t ancestors, descendants;
393 830 : wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
394 830 : CScript spk = output.txout.scriptPubKey;
395 :
396 830 : std::vector<OutputGroup>& groups = spk_to_groups_map[spk];
397 :
398 830 : if (groups.size() == 0) {
399 : // No OutputGroups for this scriptPubKey yet, add one
400 818 : groups.emplace_back(coin_sel_params);
401 818 : }
402 :
403 : // Get the last OutputGroup in the vector so that we can add the COutput to it
404 : // A pointer is used here so that group can be reassigned later if it is full.
405 830 : OutputGroup* group = &groups.back();
406 :
407 : // Check if this OutputGroup is full. We limit to OUTPUT_GROUP_MAX_ENTRIES when using -avoidpartialspends
408 : // to avoid surprising users with very high fees.
409 830 : if (group->m_outputs.size() >= OUTPUT_GROUP_MAX_ENTRIES) {
410 : // The last output group is full, add a new group to the vector and use that group for the insertion
411 0 : groups.emplace_back(coin_sel_params);
412 0 : group = &groups.back();
413 0 : }
414 :
415 : // Add the output to group
416 830 : group->Insert(output, ancestors, descendants, positive_only);
417 830 : }
418 :
419 : // Now we go through the entire map and pull out the OutputGroups
420 940 : for (const auto& spk_and_groups_pair: spk_to_groups_map) {
421 818 : const std::vector<OutputGroup>& groups_per_spk= spk_and_groups_pair.second;
422 :
423 : // Go through the vector backwards. This allows for the first item we deal with being the partial group.
424 1636 : for (auto group_it = groups_per_spk.rbegin(); group_it != groups_per_spk.rend(); group_it++) {
425 818 : const OutputGroup& group = *group_it;
426 :
427 : // Don't include partial groups if there are full groups too and we don't want partial groups
428 818 : if (group_it == groups_per_spk.rbegin() && groups_per_spk.size() > 1 && !filter.m_include_partial_groups) {
429 0 : continue;
430 : }
431 :
432 : // Check the OutputGroup's eligibility. Only add the eligible ones.
433 818 : if (positive_only && group.GetSelectionAmount() <= 0) continue;
434 818 : bool isISLocked = isGroupISLocked(group, wallet.chain());
435 818 : if (group.m_outputs.size() > 0 && group.EligibleForSpending(filter, isISLocked)) groups_out.push_back(group);
436 818 : }
437 : }
438 :
439 122 : return groups_out;
440 4036 : }
441 :
442 256 : std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const CoinsResult& available_coins,
443 : const CoinSelectionParams& coin_selection_params, bool allow_mixed_output_types, CoinType nCoinType)
444 : {
445 : // Run coin selection on each OutputType and compute the Waste Metric
446 256 : std::vector<SelectionResult> results;
447 424 : if (auto result{ChooseSelectionResult(wallet, nTargetValue, eligibility_filter, available_coins.legacy, coin_selection_params, nCoinType)}) {
448 168 : results.push_back(*result);
449 168 : }
450 :
451 : // If we can't fund the transaction from any individual OutputType, run coin selection
452 : // over all available coins, else pick the best solution from the results
453 256 : if (results.size() == 0) {
454 88 : if (allow_mixed_output_types) {
455 80 : if (auto result{ChooseSelectionResult(wallet, nTargetValue, eligibility_filter, available_coins.all(), coin_selection_params, nCoinType)}) {
456 20 : return result;
457 : }
458 40 : }
459 68 : return std::optional<SelectionResult>();
460 : };
461 168 : std::optional<SelectionResult> result{*std::min_element(results.begin(), results.end())};
462 168 : return result;
463 424 : };
464 :
465 316 : std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const std::vector<COutput>& available_coins,
466 : const CoinSelectionParams& coin_selection_params, CoinType nCoinType)
467 : {
468 : // Vector of results. We will choose the best one based on waste.
469 316 : std::vector<SelectionResult> results;
470 :
471 316 : int max_inputs_weight = MAX_STANDARD_TX_SIZE - coin_selection_params.tx_noinputs_size;
472 :
473 : // Note that unlike KnapsackSolver, we do not include the fee for creating a change output as BnB will not create a change output.
474 316 : std::vector<OutputGroup> positive_groups = GroupOutputs(wallet, available_coins, coin_selection_params, eligibility_filter, true /* positive_only */);
475 316 : positive_groups.clear(); // Cleared to skip BnB and SRD as they're unaware of mixed coins
476 316 : if (auto bnb_result{SelectCoinsBnB(positive_groups, nTargetValue, coin_selection_params.m_cost_of_change, max_inputs_weight)}) {
477 0 : results.push_back(*bnb_result);
478 0 : }
479 :
480 316 : max_inputs_weight -= coin_selection_params.change_output_size;
481 :
482 : // The knapsack solver has some legacy behavior where it will spend dust outputs. We retain this behavior, so don't filter for positive only here.
483 316 : std::vector<OutputGroup> all_groups = GroupOutputs(wallet, available_coins, coin_selection_params, eligibility_filter, false /* positive_only */);
484 316 : CAmount target_with_change = nTargetValue;
485 : // While nTargetValue includes the transaction fees for non-input things, it does not include the fee for creating a change output.
486 : // So we need to include that for KnapsackSolver as well, as we are expecting to create a change output.
487 : // There is also no change output when spending fully mixed coins.
488 316 : if (!coin_selection_params.m_subtract_fee_outputs && nCoinType != CoinType::ONLY_FULLY_MIXED) {
489 223 : target_with_change += coin_selection_params.m_change_fee;
490 223 : }
491 820 : if (auto knapsack_result{KnapsackSolver(all_groups, target_with_change, coin_selection_params.m_min_change_target,
492 316 : coin_selection_params.rng_fast, max_inputs_weight, nCoinType == CoinType::ONLY_FULLY_MIXED,
493 316 : wallet.m_default_max_tx_fee)}) {
494 188 : knapsack_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
495 188 : results.push_back(*knapsack_result);
496 188 : }
497 :
498 : // Include change for SRD as we want to avoid making really small change if the selection just
499 : // barely meets the target. Just use the lower bound change target instead of the randomly
500 : // generated one, since SRD will result in a random change amount anyway; avoid making the
501 : // target needlessly large.
502 316 : const CAmount srd_target = target_with_change + CHANGE_LOWER;
503 316 : if (auto srd_result{SelectCoinsSRD(positive_groups, srd_target, coin_selection_params.rng_fast, max_inputs_weight)}) {
504 0 : srd_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
505 0 : results.push_back(*srd_result);
506 0 : }
507 :
508 316 : if (results.size() == 0) {
509 128 : return std::nullopt;
510 : }
511 :
512 : // Choose the result with the least waste
513 : // If the waste is the same, choose the one which spends more inputs.
514 188 : return *std::min_element(results.begin(), results.end());
515 316 : }
516 :
517 330 : std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& available_coins, const CAmount& nTargetValue, const CCoinControl& coin_control, const CoinSelectionParams& coin_selection_params)
518 : {
519 : // Note: this function should never be used for "always free" tx types like dstx
520 330 : CoinType nCoinType = coin_control.nCoinType;
521 330 : CAmount value_to_select = nTargetValue;
522 :
523 330 : OutputGroup preset_inputs(coin_selection_params);
524 :
525 : // calculate value from preset inputs and store them
526 330 : std::set<COutPoint> preset_coins;
527 :
528 905 : for (const COutPoint& outpoint : coin_control.ListSelected()) {
529 575 : int input_bytes = -1;
530 575 : CTxOut txout;
531 575 : auto ptr_wtx = wallet.GetWalletTx(outpoint.hash);
532 575 : if (ptr_wtx) {
533 : // Clearly invalid input, fail
534 575 : if (ptr_wtx->tx->vout.size() <= outpoint.n) {
535 0 : return std::nullopt;
536 : }
537 575 : txout = ptr_wtx->tx->vout.at(outpoint.n);
538 575 : input_bytes = CalculateMaximumSignedInputSize(txout, &wallet, &coin_control);
539 575 : } else {
540 : // The input is external. We did not find the tx in mapWallet.
541 0 : const auto out{coin_control.GetExternalOutput(outpoint)};
542 0 : if (!out) {
543 0 : return std::nullopt;
544 : }
545 0 : txout = *out;
546 0 : }
547 :
548 575 : if (input_bytes == -1) {
549 0 : input_bytes = CalculateMaximumSignedInputSize(txout, outpoint, &coin_control.m_external_provider, &coin_control);
550 0 : }
551 575 : if (nCoinType == CoinType::ONLY_FULLY_MIXED) {
552 : // Make sure to include mixed preset inputs only,
553 : // even if some non-mixed inputs were manually selected via CoinControl
554 0 : if (!wallet.IsFullyMixed(outpoint)) continue;
555 0 : }
556 : // If available, override calculated size with coin control specified size
557 575 : if (coin_control.HasInputWeight(outpoint)) {
558 0 : input_bytes = GetVirtualTransactionSize(coin_control.GetInputWeight(outpoint), 0, 0);
559 0 : }
560 :
561 575 : if (input_bytes == -1) {
562 0 : return std::nullopt; // Not solvable, can't estimate size for fee
563 : }
564 :
565 : /* Set some defaults for depth, spendable, solvable, safe, time, and from_me as these don't matter for preset inputs since no selection is being done. */
566 575 : COutput output(outpoint, txout, /*depth=*/ 0, input_bytes, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, /*time=*/ 0, /*from_me=*/ false, coin_selection_params.m_effective_feerate);
567 575 : if (coin_selection_params.m_subtract_fee_outputs) {
568 236 : value_to_select -= output.txout.nValue;
569 236 : } else {
570 339 : value_to_select -= output.GetEffectiveValue();
571 : }
572 575 : preset_coins.insert(outpoint);
573 : /* Set ancestors and descendants to 0 as they don't matter for preset inputs since no actual selection is being done.
574 : * positive_only is set to false because we want to include all preset inputs, even if they are dust.
575 : */
576 575 : preset_inputs.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
577 575 : }
578 :
579 : // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
580 330 : if (coin_control.HasSelected() && !coin_control.m_allow_other_inputs) {
581 134 : SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
582 134 : bool all_inputs{coin_control.fRequireAllInputs};
583 134 : if (!all_inputs) {
584 : // Calculate the smallest set of inputs required to meet nTargetValue from available_coins
585 1 : bool success{false};
586 1 : OutputGroup preset_candidates(coin_selection_params);
587 3 : for (const COutput& out : available_coins.all()) {
588 2 : if (!out.spendable) continue;
589 2 : if (preset_coins.count(out.outpoint)) {
590 2 : preset_candidates.Insert(out, /*ancestors=*/0, /*descendants=*/0, /*positive_only=*/false);
591 2 : }
592 2 : if (preset_candidates.GetSelectionAmount() >= nTargetValue) {
593 1 : result.AddInput(preset_candidates);
594 1 : success = true;
595 1 : break;
596 : }
597 : }
598 : // Couldn't meet target, add all inputs
599 1 : if (!success) all_inputs = true;
600 1 : }
601 134 : if (all_inputs) {
602 133 : result.AddInput(preset_inputs);
603 133 : }
604 134 : if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
605 98 : result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
606 98 : return result;
607 134 : }
608 :
609 : // remove preset inputs from coins so that Coin Selection doesn't pick them.
610 196 : if (coin_control.HasSelected()) {
611 8 : available_coins.legacy.erase(remove_if(available_coins.legacy.begin(), available_coins.legacy.end(), [&](const COutput& c) { return preset_coins.count(c.outpoint); }), available_coins.legacy.end());
612 2 : available_coins.other.erase(remove_if(available_coins.other.begin(), available_coins.other.end(), [&](const COutput& c) { return preset_coins.count(c.outpoint); }), available_coins.other.end());
613 2 : }
614 :
615 196 : unsigned int limit_ancestor_count = 0;
616 196 : unsigned int limit_descendant_count = 0;
617 196 : wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
618 196 : const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
619 196 : const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
620 196 : const bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
621 :
622 : // form groups from remaining coins; note that preset coins will not
623 : // automatically have their associated (same address) coins included
624 196 : if (coin_control.m_avoid_partial_spends && available_coins.size() > OUTPUT_GROUP_MAX_ENTRIES) {
625 : // Cases where we have 101+ outputs all pointing to the same destination may result in
626 : // privacy leaks as they will potentially be deterministically sorted. We solve that by
627 : // explicitly shuffling the outputs before processing
628 0 : Shuffle(available_coins.legacy.begin(), available_coins.legacy.end(), coin_selection_params.rng_fast);
629 0 : Shuffle(available_coins.other.begin(), available_coins.other.end(), coin_selection_params.rng_fast);
630 0 : }
631 : // Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the
632 : // transaction at a target feerate. If an attempt fails, more attempts may be made using a more
633 : // permissive CoinEligibilityFilter.
634 392 : std::optional<SelectionResult> res = [&] {
635 : // Pre-selected inputs already cover the target amount.
636 196 : if (value_to_select <= 0) return std::make_optional(SelectionResult(nTargetValue, SelectionAlgorithm::MANUAL));
637 :
638 : // If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
639 : // confirmations on outputs received from other wallets and only spend confirmed change.
640 196 : if (auto r1{AttemptSelection(wallet, value_to_select, CoinEligibilityFilter(1, 6, 0), available_coins, coin_selection_params, /*allow_mixed_output_types=*/false, nCoinType)}) return r1;
641 : // Allow mixing only if no solution from any single output type can be found
642 28 : if (auto r2{AttemptSelection(wallet, value_to_select, CoinEligibilityFilter(1, 1, 0), available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) return r2;
643 :
644 : // Fall back to using zero confirmation change (but with as few ancestors in the mempool as
645 : // possible) if we cannot fund the transaction otherwise.
646 8 : if (wallet.m_spend_zero_conf_change) {
647 8 : if (auto r3{AttemptSelection(wallet, value_to_select, CoinEligibilityFilter(0, 1, 2), available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) return r3;
648 16 : if (auto r4{AttemptSelection(wallet, value_to_select, CoinEligibilityFilter(0, 1, std::min(size_t{4}, max_ancestors/3), std::min(size_t{4}, max_descendants/3)),
649 8 : available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) {
650 0 : return r4;
651 : }
652 16 : if (auto r5{AttemptSelection(wallet, value_to_select, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2),
653 8 : available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) {
654 0 : return r5;
655 : }
656 : // If partial groups are allowed, relax the requirement of spending OutputGroups (groups
657 : // of UTXOs sent to the same address, which are obviously controlled by a single wallet)
658 : // in their entirety.
659 16 : if (auto r6{AttemptSelection(wallet, value_to_select, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1, true /* include_partial_groups */),
660 8 : available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) {
661 0 : return r6;
662 : }
663 : // Try with unsafe inputs if they are allowed. This may spend unconfirmed outputs
664 : // received from other wallets.
665 8 : if (coin_control.m_include_unsafe_inputs) {
666 0 : if (auto r7{AttemptSelection(wallet, value_to_select,
667 0 : CoinEligibilityFilter(0 /* conf_mine */, 0 /* conf_theirs */, max_ancestors-1, max_descendants-1, true /* include_partial_groups */),
668 0 : available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) {
669 0 : return r7;
670 : }
671 0 : }
672 : // Try with unlimited ancestors/descendants. The transaction will still need to meet
673 : // mempool ancestor/descendant policy to be accepted to mempool and broadcasted, but
674 : // OutputGroups use heuristics that may overestimate ancestor/descendant counts.
675 8 : if (!fRejectLongChains) {
676 0 : if (auto r8{AttemptSelection(wallet, value_to_select,
677 0 : CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), true /* include_partial_groups */),
678 0 : available_coins, coin_selection_params, /*allow_mixed_output_types=*/true, nCoinType)}) {
679 0 : return r8;
680 : }
681 0 : }
682 8 : }
683 : // Coin Selection failed.
684 8 : return std::optional<SelectionResult>();
685 196 : }();
686 :
687 196 : if (!res) return std::nullopt;
688 :
689 : // Add preset inputs to result
690 188 : res->AddInput(preset_inputs);
691 188 : if (res->m_algo == SelectionAlgorithm::MANUAL) {
692 0 : res->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
693 0 : }
694 :
695 188 : return res;
696 330 : }
697 :
698 178 : static bool IsCurrentForAntiFeeSniping(interfaces::Chain& chain, const uint256& block_hash)
699 : {
700 178 : if (chain.isInitialBlockDownload()) {
701 0 : return false;
702 : }
703 178 : constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60; // in seconds
704 : int64_t block_time;
705 178 : CHECK_NONFATAL(chain.findBlock(block_hash, FoundBlock().time(block_time)));
706 178 : if (block_time < (GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
707 0 : return false;
708 : }
709 178 : return true;
710 178 : }
711 :
712 : /**
713 : * Set a height-based locktime for new transactions (uses the height of the
714 : * current chain tip unless we are not synced with the current chain
715 : */
716 178 : static void DiscourageFeeSniping(CMutableTransaction& tx, FastRandomContext& rng_fast,
717 : interfaces::Chain& chain, const uint256& block_hash, int block_height)
718 : {
719 : // All inputs must be added by now
720 178 : assert(!tx.vin.empty());
721 : // Discourage fee sniping.
722 : //
723 : // For a large miner the value of the transactions in the best block and
724 : // the mempool can exceed the cost of deliberately attempting to mine two
725 : // blocks to orphan the current best block. By setting nLockTime such that
726 : // only the next block can include the transaction, we discourage this
727 : // practice as the height restricted and limited blocksize gives miners
728 : // considering fee sniping fewer options for pulling off this attack.
729 : //
730 : // A simple way to think about this is from the wallet's point of view we
731 : // always want the blockchain to move forward. By setting nLockTime this
732 : // way we're basically making the statement that we only want this
733 : // transaction to appear in the next block; we don't want to potentially
734 : // encourage reorgs by allowing transactions to appear at lower heights
735 : // than the next block in forks of the best chain.
736 : //
737 : // Of course, the subsidy is high enough, and transaction volume low
738 : // enough, that fee sniping isn't a problem yet, but by implementing a fix
739 : // now we ensure code won't be written that makes assumptions about
740 : // nLockTime that preclude a fix later.
741 178 : if (IsCurrentForAntiFeeSniping(chain, block_hash)) {
742 178 : tx.nLockTime = block_height;
743 :
744 : // Secondly occasionally randomly pick a nLockTime even further back, so
745 : // that transactions that are delayed after signing for whatever reason,
746 : // e.g. high-latency mix networks and some CoinJoin implementations, have
747 : // better privacy.
748 178 : if (rng_fast.randrange(10) == 0) {
749 18 : tx.nLockTime = std::max(0, int(tx.nLockTime) - int(rng_fast.randrange(100)));
750 18 : }
751 178 : } else {
752 : // If our chain is lagging behind, we can't discourage fee sniping nor help
753 : // the privacy of high-latency transactions. To avoid leaking a potentially
754 : // unique "nLockTime fingerprint", set nLockTime to a constant.
755 0 : tx.nLockTime = 0;
756 : }
757 : // Sanity check all values
758 178 : assert(tx.nLockTime < LOCKTIME_THRESHOLD); // Type must be block height
759 178 : assert(tx.nLockTime <= uint64_t(block_height));
760 882 : for (const auto& in : tx.vin) {
761 : // Can not be FINAL for locktime to work
762 704 : assert(in.nSequence != CTxIn::SEQUENCE_FINAL);
763 : // May be MAX NONFINAL to disable BIP68
764 704 : if (in.nSequence == CTxIn::MAX_SEQUENCE_NONFINAL) continue;
765 : // The wallet does not support any other sequence-use right now.
766 0 : assert(false);
767 : }
768 178 : }
769 :
770 226 : static util::Result<CreatedTransactionResult> CreateTransactionInternal(
771 : CWallet& wallet,
772 : const std::vector<CRecipient>& vecSend,
773 : int change_pos,
774 : const CCoinControl& coin_control,
775 : bool sign,
776 : int nExtraPayloadSize) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
777 : {
778 226 : AssertLockHeld(wallet.cs_wallet);
779 :
780 : // out variables, to be packed into returned result structure
781 : CAmount nFeeRet;
782 226 : int nChangePosInOut = change_pos;
783 :
784 226 : FastRandomContext rng_fast;
785 226 : CMutableTransaction txNew; // The resulting transaction that we make
786 :
787 226 : CoinSelectionParams coin_selection_params{rng_fast}; // Parameters for coin selection, init with dummy
788 226 : coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
789 :
790 : // Set the long term feerate estimate to the wallet's consolidate feerate
791 226 : coin_selection_params.m_long_term_feerate = wallet.m_consolidate_feerate;
792 :
793 226 : CAmount recipients_sum = 0;
794 226 : ReserveDestination reservedest(&wallet);
795 226 : const bool sort_bip69{nChangePosInOut == -1};
796 226 : unsigned int outputs_to_subtract_fee_from = 0; // The number of outputs which we are subtracting the fee from
797 9693 : for (const auto& recipient : vecSend) {
798 9467 : recipients_sum += recipient.nAmount;
799 :
800 9467 : if (recipient.fSubtractFeeFromAmount) {
801 91 : outputs_to_subtract_fee_from++;
802 91 : coin_selection_params.m_subtract_fee_outputs = true;
803 91 : }
804 : }
805 226 : coin_selection_params.m_min_change_target = GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), rng_fast);
806 :
807 : // Create change script that will be used if we need change
808 226 : CScript scriptChange;
809 226 : bilingual_str error; // possible error str
810 :
811 : // coin control: send change to custom address
812 226 : if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
813 46 : scriptChange = GetScriptForDestination(coin_control.destChange);
814 46 : } else { // no coin control: send change to newly generated address
815 : // Note: We use a new key here to keep it from being obvious which side is the change.
816 : // The drawback is that by not reusing a previous key, the change may be lost if a
817 : // backup is restored, if the backup doesn't have the new private key for the change.
818 : // If we reused the old key, it would be possible to add code to look for and
819 : // rediscover unknown transactions that were written with keys of ours to recover
820 : // post-backup change.
821 :
822 : // Reserve a new key pair from key pool. If it fails, provide a dummy
823 : // destination in case we don't need change.
824 180 : CTxDestination dest;
825 180 : auto op_dest = reservedest.GetReservedDestination(true);
826 180 : if (!op_dest) {
827 0 : error = _("Transaction needs a change address, but we can't generate it.") + Untranslated(" ") + util::ErrorString(op_dest);
828 0 : } else {
829 180 : dest = *op_dest;
830 180 : scriptChange = GetScriptForDestination(dest);
831 : }
832 : // A valid destination implies a change script (and
833 : // vice-versa). An empty change script will abort later, if the
834 : // change keypool ran out, but change is required.
835 180 : CHECK_NONFATAL(IsValidDestination(dest) != scriptChange.empty());
836 180 : }
837 226 : CTxOut change_prototype_txout(0, scriptChange);
838 226 : coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
839 :
840 : // Get size of spending the change output
841 226 : int change_spend_size = CalculateMaximumSignedInputSize(change_prototype_txout, &wallet);
842 : // If the wallet doesn't know how to sign change output, assume p2sh-p2pkh
843 : // as lower-bound to allow BnB to do it's thing
844 226 : if (change_spend_size == -1) {
845 0 : coin_selection_params.change_spend_size = DUMMY_NESTED_P2PKH_INPUT_SIZE;
846 0 : } else {
847 226 : coin_selection_params.change_spend_size = (size_t)change_spend_size;
848 : }
849 :
850 : // Set discard feerate
851 226 : coin_selection_params.m_discard_feerate = coin_control.m_discard_feerate ? *coin_control.m_discard_feerate : GetDiscardRate(wallet);
852 :
853 : // Get the fee rate to use effective values in coin selection
854 226 : FeeCalculation feeCalc;
855 226 : coin_selection_params.m_effective_feerate = GetMinimumFeeRate(wallet, coin_control, &feeCalc);
856 : // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly
857 : // provided one
858 226 : if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
859 0 : return util::Error{strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::DUFF_B), coin_selection_params.m_effective_feerate.ToString(FeeEstimateMode::DUFF_B))};
860 : }
861 226 : if (feeCalc.reason == FeeReason::FALLBACK && !wallet.m_allow_fallback_fee) {
862 : // eventually allow a fallback fee
863 0 : return util::Error{strprintf(_("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s."), "-fallbackfee")};
864 : }
865 :
866 : // Calculate the cost of change
867 : // Cost of change is the cost of creating the change output + cost of spending the change output in the future.
868 : // For creating the change output now, we use the effective feerate.
869 : // For spending the change output in the future, we use the discard feerate for now.
870 : // So cost of change = (change output size * effective feerate) + (size of spending change output * discard feerate)
871 226 : coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
872 226 : coin_selection_params.m_cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + coin_selection_params.m_change_fee;
873 :
874 : // vouts to the payees
875 226 : if (!coin_selection_params.m_subtract_fee_outputs) {
876 143 : coin_selection_params.tx_noinputs_size = 9; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count
877 143 : coin_selection_params.tx_noinputs_size += GetSizeOfCompactSize(vecSend.size()); // bytes for output count
878 143 : }
879 9881 : for (const auto& recipient : vecSend)
880 : {
881 9659 : CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
882 :
883 : // Include the fee cost for outputs.
884 9467 : if (!coin_selection_params.m_subtract_fee_outputs) {
885 9258 : coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, PROTOCOL_VERSION);
886 9258 : }
887 :
888 9467 : if (IsDust(txout, wallet.chain().relayDustFee())) {
889 4 : return util::Error{_("Transaction amount too small")};
890 : }
891 9463 : txNew.vout.push_back(txout);
892 9467 : }
893 :
894 : // Include the fees for things that aren't inputs, excluding the change output
895 222 : const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
896 222 : CAmount selection_target = recipients_sum + not_input_fees;
897 :
898 : // This can only happen if feerate is 0, and requested destinations are value of 0 (e.g. OP_RETURN)
899 : // and no pre-selected inputs. This will result in 0-input transaction, which is consensus-invalid anyways
900 222 : if (selection_target == 0 && !coin_control.HasSelected()) {
901 0 : return util::Error{_("Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input")};
902 : }
903 :
904 : // Get available coins
905 222 : auto available_coins = AvailableCoins(wallet,
906 222 : &coin_control,
907 222 : coin_selection_params.m_effective_feerate,
908 222 : 1, /*nMinimumAmount*/
909 : MAX_MONEY, /*nMaximumAmount*/
910 : MAX_MONEY, /*nMinimumSumAmount*/
911 : 0); /*nMaximumCount*/
912 :
913 : // Choose coins to use
914 414 : std::optional<SelectionResult> result = SelectCoins(wallet, available_coins, /*nTargetValue=*/selection_target, coin_control, coin_selection_params);
915 414 : if (!result) {
916 43 : if (coin_control.nCoinType == CoinType::ONLY_NONDENOMINATED) {
917 1 : return util::Error{_("Unable to locate enough non-denominated funds for this transaction.")};
918 42 : } else if (coin_control.nCoinType == CoinType::ONLY_FULLY_MIXED) {
919 3 : return util::Error{_("Unable to locate enough mixed funds for this transaction.") +
920 2 : Untranslated(" ") + strprintf(_("%s uses exact denominated amounts to send funds, you might simply need to mix some more coins."), gCoinJoinName)};
921 : }
922 41 : return util::Error{_("Insufficient funds.")};
923 : }
924 : TRACE5(coin_selection, selected_coins, wallet.GetName().c_str(), GetAlgorithmName(result->m_algo).c_str(), result->m_target, result->GetWaste(), result->GetSelectedValue());
925 :
926 : // Always make a change output
927 : // We will reduce the fee from this change output later, and remove the output if it is too small.
928 371 : const CAmount change_and_fee = result->GetSelectedValue() - recipients_sum;
929 179 : assert(change_and_fee >= 0);
930 179 : CTxOut newTxOut(change_and_fee, scriptChange);
931 :
932 371 : if (nChangePosInOut == -1) {
933 : // Insert change txn at random position:
934 354 : nChangePosInOut = rng_fast.randrange(txNew.vout.size() + 1);
935 354 : }
936 17 : else if ((unsigned int)nChangePosInOut > txNew.vout.size()) {
937 1 : return util::Error{_("Transaction change output index out of range")};
938 : }
939 :
940 370 : assert(nChangePosInOut != -1);
941 370 : auto change_position = txNew.vout.insert(txNew.vout.begin() + nChangePosInOut, newTxOut);
942 :
943 : // We're making a copy of vecSend because it's const, sortedVecSend should be used
944 : // in place of vecSend in all subsequent usage.
945 178 : std::vector<CRecipient> sortedVecSend{vecSend};
946 370 : if (sort_bip69) {
947 162 : std::sort(txNew.vout.begin(), txNew.vout.end(), CompareOutputBIP69());
948 : // The output reduction loop uses vecSend to map to txNew.vout, we need to
949 : // shuffle them both to ensure this mapping remains consistent
950 162 : std::sort(sortedVecSend.begin(), sortedVecSend.end(),
951 119909 : [](const CRecipient& a, const CRecipient& b) {
952 119909 : return a.nAmount < b.nAmount || (a.nAmount == b.nAmount && a.scriptPubKey < b.scriptPubKey);
953 : });
954 :
955 : // If there was a change output added before, we must update its position now
956 162 : if (const auto it = std::find(txNew.vout.begin(), txNew.vout.end(), newTxOut); it != txNew.vout.end()) {
957 162 : change_position = it;
958 162 : nChangePosInOut = std::distance(txNew.vout.begin(), change_position);
959 162 : }
960 162 : };
961 :
962 : // The sequence number is set to non-maxint so that DiscourageFeeSniping
963 : // works.
964 370 : const uint32_t nSequence{CTxIn::SEQUENCE_FINAL - 1};
965 1074 : for (const auto& coin : result->GetInputSet()) {
966 704 : txNew.vin.emplace_back(coin.outpoint, CScript(), nSequence);
967 : }
968 178 : DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight());
969 :
970 : // Fill in final vin and shuffle/sort it
971 178 : if (sort_bip69) { std::sort(txNew.vin.begin(), txNew.vin.end(), CompareInputBIP69()); }
972 16 : else { Shuffle(txNew.vin.begin(), txNew.vin.end(), coin_selection_params.rng_fast); }
973 :
974 : // Calculate the transaction fee
975 178 : int nBytes = CalculateMaximumSignedTxSize(CTransaction(txNew), &wallet, &coin_control);
976 178 : if (nBytes == -1) {
977 0 : return util::Error{_("Missing solving data for estimating transaction size")};
978 : }
979 :
980 178 : if (nExtraPayloadSize != 0) {
981 : // account for extra payload in fee calculation
982 0 : nBytes += GetSizeOfCompactSize(nExtraPayloadSize) + nExtraPayloadSize;
983 0 : }
984 :
985 178 : CAmount fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes);
986 :
987 178 : if (!coin_selection_params.m_subtract_fee_outputs) {
988 111 : change_position->nValue -= fee_needed;
989 111 : }
990 :
991 : // We want to drop the change to fees if:
992 : // 1. The change output would be dust
993 : // 2. The change is within the (almost) exact match window, i.e. it is less than or equal to the cost of the change output (cost_of_change)
994 : // 3. We are working with fully mixed CoinJoin denominations
995 178 : CAmount change_amount = change_position->nValue;
996 178 : if (IsDust(*change_position, coin_selection_params.m_discard_feerate) || change_amount <= coin_selection_params.m_cost_of_change || coin_control.nCoinType == CoinType::ONLY_FULLY_MIXED)
997 : {
998 178 : nChangePosInOut = -1;
999 178 : change_amount = 0;
1000 178 : txNew.vout.erase(change_position);
1001 :
1002 82 : nBytes = CalculateMaximumSignedTxSize(CTransaction(txNew), &wallet, &coin_control);
1003 82 : fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes);
1004 82 : }
1005 :
1006 82 : nFeeRet = result->GetSelectedValue() - recipients_sum - change_amount;
1007 :
1008 : // The only time that fee_needed should be less than the amount available for fees is when
1009 : // we are subtracting the fee from the outputs. If this occurs at any other time, it is a bug.
1010 178 : if (!coin_selection_params.m_subtract_fee_outputs && fee_needed > nFeeRet) {
1011 7 : return util::Error{Untranslated(STR_INTERNAL_BUG("Fee needed > fee paid"))};
1012 : }
1013 :
1014 : // Update nFeeRet in case fee_needed changed due to dropping the change output
1015 171 : if (fee_needed <= change_and_fee - change_amount) {
1016 108 : nFeeRet = change_and_fee - change_amount;
1017 108 : }
1018 :
1019 : // Reduce output values for subtractFeeFromAmount
1020 171 : if (coin_selection_params.m_subtract_fee_outputs) {
1021 67 : CAmount to_reduce = fee_needed + change_amount - change_and_fee;
1022 67 : int i = 0;
1023 67 : bool fFirst = true;
1024 141 : for (const auto& recipient : sortedVecSend)
1025 : {
1026 87 : if (i == nChangePosInOut) {
1027 0 : ++i;
1028 0 : }
1029 87 : CTxOut& txout = txNew.vout[i];
1030 :
1031 87 : if (recipient.fSubtractFeeFromAmount)
1032 : {
1033 69 : txout.nValue -= to_reduce / outputs_to_subtract_fee_from; // Subtract fee equally from each selected recipient
1034 :
1035 69 : if (fFirst) // first receiver pays the remainder not divisible by output count
1036 : {
1037 67 : fFirst = false;
1038 67 : txout.nValue -= to_reduce % outputs_to_subtract_fee_from;
1039 67 : }
1040 : // Error if this output is reduced to be below dust
1041 69 : if (IsDust(txout, wallet.chain().relayDustFee())) {
1042 13 : if (txout.nValue < 0) {
1043 11 : return util::Error{_("The transaction amount is too small to pay the fee")};
1044 : } else {
1045 2 : return util::Error{_("The transaction amount is too small to send after the fee has been deducted")};
1046 : }
1047 : }
1048 56 : }
1049 74 : ++i;
1050 : }
1051 54 : nFeeRet = fee_needed;
1052 54 : }
1053 :
1054 : // Give up if change keypool ran out and change is required
1055 158 : if (scriptChange.empty() && nChangePosInOut != -1) {
1056 0 : return util::Error{error};
1057 : }
1058 :
1059 158 : if (sign && !wallet.SignTransaction(txNew)) {
1060 0 : return util::Error{_("Signing transaction failed")};
1061 : }
1062 :
1063 : // Return the constructed transaction data.
1064 158 : CTransactionRef tx = MakeTransactionRef(std::move(txNew));
1065 :
1066 : // Limit size
1067 158 : if ((sign && ::GetSerializeSize(*tx, PROTOCOL_VERSION) > MAX_STANDARD_TX_SIZE) ||
1068 157 : (!sign && static_cast<size_t>(nBytes) > MAX_STANDARD_TX_SIZE)) {
1069 1 : return util::Error{_("Transaction too large")};
1070 : }
1071 :
1072 157 : if (fee_needed > nFeeRet) {
1073 0 : return util::Error{_("Fee needed > fee paid")};
1074 : }
1075 :
1076 157 : if (nFeeRet > wallet.m_default_max_tx_fee) {
1077 1 : return util::Error{TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED)};
1078 : }
1079 :
1080 156 : if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
1081 : // Lastly, ensure this tx will pass the mempool's chain limits
1082 156 : if (!wallet.chain().checkChainLimits(tx)) {
1083 0 : return util::Error{_("Transaction has too long of a mempool chain")};
1084 : }
1085 156 : }
1086 :
1087 : // Before we return success, we assume any change key will be used to prevent
1088 : // accidental reuse.
1089 156 : reservedest.KeepDestination();
1090 :
1091 312 : wallet.WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
1092 156 : nFeeRet, nBytes, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
1093 156 : feeCalc.est.pass.start, feeCalc.est.pass.end,
1094 156 : (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool) > 0.0 ? 100 * feeCalc.est.pass.withinTarget / (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool) : 0.0,
1095 156 : feeCalc.est.pass.withinTarget, feeCalc.est.pass.totalConfirmed, feeCalc.est.pass.inMempool, feeCalc.est.pass.leftMempool,
1096 156 : feeCalc.est.fail.start, feeCalc.est.fail.end,
1097 156 : (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) > 0.0 ? 100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) : 0.0,
1098 156 : feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
1099 156 : return CreatedTransactionResult(tx, nFeeRet, nChangePosInOut, feeCalc);
1100 1946 : }
1101 :
1102 150 : util::Result<CreatedTransactionResult> CreateTransaction(
1103 : CWallet& wallet,
1104 : const std::vector<CRecipient>& vecSend,
1105 : int change_pos,
1106 : const CCoinControl& coin_control,
1107 : bool sign,
1108 : int nExtraPayloadSize)
1109 : {
1110 150 : if (vecSend.empty()) {
1111 1 : return util::Error{_("Transaction must have at least one recipient")};
1112 : }
1113 :
1114 6451 : if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](const auto& recipient){ return recipient.nAmount < 0; })) {
1115 1 : return util::Error{_("Transaction amounts must not be negative")};
1116 : }
1117 :
1118 148 : LOCK(wallet.cs_wallet);
1119 :
1120 148 : auto res = CreateTransactionInternal(wallet, vecSend, change_pos, coin_control, sign, nExtraPayloadSize);
1121 : TRACE4(coin_selection, normal_create_tx_internal, wallet.GetName().c_str(), bool(res),
1122 : res ? res->fee : 0, res ? res->change_pos : 0);
1123 148 : if (!res) return res;
1124 78 : const auto& txr_ungrouped = *res;
1125 : // try with avoidpartialspends unless it's enabled already
1126 78 : if (txr_ungrouped.fee > 0 /* 0 means non-functional fee rate estimation */ && wallet.m_max_aps_fee > -1 && !coin_control.m_avoid_partial_spends) {
1127 : TRACE1(coin_selection, attempting_aps_create_tx, wallet.GetName().c_str());
1128 78 : CCoinControl tmp_cc = coin_control;
1129 78 : tmp_cc.m_avoid_partial_spends = true;
1130 :
1131 : // Reuse the change destination from the first creation attempt to avoid skipping BIP44 indexes
1132 78 : const int ungrouped_change_pos = txr_ungrouped.change_pos;
1133 78 : if (ungrouped_change_pos != -1) {
1134 42 : ExtractDestination(txr_ungrouped.tx->vout[ungrouped_change_pos].scriptPubKey, tmp_cc.destChange);
1135 42 : }
1136 :
1137 78 : auto txr_grouped = CreateTransactionInternal(wallet, vecSend, change_pos, tmp_cc, sign, nExtraPayloadSize);
1138 : // if fee of this alternative one is within the range of the max fee, we use this one
1139 78 : const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee + wallet.m_max_aps_fee) : false};
1140 : TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
1141 : txr_grouped.has_value() ? txr_grouped->fee : 0, txr_grouped.has_value() ? txr_grouped->change_pos : 0);
1142 78 : if (txr_grouped) {
1143 156 : wallet.WalletLogPrintf("Fee non-grouped = %lld, grouped = %lld, using %s\n",
1144 78 : txr_ungrouped.fee, txr_grouped->fee, use_aps ? "grouped" : "non-grouped");
1145 78 : if (use_aps) return txr_grouped;
1146 2 : }
1147 78 : }
1148 2 : return res;
1149 150 : }
1150 :
1151 0 : bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
1152 : {
1153 0 : std::vector<CRecipient> vecSend;
1154 :
1155 : // If no specific change position was requested, apply BIP69
1156 0 : if (nChangePosInOut == -1) {
1157 0 : std::sort(tx.vin.begin(), tx.vin.end(), CompareInputBIP69());
1158 0 : std::sort(tx.vout.begin(), tx.vout.end(), CompareOutputBIP69());
1159 0 : }
1160 :
1161 : // Turn the txout set into a CRecipient vector.
1162 0 : for (size_t idx = 0; idx < tx.vout.size(); idx++) {
1163 0 : const CTxOut& txOut = tx.vout[idx];
1164 0 : CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, setSubtractFeeFromOutputs.count(idx) == 1};
1165 0 : vecSend.push_back(recipient);
1166 0 : }
1167 :
1168 : // Acquire the locks to prevent races to the new locked unspents between the
1169 : // CreateTransaction call and LockCoin calls (when lockUnspents is true).
1170 0 : LOCK(wallet.cs_wallet);
1171 :
1172 : // Fetch specified UTXOs from the UTXO set to get the scriptPubKeys and values of the outputs being selected
1173 : // and to match with the given solving_data. Only used for non-wallet outputs.
1174 0 : std::map<COutPoint, Coin> coins;
1175 0 : for (const CTxIn& txin : tx.vin) {
1176 0 : coins[txin.prevout]; // Create empty map entry keyed by prevout.
1177 : }
1178 0 : wallet.chain().findCoins(coins);
1179 :
1180 0 : for (const CTxIn& txin : tx.vin) {
1181 0 : const auto& outPoint = txin.prevout;
1182 0 : if (wallet.IsMine(outPoint)) {
1183 : // The input was found in the wallet, so select as internal
1184 0 : coinControl.Select(outPoint);
1185 0 : } else if (coins[outPoint].out.IsNull()) {
1186 0 : error = _("Unable to find UTXO for external input");
1187 0 : return false;
1188 : } else {
1189 : // The input was not in the wallet, but is in the UTXO set, so select as external
1190 0 : coinControl.SelectExternal(outPoint, coins[outPoint].out);
1191 : }
1192 : }
1193 :
1194 0 : auto res = CreateTransaction(wallet, vecSend, nChangePosInOut, coinControl, /*sign=*/false, tx.vExtraPayload.size());
1195 0 : if (!res) {
1196 0 : error = util::ErrorString(res);
1197 0 : return false;
1198 : }
1199 0 : const auto& txr = *res;
1200 0 : CTransactionRef tx_new = txr.tx;
1201 0 : nFeeRet = txr.fee;
1202 0 : nChangePosInOut = txr.change_pos;
1203 :
1204 0 : if (nChangePosInOut != -1) {
1205 0 : tx.vout.insert(tx.vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
1206 0 : }
1207 :
1208 : // Copy output sizes from new transaction; they may have had the fee
1209 : // subtracted from them.
1210 0 : for (unsigned int idx = 0; idx < tx.vout.size(); idx++) {
1211 0 : tx.vout[idx].nValue = tx_new->vout[idx].nValue;
1212 0 : }
1213 :
1214 : // Add new txins while keeping original txin scriptSig/order.
1215 0 : for (const CTxIn& txin : tx_new->vin) {
1216 0 : if (!coinControl.IsSelected(txin.prevout)) {
1217 0 : tx.vin.push_back(txin);
1218 :
1219 0 : }
1220 0 : if (lockUnspents) {
1221 0 : wallet.LockCoin(txin.prevout);
1222 0 : }
1223 :
1224 : }
1225 :
1226 0 : return true;
1227 0 : }
1228 :
1229 0 : bool GenBudgetSystemCollateralTx(CWallet& wallet, CTransactionRef& tx, uint256 hash, CAmount amount, const COutPoint& outpoint)
1230 : {
1231 0 : const CScript scriptChange{CScript() << OP_RETURN << ToByteVector(hash)};
1232 0 : const std::vector<CRecipient> vecSend{{scriptChange, amount, false}};
1233 :
1234 0 : CCoinControl coinControl;
1235 0 : if (!outpoint.IsNull()) {
1236 0 : coinControl.Select(outpoint);
1237 0 : }
1238 :
1239 0 : auto res{CreateTransaction(wallet, vecSend, RANDOM_CHANGE_POSITION, coinControl)};
1240 0 : if (!res) {
1241 0 : wallet.WalletLogPrintf("%s -- Error: %s\n", __func__, util::ErrorString(res).original);
1242 0 : return false;
1243 : }
1244 0 : tx = res->tx;
1245 0 : return true;
1246 0 : }
1247 : } // namespace wallet
|