Bitcoin ABC 0.34.2
P2P Digital Currency
spend.cpp
Go to the documentation of this file.
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 <wallet/spend.h>
6
7#include <common/args.h>
8#include <common/messages.h>
9#include <common/system.h>
11#include <interfaces/chain.h>
12#include <node/types.h>
13#include <policy/policy.h>
14#include <script/script.h>
15#include <util/check.h>
16#include <util/insert.h>
17#include <util/moneystr.h>
18#include <util/translation.h>
19#include <wallet/coincontrol.h>
20#include <wallet/fees.h>
21#include <wallet/receive.h>
22#include <wallet/transaction.h>
23#include <wallet/wallet.h>
24
27
28static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10;
29
30int GetTxSpendSize(const CWallet &wallet, const CWalletTx &wtx,
31 unsigned int out, bool use_max_sig) {
32 return CalculateMaximumSignedInputSize(wtx.tx->vout[out], &wallet,
33 use_max_sig);
34}
35std::string COutput::ToString() const {
36 return strprintf("COutput(%s, %d, %d) [%s]", tx->GetId().ToString(), i,
37 nDepth, FormatMoney(tx->tx->vout[i].nValue));
38}
39
41 bool use_max_sig) {
43 txn.vin.push_back(CTxIn(COutPoint()));
44 if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) {
45 return -1;
46 }
47 return GetSerializeSize(txn.vin[0]);
48}
49
50// txouts needs to be in the order of tx.vin
51int64_t CalculateMaximumSignedTxSize(const CTransaction &tx,
52 const CWallet *wallet,
53 const std::vector<CTxOut> &txouts,
54 bool use_max_sig) {
55 CMutableTransaction txNew(tx);
56 if (!wallet->DummySignTx(txNew, txouts, use_max_sig)) {
57 return -1;
58 }
59 return GetSerializeSize(txNew);
60}
61
62int64_t CalculateMaximumSignedTxSize(const CTransaction &tx,
63 const CWallet *wallet, bool use_max_sig) {
64 std::vector<CTxOut> txouts;
65 for (auto &input : tx.vin) {
66 const auto mi = wallet->mapWallet.find(input.prevout.GetTxId());
67 // Can not estimate size without knowing the input details
68 if (mi == wallet->mapWallet.end()) {
69 return -1;
70 }
71 assert(input.prevout.GetN() < mi->second.tx->vout.size());
72 txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]);
73 }
74 return CalculateMaximumSignedTxSize(tx, wallet, txouts, use_max_sig);
75}
76
77void AvailableCoins(const CWallet &wallet, std::vector<COutput> &vCoins,
78 const CCoinControl *coinControl,
79 const Amount nMinimumAmount, const Amount nMaximumAmount,
80 const Amount nMinimumSumAmount,
81 const uint64_t nMaximumCount) {
82 AssertLockHeld(wallet.cs_wallet);
83
84 vCoins.clear();
85 Amount nTotal = Amount::zero();
86 // Either the WALLET_FLAG_AVOID_REUSE flag is not set (in which case we
87 // always allow), or we default to avoiding, and only in the case where a
88 // coin control object is provided, and has the avoid address reuse flag set
89 // to false, do we allow already used addresses
90 bool allow_used_addresses =
91 !wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE) ||
92 (coinControl && !coinControl->m_avoid_address_reuse);
93 const int min_depth = {coinControl ? coinControl->m_min_depth
95 const int max_depth = {coinControl ? coinControl->m_max_depth
97 const bool only_safe = {coinControl ? !coinControl->m_include_unsafe_inputs
98 : true};
99
100 std::set<TxId> trusted_parents;
101 for (const auto &entry : wallet.mapWallet) {
102 const TxId &wtxid = entry.first;
103 const CWalletTx &wtx = entry.second;
104
105 if (wallet.IsTxImmatureCoinBase(wtx)) {
106 continue;
107 }
108
109 int nDepth = wallet.GetTxDepthInMainChain(wtx);
110 if (nDepth < 0) {
111 continue;
112 }
113
114 // We should not consider coins which aren't at least in our mempool.
115 // It's possible for these to be conflicted via ancestors which we may
116 // never be able to detect.
117 if (nDepth == 0 && !wtx.InMempool()) {
118 continue;
119 }
120
121 bool safeTx = CachedTxIsTrusted(wallet, wtx, trusted_parents);
122
123 // Bitcoin-ABC: Removed check that prevents consideration of coins from
124 // transactions that are replacing other transactions. This check based
125 // on wtx.mapValue.count("replaces_txid") which was not being set
126 // anywhere.
127
128 // Similarly, we should not consider coins from transactions that have
129 // been replaced. In the example above, we would want to prevent
130 // creation of a transaction A' spending an output of A, because if
131 // transaction B were initially confirmed, conflicting with A and A', we
132 // wouldn't want to the user to create a transaction D intending to
133 // replace A', but potentially resulting in a scenario where A, A', and
134 // D could all be accepted (instead of just B and D, or just A and A'
135 // like the user would want).
136
137 // Bitcoin-ABC: retained this check as 'replaced_by_txid' is still set
138 // in the wallet code.
139 if (nDepth == 0 && wtx.mapValue.count("replaced_by_txid")) {
140 safeTx = false;
141 }
142
143 if (only_safe && !safeTx) {
144 continue;
145 }
146
147 if (nDepth < min_depth || nDepth > max_depth) {
148 continue;
149 }
150
151 for (uint32_t i = 0; i < wtx.tx->vout.size(); i++) {
152 // Only consider selected coins if add_inputs is false
153 if (coinControl && !coinControl->m_add_inputs &&
154 !coinControl->IsSelected(COutPoint(entry.first, i))) {
155 continue;
156 }
157
158 if (wtx.tx->vout[i].nValue < nMinimumAmount ||
159 wtx.tx->vout[i].nValue > nMaximumAmount) {
160 continue;
161 }
162
163 const COutPoint outpoint(wtxid, i);
164
165 if (coinControl && coinControl->HasSelected() &&
166 !coinControl->fAllowOtherInputs &&
167 !coinControl->IsSelected(outpoint)) {
168 continue;
169 }
170
171 if (wallet.IsLockedCoin(outpoint)) {
172 continue;
173 }
174
175 if (wallet.IsSpent(outpoint)) {
176 continue;
177 }
178
179 isminetype mine = wallet.IsMine(wtx.tx->vout[i]);
180
181 if (mine == ISMINE_NO) {
182 continue;
183 }
184
185 if (!allow_used_addresses && wallet.IsSpentKey(wtxid, i)) {
186 continue;
187 }
188
189 std::unique_ptr<SigningProvider> provider =
190 wallet.GetSolvingProvider(wtx.tx->vout[i].scriptPubKey);
191
192 bool solvable =
193 provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey)
194 : false;
195 bool spendable =
196 ((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
197 (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) &&
198 (coinControl && coinControl->fAllowWatchOnly && solvable));
199
200 vCoins.push_back(
201 COutput(wallet, wtx, i, nDepth, spendable, solvable, safeTx,
202 (coinControl && coinControl->fAllowWatchOnly)));
203
204 // Checks the sum amount of all UTXO's.
205 if (nMinimumSumAmount != MAX_MONEY) {
206 nTotal += wtx.tx->vout[i].nValue;
207
208 if (nTotal >= nMinimumSumAmount) {
209 return;
210 }
211 }
212
213 // Checks the maximum number of UTXO's.
214 if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
215 return;
216 }
217 }
218 }
219}
220
222 const CCoinControl *coinControl) {
223 LOCK(wallet.cs_wallet);
224
226 std::vector<COutput> vCoins;
227 AvailableCoins(wallet, vCoins, coinControl);
228 for (const COutput &out : vCoins) {
229 if (out.fSpendable) {
230 balance += out.tx->tx->vout[out.i].nValue;
231 }
232 }
233 return balance;
234}
235
237 const CTransaction &tx, int output) {
238 AssertLockHeld(wallet.cs_wallet);
239 const CTransaction *ptx = &tx;
240 int n = output;
241 while (OutputIsChange(wallet, ptx->vout[n]) && ptx->vin.size() > 0) {
242 const COutPoint &prevout = ptx->vin[0].prevout;
243 auto it = wallet.mapWallet.find(prevout.GetTxId());
244 if (it == wallet.mapWallet.end() ||
245 it->second.tx->vout.size() <= prevout.GetN() ||
246 !wallet.IsMine(it->second.tx->vout[prevout.GetN()])) {
247 break;
248 }
249 ptx = it->second.tx.get();
250 n = prevout.GetN();
251 }
252 return ptx->vout[n];
253}
254
255std::map<CTxDestination, std::vector<COutput>>
257 AssertLockHeld(wallet.cs_wallet);
258
259 std::map<CTxDestination, std::vector<COutput>> result;
260 std::vector<COutput> availableCoins;
261
262 AvailableCoins(wallet, availableCoins);
263
264 for (COutput &coin : availableCoins) {
265 CTxDestination address;
266 if ((coin.fSpendable ||
267 (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) &&
268 coin.fSolvable)) &&
270 FindNonChangeParentOutput(wallet, *coin.tx->tx, coin.i)
272 address)) {
273 result[address].emplace_back(std::move(coin));
274 }
275 }
276
277 std::vector<COutPoint> lockedCoins;
278 wallet.ListLockedCoins(lockedCoins);
279 // Include watch-only for LegacyScriptPubKeyMan wallets without private keys
280 const bool include_watch_only =
281 wallet.GetLegacyScriptPubKeyMan() &&
283 const isminetype is_mine_filter =
284 include_watch_only ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
285 for (const auto &output : lockedCoins) {
286 auto it = wallet.mapWallet.find(output.GetTxId());
287 if (it != wallet.mapWallet.end()) {
288 int depth = wallet.GetTxDepthInMainChain(it->second);
289 if (depth >= 0 && output.GetN() < it->second.tx->vout.size() &&
290 wallet.IsMine(it->second.tx->vout[output.GetN()]) ==
291 is_mine_filter) {
292 CTxDestination address;
294 *it->second.tx,
295 output.GetN())
297 address)) {
298 result[address].emplace_back(
299 wallet, it->second, output.GetN(), depth,
300 true /* spendable */, true /* solvable */,
301 false /* safe */);
302 }
303 }
304 }
305 }
306
307 return result;
308}
309
310std::vector<OutputGroup>
311GroupOutputs(const CWallet &wallet, const std::vector<COutput> &outputs,
312 bool separate_coins, const CFeeRate &effective_feerate,
313 const CFeeRate &long_term_feerate,
314 const CoinEligibilityFilter &filter, bool positive_only) {
315 std::vector<OutputGroup> groups_out;
316
317 if (separate_coins) {
318 // Single coin means no grouping. Each COutput gets its own OutputGroup.
319 for (const COutput &output : outputs) {
320 // Skip outputs we cannot spend
321 if (!output.fSpendable) {
322 continue;
323 }
324
325 CInputCoin input_coin = output.GetInputCoin();
326
327 // Make an OutputGroup containing just this output
328 OutputGroup group{effective_feerate, long_term_feerate};
329 group.Insert(input_coin, output.nDepth,
330 CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL),
331 positive_only);
332
333 // Check the OutputGroup's eligibility. Only add the eligible ones.
334 if (positive_only && group.effective_value <= Amount::zero()) {
335 continue;
336 }
337 if (group.m_outputs.size() > 0 &&
338 group.EligibleForSpending(filter)) {
339 groups_out.push_back(group);
340 }
341 }
342 return groups_out;
343 }
344
345 // We want to combine COutputs that have the same scriptPubKey into single
346 // OutputGroups except when there are more than OUTPUT_GROUP_MAX_ENTRIES
347 // COutputs grouped in an OutputGroup.
348 // To do this, we maintain a map where the key is the scriptPubKey and the
349 // value is a vector of OutputGroups.
350 // For each COutput, we check if the scriptPubKey is in the map, and if it
351 // is, the COutput's CInputCoin is added to the last OutputGroup in the
352 // vector for the scriptPubKey. When the last OutputGroup has
353 // OUTPUT_GROUP_MAX_ENTRIES CInputCoins, a new OutputGroup is added to the
354 // end of the vector.
355 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
356 for (const auto &output : outputs) {
357 // Skip outputs we cannot spend
358 if (!output.fSpendable) {
359 continue;
360 }
361
362 CInputCoin input_coin = output.GetInputCoin();
363 CScript spk = input_coin.txout.scriptPubKey;
364
365 std::vector<OutputGroup> &groups = spk_to_groups_map[spk];
366
367 if (groups.size() == 0) {
368 // No OutputGroups for this scriptPubKey yet, add one
369 groups.emplace_back(effective_feerate, long_term_feerate);
370 }
371
372 // Get the last OutputGroup in the vector so that we can add the
373 // CInputCoin to it.
374 // A pointer is used here so that group can be reassigned later if it
375 // is full.
376 OutputGroup *group = &groups.back();
377
378 // Check if this OutputGroup is full. We limit to
379 // OUTPUT_GROUP_MAX_ENTRIES when using -avoidpartialspends to avoid
380 // surprising users with very high fees.
381 if (group->m_outputs.size() >= OUTPUT_GROUP_MAX_ENTRIES) {
382 // The last output group is full, add a new group to the vector and
383 // use that group for the insertion
384 groups.emplace_back(effective_feerate, long_term_feerate);
385 group = &groups.back();
386 }
387
388 // Add the input_coin to group
389 group->Insert(input_coin, output.nDepth,
390 CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL),
391 positive_only);
392 }
393
394 // Now we go through the entire map and pull out the OutputGroups
395 for (const auto &spk_and_groups_pair : spk_to_groups_map) {
396 const std::vector<OutputGroup> &groups_per_spk =
397 spk_and_groups_pair.second;
398
399 // Go through the vector backwards. This allows for the first item we
400 // deal with being the partial group.
401 for (auto group_it = groups_per_spk.rbegin();
402 group_it != groups_per_spk.rend(); group_it++) {
403 const OutputGroup &group = *group_it;
404
405 // Don't include partial groups if there are full groups too and we
406 // don't want partial groups
407 if (group_it == groups_per_spk.rbegin() &&
408 groups_per_spk.size() > 1 && !filter.m_include_partial_groups) {
409 continue;
410 }
411
412 // Check the OutputGroup's eligibility. Only add the eligible ones.
413 if (positive_only && group.effective_value <= Amount::zero()) {
414 continue;
415 }
416 if (group.m_outputs.size() > 0 &&
417 group.EligibleForSpending(filter)) {
418 groups_out.push_back(group);
419 }
420 }
421 }
422
423 return groups_out;
424}
425
426bool SelectCoinsMinConf(const CWallet &wallet, const Amount nTargetValue,
427 const CoinEligibilityFilter &eligibility_filter,
428 std::vector<COutput> coins,
429 std::set<CInputCoin> &setCoinsRet, Amount &nValueRet,
431 bool &bnb_used) {
432 setCoinsRet.clear();
433 nValueRet = Amount::zero();
434
436 // Get long term estimate
437 CCoinControl temp;
438 temp.m_confirm_target = 1008;
439 CFeeRate long_term_feerate = GetMinimumFeeRate(wallet, temp);
440
441 // Get the feerate for effective value.
442 // When subtracting the fee from the outputs, we want the effective
443 // feerate to be 0
444 CFeeRate effective_feerate{Amount::zero()};
446 effective_feerate = coin_selection_params.effective_fee;
447 }
448
449 std::vector<OutputGroup> groups = GroupOutputs(
451 effective_feerate, long_term_feerate, eligibility_filter,
452 /*positive_only=*/true);
453
454 // Calculate cost of change
455 Amount cost_of_change = wallet.chain().relayDustFee().GetFee(
459
460 // Calculate the fees for things that aren't inputs
463 bnb_used = true;
464 return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet,
465 nValueRet, not_input_fees);
466 } else {
467 std::vector<OutputGroup> groups = GroupOutputs(
470 eligibility_filter,
471 /*positive_only=*/false);
472
473 bnb_used = false;
474 return KnapsackSolver(nTargetValue, groups, setCoinsRet, nValueRet);
475 }
476}
477
479 const std::vector<COutput> &vAvailableCoins,
480 const Amount nTargetValue, std::set<CInputCoin> &setCoinsRet,
481 Amount &nValueRet, const CCoinControl &coin_control,
483 std::vector<COutput> vCoins(vAvailableCoins);
484 Amount value_to_select = nTargetValue;
485
486 // Default to bnb was not used. If we use it, we set it later
487 bnb_used = false;
488
489 // coin control -> return all selected outputs (we want all selected to go
490 // into the transaction for sure)
491 if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs) {
492 for (const COutput &out : vCoins) {
493 if (!out.fSpendable) {
494 continue;
495 }
496
497 nValueRet += out.tx->tx->vout[out.i].nValue;
498 setCoinsRet.insert(out.GetInputCoin());
499 }
500
501 return (nValueRet >= nTargetValue);
502 }
503
504 // Calculate value from preset inputs and store them.
505 std::set<CInputCoin> setPresetCoins;
506 Amount nValueFromPresetInputs = Amount::zero();
507
508 std::vector<COutPoint> vPresetInputs;
509 coin_control.ListSelected(vPresetInputs);
510
511 for (const COutPoint &outpoint : vPresetInputs) {
512 std::map<TxId, CWalletTx>::const_iterator it =
513 wallet.mapWallet.find(outpoint.GetTxId());
514 if (it != wallet.mapWallet.end()) {
515 const CWalletTx &wtx = it->second;
516 // Clearly invalid input, fail
517 if (wtx.tx->vout.size() <= outpoint.GetN()) {
518 return false;
519 }
520 // Just to calculate the marginal byte size
521 CInputCoin coin(
522 wtx.tx, outpoint.GetN(),
523 GetTxSpendSize(wallet, wtx, outpoint.GetN(), false));
524 nValueFromPresetInputs += coin.txout.nValue;
525 if (coin.m_input_bytes <= 0) {
526 // Not solvable, can't estimate size for fee
527 return false;
528 }
529 coin.effective_value =
530 coin.txout.nValue -
533 value_to_select -= coin.effective_value;
534 } else {
535 value_to_select -= coin.txout.nValue;
536 }
537 setPresetCoins.insert(coin);
538 } else {
539 return false; // TODO: Allow non-wallet inputs
540 }
541 }
542
543 // Remove preset inputs from vCoins
544 for (std::vector<COutput>::iterator it = vCoins.begin();
545 it != vCoins.end() && coin_control.HasSelected();) {
546 if (setPresetCoins.count(it->GetInputCoin())) {
547 it = vCoins.erase(it);
548 } else {
549 ++it;
550 }
551 }
552
553 // form groups from remaining coins; note that preset coins will not
554 // automatically have their associated (same address) coins included
555 if (coin_control.m_avoid_partial_spends &&
557 // Cases where we have 11+ outputs all pointing to the same destination
558 // may result in privacy leaks as they will potentially be
559 // deterministically sorted. We solve that by explicitly shuffling the
560 // outputs before processing
561 Shuffle(vCoins.begin(), vCoins.end(), FastRandomContext());
562 }
563
564 bool res =
565 value_to_select <= Amount::zero() ||
566 SelectCoinsMinConf(wallet, value_to_select, CoinEligibilityFilter(1, 6),
567 vCoins, setCoinsRet, nValueRet,
568 coin_selection_params, bnb_used) ||
569 SelectCoinsMinConf(wallet, value_to_select, CoinEligibilityFilter(1, 1),
570 vCoins, setCoinsRet, nValueRet,
571 coin_selection_params, bnb_used) ||
572 (wallet.m_spend_zero_conf_change &&
573 SelectCoinsMinConf(wallet, value_to_select,
574 CoinEligibilityFilter(0, 1), vCoins, setCoinsRet,
575 nValueRet, coin_selection_params, bnb_used)) ||
576 (wallet.m_spend_zero_conf_change &&
577 SelectCoinsMinConf(wallet, value_to_select,
578 CoinEligibilityFilter(0, 1), vCoins, setCoinsRet,
579 nValueRet, coin_selection_params, bnb_used)) ||
580 (wallet.m_spend_zero_conf_change &&
581 SelectCoinsMinConf(wallet, value_to_select,
582 CoinEligibilityFilter(0, 1), vCoins, setCoinsRet,
583 nValueRet, coin_selection_params, bnb_used)) ||
584 (wallet.m_spend_zero_conf_change &&
586 wallet, value_to_select,
587 CoinEligibilityFilter(0, 1, /*include_partial_groups=*/true),
588 vCoins, setCoinsRet, nValueRet, coin_selection_params,
589 bnb_used)) ||
590 (wallet.m_spend_zero_conf_change &&
592 wallet, value_to_select,
593 CoinEligibilityFilter(0, 1, /*include_partial_groups=*/true),
594 vCoins, setCoinsRet, nValueRet, coin_selection_params,
595 bnb_used)) ||
596 // Try with unsafe inputs if they are allowed. This may spend
597 // unconfirmed outputs received from other wallets.
598 (coin_control.m_include_unsafe_inputs &&
600 wallet, value_to_select,
601 CoinEligibilityFilter(/*conf_mine=*/0, /*conf_theirs=*/0,
602 /*include_partial_groups=*/true),
603 vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
604
605 // Because SelectCoinsMinConf clears the setCoinsRet, we now add the
606 // possible inputs to the coinset.
607 util::insert(setCoinsRet, setPresetCoins);
608
609 // Add preset inputs to the total value selected.
610 nValueRet += nValueFromPresetInputs;
611
612 return res;
613}
614
616 CWallet &wallet, const std::vector<CRecipient> &vecSend, int change_pos,
617 const CCoinControl &coin_control, bool sign) {
618 // TODO: remember to add the lock annotation when adding AssertLockHeld.
619 // The lock annotation was added by core in PR22100, but due to
620 // other missing backports it was not possible to add it during that
621 // backport.
622
623 // out variables, to be packed into returned result structure
624 Amount nFeeRet;
625 int nChangePosInOut = change_pos;
626
627 Amount nValue = Amount::zero();
628 const OutputType change_type = wallet.TransactionChangeType(
629 coin_control.m_change_type ? *coin_control.m_change_type
630 : wallet.m_default_change_type,
631 vecSend);
632 ReserveDestination reservedest(&wallet, change_type);
633 int nChangePosRequest = nChangePosInOut;
634 unsigned int nSubtractFeeFromAmount = 0;
635 for (const auto &recipient : vecSend) {
636 if (nValue < Amount::zero() || recipient.nAmount < Amount::zero()) {
637 return util::Error{_("Transaction amounts must not be negative")};
638 }
639
640 nValue += recipient.nAmount;
641
642 if (recipient.fSubtractFeeFromAmount) {
643 nSubtractFeeFromAmount++;
644 }
645 }
646
647 if (vecSend.empty()) {
648 return util::Error{_("Transaction must have at least one recipient")};
649 }
650
652 {
654 std::set<CInputCoin> setCoins;
655 LOCK(wallet.cs_wallet);
656 // Previously the locktime was set to the current block height, to
657 // prevent fee-sniping. This is now disabled as fee-sniping is mitigated
658 // by avalanche post-consensus. Consistently Using a locktime of 0 for
659 // most wallets in the ecosystem improves privacy, as this is the
660 // easiest solution to implement for light wallets which are not aware
661 // of the current block height.
662 txNew.nLockTime = 0;
663 std::vector<COutput> vAvailableCoins;
664 AvailableCoins(wallet, vAvailableCoins, &coin_control);
665 // Parameters for coin selection, init with dummy
668 coin_control.m_avoid_partial_spends;
669
670 // Create change script that will be used if we need change
671 // TODO: pass in scriptChange instead of reservedest so
672 // change transaction isn't always pay-to-bitcoin-address
673 CScript scriptChange;
674 bilingual_str error; // possible error str
675
676 // coin control: send change to custom address
677 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
678 scriptChange = GetScriptForDestination(coin_control.destChange);
679
680 // no coin control: send change to newly generated address
681 } else {
682 // Note: We use a new key here to keep it from being obvious
683 // which side is the change.
684 // The drawback is that by not reusing a previous key, the
685 // change may be lost if a backup is restored, if the backup
686 // doesn't have the new private key for the change. If we
687 // reused the old key, it would be possible to add code to look
688 // for and rediscover unknown transactions that were written
689 // with keys of ours to recover post-backup change.
690
691 // Reserve a new key pair from key pool. If it fails, provide a
692 // dummy destination in case we don't need change.
693 CTxDestination dest;
694 if (!reservedest.GetReservedDestination(dest, true)) {
695 error = _("Transaction needs a change address, but we can't "
696 "generate it. Please call keypoolrefill first.");
697 }
698
699 scriptChange = GetScriptForDestination(dest);
700 // A valid destination implies a change script (and
701 // vice-versa). An empty change script will abort later, if the
702 // change keypool ran out, but change is required.
703 CHECK_NONFATAL(IsValidDestination(dest) != scriptChange.empty());
704 }
705 CTxOut change_prototype_txout(Amount::zero(), scriptChange);
707 GetSerializeSize(change_prototype_txout);
708
709 // Get the fee rate to use effective values in coin selection
710 CFeeRate nFeeRateNeeded = GetMinimumFeeRate(wallet, coin_control);
711 // Do not, ever, assume that it's fine to change the fee rate if the
712 // user has explicitly provided one
713 if (coin_control.m_feerate &&
714 nFeeRateNeeded > *coin_control.m_feerate) {
715 return util::Error{strprintf(
716 _("Fee rate (%s) is lower than the minimum fee "
717 "rate setting (%s)"),
718 coin_control.m_feerate->ToString(), nFeeRateNeeded.ToString())};
719 }
720
721 nFeeRet = Amount::zero();
722 bool pick_new_inputs = true;
723 Amount nValueIn = Amount::zero();
724
725 // BnB selector is the only selector used when this is true.
726 // That should only happen on the first pass through the loop.
728 // If we are doing subtract fee from recipient, don't use effective
729 // values
731 nSubtractFeeFromAmount != 0;
732 // Start with no fee and loop until there is enough fee
733 while (true) {
734 nChangePosInOut = nChangePosRequest;
735 txNew.vin.clear();
736 txNew.vout.clear();
737 bool fFirst = true;
738
739 Amount nValueToSelect = nValue;
740 if (nSubtractFeeFromAmount == 0) {
741 nValueToSelect += nFeeRet;
742 }
743
744 // vouts to the payees
746 // Static size overhead + outputs vsize. 4 nVersion, 4
747 // nLocktime, 1 input count, 1 output count
749 }
750 // vouts to the payees
751 for (const auto &recipient : vecSend) {
752 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
753
754 if (recipient.fSubtractFeeFromAmount) {
755 assert(nSubtractFeeFromAmount != 0);
756 // Subtract fee equally from each selected recipient.
757 txout.nValue -= nFeeRet / int(nSubtractFeeFromAmount);
758
759 // First receiver pays the remainder not divisible by output
760 // count.
761 if (fFirst) {
762 fFirst = false;
763 txout.nValue -= nFeeRet % int(nSubtractFeeFromAmount);
764 }
765 }
766
767 // Include the fee cost for outputs. Note this is only used for
768 // BnB right now
771 ::GetSerializeSize(txout);
772 }
773
774 if (IsDust(txout, wallet.chain().relayDustFee())) {
775 if (recipient.fSubtractFeeFromAmount &&
776 nFeeRet > Amount::zero()) {
777 if (txout.nValue < Amount::zero()) {
778 error = _("The transaction amount is too small to "
779 "pay the fee");
780 } else {
781 error = _("The transaction amount is too small to "
782 "send after the fee has been deducted");
783 }
784 } else {
785 error = _("Transaction amount too small");
786 }
787
788 return util::Error{error};
789 }
790
791 txNew.vout.push_back(txout);
792 }
793
794 // Choose coins to use
795 bool bnb_used = false;
796 if (pick_new_inputs) {
797 nValueIn = Amount::zero();
798 setCoins.clear();
799 int change_spend_size = CalculateMaximumSignedInputSize(
800 change_prototype_txout, &wallet);
801 // If the wallet doesn't know how to sign change output, assume
802 // p2pkh as lower-bound to allow BnB to do it's thing
803 if (change_spend_size == -1) {
806 } else {
808 size_t(change_spend_size);
809 }
810 coin_selection_params.effective_fee = nFeeRateNeeded;
811 if (!SelectCoins(wallet, vAvailableCoins, nValueToSelect,
812 setCoins, nValueIn, coin_control,
813 coin_selection_params, bnb_used)) {
814 // If BnB was used, it was the first pass. No longer the
815 // first pass and continue loop with knapsack.
816 if (bnb_used) {
818 continue;
819 } else {
820 return util::Error{_("Insufficient funds")};
821 }
822 }
823 } else {
824 bnb_used = false;
825 }
826
827 const Amount nChange = nValueIn - nValueToSelect;
828 if (nChange > Amount::zero()) {
829 // Fill a vout to ourself.
830 CTxOut newTxOut(nChange, scriptChange);
831
832 // Never create dust outputs; if we would, just add the dust to
833 // the fee.
834 // The nChange when BnB is used is always going to go to fees.
835 if (IsDust(newTxOut, wallet.chain().relayDustFee()) ||
836 bnb_used) {
837 nChangePosInOut = -1;
838 nFeeRet += nChange;
839 } else {
840 if (nChangePosInOut == -1) {
841 // Insert change txn at random position:
842 nChangePosInOut = FastRandomContext().randrange<int>(
843 txNew.vout.size() + 1);
844 } else if ((unsigned int)nChangePosInOut >
845 txNew.vout.size()) {
846 return util::Error{_("Change index out of range")};
847 }
848
849 std::vector<CTxOut>::iterator position =
850 txNew.vout.begin() + nChangePosInOut;
851 txNew.vout.insert(position, newTxOut);
852 }
853 } else {
854 nChangePosInOut = -1;
855 }
856
857 // Dummy fill vin for maximum size estimation
858 //
859 for (const auto &coin : setCoins) {
860 txNew.vin.push_back(CTxIn(coin.outpoint, CScript()));
861 }
862
863 CTransaction txNewConst(txNew);
864 int nBytes = CalculateMaximumSignedTxSize(
865 txNewConst, &wallet, coin_control.fAllowWatchOnly);
866 if (nBytes < 0) {
867 return util::Error{_("Signing transaction failed")};
868 }
869
870 Amount nFeeNeeded = GetMinimumFee(wallet, nBytes, coin_control);
871
872 if (nFeeRet >= nFeeNeeded) {
873 // Reduce fee to only the needed amount if possible. This
874 // prevents potential overpayment in fees if the coins selected
875 // to meet nFeeNeeded result in a transaction that requires less
876 // fee than the prior iteration.
877
878 // If we have no change and a big enough excess fee, then try to
879 // construct transaction again only without picking new inputs.
880 // We now know we only need the smaller fee (because of reduced
881 // tx size) and so we should add a change output. Only try this
882 // once.
883 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 &&
884 pick_new_inputs) {
885 // Add 2 as a buffer in case increasing # of outputs changes
886 // compact size
887 unsigned int tx_size_with_change =
889 Amount fee_needed_with_change = GetMinimumFee(
890 wallet, tx_size_with_change, coin_control);
891 Amount minimum_value_for_change = GetDustThreshold(
892 change_prototype_txout, wallet.chain().relayDustFee());
893 if (nFeeRet >=
894 fee_needed_with_change + minimum_value_for_change) {
895 pick_new_inputs = false;
896 nFeeRet = fee_needed_with_change;
897 continue;
898 }
899 }
900
901 // If we have change output already, just increase it
902 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 &&
903 nSubtractFeeFromAmount == 0) {
904 Amount extraFeePaid = nFeeRet - nFeeNeeded;
905 std::vector<CTxOut>::iterator change_position =
906 txNew.vout.begin() + nChangePosInOut;
907 change_position->nValue += extraFeePaid;
908 nFeeRet -= extraFeePaid;
909 }
910
911 // Done, enough fee included.
912 break;
913 } else if (!pick_new_inputs) {
914 // This shouldn't happen, we should have had enough excess fee
915 // to pay for the new output and still meet nFeeNeeded.
916 // Or we should have just subtracted fee from recipients and
917 // nFeeNeeded should not have changed.
918 return util::Error{
919 _("Transaction fee and change calculation failed")};
920 }
921
922 // Try to reduce change to include necessary fee.
923 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
924 Amount additionalFeeNeeded = nFeeNeeded - nFeeRet;
925 std::vector<CTxOut>::iterator change_position =
926 txNew.vout.begin() + nChangePosInOut;
927 // Only reduce change if remaining amount is still a large
928 // enough output.
929 if (change_position->nValue >=
930 MIN_FINAL_CHANGE + additionalFeeNeeded) {
931 change_position->nValue -= additionalFeeNeeded;
932 nFeeRet += additionalFeeNeeded;
933 // Done, able to increase fee from change.
934 break;
935 }
936 }
937
938 // If subtracting fee from recipients, we now know what fee we
939 // need to subtract, we have no reason to reselect inputs.
940 if (nSubtractFeeFromAmount > 0) {
941 pick_new_inputs = false;
942 }
943
944 // Include more fee and try again.
945 nFeeRet = nFeeNeeded;
947 continue;
948 }
949
950 // Give up if change keypool ran out and change is required
951 if (scriptChange.empty() && nChangePosInOut != -1) {
952 return util::Error{error};
953 }
954
955 // Shuffle selected coins and fill in final vin
956 txNew.vin.clear();
957 std::vector<CInputCoin> selected_coins(setCoins.begin(),
958 setCoins.end());
959 Shuffle(selected_coins.begin(), selected_coins.end(),
961
962 // Note how the sequence number is set to non-maxint so that
963 // the nLockTime set above actually works.
964 for (const auto &coin : selected_coins) {
965 txNew.vin.push_back(
966 CTxIn(coin.outpoint, CScript(),
967 std::numeric_limits<uint32_t>::max() - 1));
968 }
969
970 if (sign && !wallet.SignTransaction(txNew)) {
971 return util::Error{_("Signing transaction failed")};
972 }
973
974 // Return the constructed transaction data.
975 tx = MakeTransactionRef(std::move(txNew));
976
977 // Limit size.
978 if (tx->GetTotalSize() > MAX_STANDARD_TX_SIZE) {
979 return util::Error{_("Transaction too large")};
980 }
981 }
982
983 if (nFeeRet > wallet.m_default_max_tx_fee) {
984 return util::Error{
985 TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED)};
986 }
987
988 // Before we return success, we assume any change key will be used to
989 // prevent accidental re-use.
990 reservedest.KeepDestination();
991
992 return CreatedTransactionResult(tx, nFeeRet, nChangePosInOut);
993}
994
996CreateTransaction(CWallet &wallet, const std::vector<CRecipient> &vecSend,
997 int change_pos, const CCoinControl &coin_control, bool sign) {
998 auto res = CreateTransactionInternal(wallet, vecSend, change_pos,
999 coin_control, sign);
1000 if (!res) {
1001 return res;
1002 }
1003 const auto &txr_ungrouped = *res;
1004 // try with avoidpartialspends unless it's enabled already
1005 // 0 as fee means non-functional fee rate estimation
1006 if (txr_ungrouped.fee > Amount::zero() &&
1007 wallet.m_max_aps_fee > (-1 * SATOSHI) &&
1008 !coin_control.m_avoid_partial_spends) {
1009 CCoinControl tmp_cc = coin_control;
1010 tmp_cc.m_avoid_partial_spends = true;
1011 // fired and forgotten; if an error occurs, we discard the results
1012 bilingual_str error2;
1013 auto txr_grouped = CreateTransactionInternal(wallet, vecSend,
1014 change_pos, tmp_cc, sign);
1015 if (txr_grouped) {
1016 // if fee of this alternative one is within the range of the max
1017 // fee, we use this one
1018 const bool use_aps =
1019 txr_grouped->fee <= txr_ungrouped.fee + wallet.m_max_aps_fee;
1020 wallet.WalletLogPrintf(
1021 "Fee non-grouped = %lld, grouped = %lld, using %s\n",
1022 txr_ungrouped.fee, txr_grouped->fee,
1023 use_aps ? "grouped" : "non-grouped");
1024 if (use_aps) {
1025 return txr_grouped;
1026 }
1027 }
1028 }
1029 return res;
1030}
1031
1033 int &nChangePosInOut, bilingual_str &error,
1034 bool lockUnspents,
1035 const std::set<int> &setSubtractFeeFromOutputs,
1036 CCoinControl coinControl) {
1037 std::vector<CRecipient> vecSend;
1038
1039 // Turn the txout set into a CRecipient vector.
1040 for (size_t idx = 0; idx < tx.vout.size(); idx++) {
1041 const CTxOut &txOut = tx.vout[idx];
1042 CRecipient recipient = {txOut.scriptPubKey, txOut.nValue,
1043 setSubtractFeeFromOutputs.count(idx) == 1};
1044 vecSend.push_back(recipient);
1045 }
1046
1047 coinControl.fAllowOtherInputs = true;
1048
1049 for (const CTxIn &txin : tx.vin) {
1050 coinControl.Select(txin.prevout);
1051 }
1052
1053 // Acquire the locks to prevent races to the new locked unspents between the
1054 // CreateTransaction call and LockCoin calls (when lockUnspents is true).
1055 LOCK(wallet.cs_wallet);
1056
1057 auto res =
1058 CreateTransaction(wallet, vecSend, nChangePosInOut, coinControl, false);
1059 if (!res) {
1060 error = util::ErrorString(res);
1061 return false;
1062 }
1063 const auto &txr = *res;
1064 CTransactionRef tx_new = txr.tx;
1065 nFeeRet = txr.fee;
1066 nChangePosInOut = txr.change_pos;
1067
1068 if (nChangePosInOut != -1) {
1069 tx.vout.insert(tx.vout.begin() + nChangePosInOut,
1070 tx_new->vout[nChangePosInOut]);
1071 }
1072
1073 // Copy output sizes from new transaction; they may have had the fee
1074 // subtracted from them.
1075 for (size_t idx = 0; idx < tx.vout.size(); idx++) {
1076 tx.vout[idx].nValue = tx_new->vout[idx].nValue;
1077 }
1078
1079 // Add new txins (keeping original txin scriptSig/order)
1080 for (const CTxIn &txin : tx_new->vin) {
1081 if (!coinControl.IsSelected(txin.prevout)) {
1082 tx.vin.push_back(txin);
1083 }
1084 if (lockUnspents) {
1085 wallet.LockCoin(txin.prevout);
1086 }
1087 }
1088
1089 return true;
1090}
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: addresstype.cpp:33
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: addresstype.h:54
static constexpr Amount SATOSHI
Definition: amount.h:153
static constexpr Amount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:176
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:83
Coin Control Features.
Definition: coincontrol.h:20
std::optional< OutputType > m_change_type
Override the default change type if set, ignored if destChange is set.
Definition: coincontrol.h:24
bool HasSelected() const
Definition: coincontrol.h:53
std::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
Definition: coincontrol.h:39
bool IsSelected(const COutPoint &output) const
Definition: coincontrol.h:55
int m_max_depth
Maximum chain depth value for coin availability.
Definition: coincontrol.h:47
void Select(const COutPoint &output)
Definition: coincontrol.h:59
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
Definition: coincontrol.h:33
int m_min_depth
Minimum chain depth value for coin availability.
Definition: coincontrol.h:45
std::optional< CFeeRate > m_feerate
Override the wallet's m_pay_tx_fee if set.
Definition: coincontrol.h:37
bool m_add_inputs
If false, only selected inputs are used.
Definition: coincontrol.h:26
CTxDestination destChange
Definition: coincontrol.h:22
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
Definition: coincontrol.h:43
bool m_include_unsafe_inputs
If false, only safe inputs will be used (confirmed or self transfers)
Definition: coincontrol.h:28
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
Definition: coincontrol.h:41
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
Definition: coincontrol.h:31
void ListSelected(std::vector< COutPoint > &vOutpoints) const
Definition: coincontrol.h:65
Fee rate in satoshis per virtualbyte: Amount / vB the feerate is represented internally as FeeFrac.
Definition: feerate.h:24
Amount GetFee(int32_t virtual_bytes) const
Return the fee in satoshis for the given size in bytes.
Definition: feerate.cpp:23
std::string ToString() const
Definition: feerate.cpp:43
int m_input_bytes
Pre-computed estimated size of this output as a fully-signed input in a transaction.
Definition: coinselection.h:47
CTxOut txout
Definition: coinselection.h:38
Amount effective_value
Definition: coinselection.h:39
A mutable version of CTransaction.
Definition: transaction.h:274
std::vector< CTxOut > vout
Definition: transaction.h:277
std::vector< CTxIn > vin
Definition: transaction.h:276
Definition: spend.h:22
int nDepth
Definition: spend.h:26
const CWalletTx * tx
Definition: spend.h:24
std::string ToString() const
Definition: spend.cpp:35
int i
Definition: spend.h:25
An output of a transaction.
Definition: transaction.h:128
CScript scriptPubKey
Definition: transaction.h:131
Amount nValue
Definition: transaction.h:130
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:270
A transaction with a bunch of additional info that only the owner cares about.
Definition: transaction.h:65
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: transaction.h:99
CTransactionRef tx
Definition: transaction.h:160
TxId GetId() const
Definition: transaction.h:301
bool InMempool() const
Definition: transaction.cpp:21
Fast randomness source.
Definition: random.h:411
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
Definition: random.h:266
A wrapper to reserve an address from a wallet.
Definition: wallet.h:177
std::string ToString() const
Definition: uint256.h:117
const int DEFAULT_MAX_DEPTH
Definition: coincontrol.h:14
const int DEFAULT_MIN_DEPTH
Definition: coincontrol.h:13
bool KnapsackSolver(const Amount nTargetValue, std::vector< OutputGroup > &groups, std::set< CInputCoin > &setCoinsRet, Amount &nValueRet)
bool SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const Amount &target_value, const Amount &cost_of_change, std::set< CInputCoin > &out_set, Amount &value_ret, const Amount not_input_fees)
This is the Branch and Bound Coin Selection algorithm designed by Murch.
static const Amount MIN_FINAL_CHANGE
final minimum change amount after paying for fees
Definition: coinselection.h:15
static std::vector< COutput > vCoins
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(Amount::zero()), 0, false)
static Amount balance
void KeepDestination()
Keep the address.
Definition: wallet.cpp:2521
bool GetReservedDestination(CTxDestination &pubkey, bool internal)
Reserve an address.
Definition: wallet.cpp:2500
isminetype
IsMine() return codes.
Definition: ismine.h:18
@ ISMINE_ALL
Definition: ismine.h:23
@ ISMINE_SPENDABLE
Definition: ismine.h:21
@ ISMINE_NO
Definition: ismine.h:19
@ ISMINE_WATCH_ONLY
Definition: ismine.h:20
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
Definition: moneystr.cpp:13
bilingual_str TransactionErrorString(const TransactionError error)
Definition: messages.cpp:36
TransactionError
Definition: types.h:17
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:90
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
Definition: insert.h:14
is a home for public enum and struct type definitions that are used by internally by node code,...
OutputType
Definition: outputtype.h:16
Amount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Definition: policy.cpp:14
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Definition: policy.cpp:36
static constexpr unsigned int MAX_STANDARD_TX_SIZE
The maximum size for transactions we're willing to relay/mine.
Definition: policy.h:36
static CTransactionRef MakeTransactionRef()
Definition: transaction.h:316
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:315
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:512
bool CachedTxIsFromMe(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
Definition: receive.cpp:321
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
Definition: receive.cpp:98
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< TxId > &trusted_parents)
Definition: receive.cpp:326
size_t GetSerializeSize(const T &t)
Definition: serialize.h:1264
bool IsSolvable(const SigningProvider &provider, const CScript &script)
Check whether we know how to sign for an output like this, assuming we have all private keys.
Definition: sign.cpp:436
int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *wallet, bool use_max_sig)
Get the marginal bytes of spending the specified output.
Definition: spend.cpp:40
bool SelectCoinsMinConf(const CWallet &wallet, const Amount nTargetValue, const CoinEligibilityFilter &eligibility_filter, std::vector< COutput > coins, std::set< CInputCoin > &setCoinsRet, Amount &nValueRet, const CoinSelectionParams &coin_selection_params, bool &bnb_used)
Shuffle and select coins until nTargetValue is reached while avoiding small change; This method is st...
Definition: spend.cpp:426
bool FundTransaction(CWallet &wallet, CMutableTransaction &tx, Amount &nFeeRet, int &nChangePosInOut, bilingual_str &error, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, CCoinControl coinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
Definition: spend.cpp:1032
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
Definition: spend.cpp:256
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector< CTxOut > &txouts, bool use_max_sig)
Calculate the size of the transaction assuming all signatures are max size Use DummySignatureCreator,...
Definition: spend.cpp:51
const CTxOut & FindNonChangeParentOutput(const CWallet &wallet, const CTransaction &tx, int output)
Find non-change parent output.
Definition: spend.cpp:236
std::vector< OutputGroup > GroupOutputs(const CWallet &wallet, const std::vector< COutput > &outputs, bool separate_coins, const CFeeRate &effective_feerate, const CFeeRate &long_term_feerate, const CoinEligibilityFilter &filter, bool positive_only)
Definition: spend.cpp:311
static const size_t OUTPUT_GROUP_MAX_ENTRIES
Definition: spend.cpp:28
util::Result< CreatedTransactionResult > CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, int change_pos, const CCoinControl &coin_control, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: spend.cpp:996
void AvailableCoins(const CWallet &wallet, std::vector< COutput > &vCoins, const CCoinControl *coinControl, const Amount nMinimumAmount, const Amount nMaximumAmount, const Amount nMinimumSumAmount, const uint64_t nMaximumCount)
populate vCoins with vector of available COutputs.
Definition: spend.cpp:77
static util::Result< CreatedTransactionResult > CreateTransactionInternal(CWallet &wallet, const std::vector< CRecipient > &vecSend, int change_pos, const CCoinControl &coin_control, bool sign)
Definition: spend.cpp:615
int GetTxSpendSize(const CWallet &wallet, const CWalletTx &wtx, unsigned int out, bool use_max_sig)
Get the marginal bytes if spending the specified output from this transaction.
Definition: spend.cpp:30
Amount GetAvailableBalance(const CWallet &wallet, const CCoinControl *coinControl)
Definition: spend.cpp:221
bool SelectCoins(const CWallet &wallet, const std::vector< COutput > &vAvailableCoins, const Amount nTargetValue, std::set< CInputCoin > &setCoinsRet, Amount &nValueRet, const CCoinControl &coin_control, CoinSelectionParams &coin_selection_params, bool &bnb_used)
Select a set of coins such that nValueRet >= nTargetValue and at least all coins from coin_control ar...
Definition: spend.cpp:478
Definition: amount.h:23
static constexpr Amount zero() noexcept
Definition: amount.h:36
const bool m_include_partial_groups
Include partial destination groups when avoid_reuse and there are full groups.
Definition: coinselection.h:71
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
Definition: wallet.h:249
size_t change_spend_size
Definition: wallet.h:245
size_t tx_noinputs_size
Definition: wallet.h:247
bool m_avoid_partial_spends
Definition: wallet.h:250
CFeeRate effective_fee
Definition: wallet.h:246
size_t change_output_size
Definition: wallet.h:244
A TxId is the identifier of a transaction.
Definition: txid.h:14
Bilingual messages:
Definition: translation.h:17
#define LOCK(cs)
Definition: sync.h:295
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1203
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())
Amount GetMinimumFee(const CWallet &wallet, unsigned int nTxBytes, const CCoinControl &coin_control)
Estimate the minimum fee considering user set parameters and the required fee.
Definition: fees.cpp:17
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control)
Estimate the minimum fee rate considering user set parameters and the required fee.
Definition: fees.cpp:27
static constexpr size_t DUMMY_P2PKH_INPUT_SIZE
Pre-calculated constants for input size estimation.
Definition: wallet.h:131
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Definition: walletutil.h:55
@ WALLET_FLAG_AVOID_REUSE
Definition: walletutil.h:47