30 unsigned int out,
bool use_max_sig) {
42 txn.
vin.push_back(CTxIn(COutPoint()));
43 if (!
wallet->DummySignInput(txn.
vin[0], txout, use_max_sig)) {
52 const std::vector<CTxOut> &txouts,
55 if (!
wallet->DummySignTx(txNew, txouts, use_max_sig)) {
63 std::vector<CTxOut> txouts;
64 for (
auto &input : tx.vin) {
65 const auto mi =
wallet->mapWallet.find(input.prevout.GetTxId());
67 if (mi ==
wallet->mapWallet.end()) {
70 assert(input.prevout.GetN() < mi->second.tx->vout.size());
71 txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]);
78 const Amount nMinimumAmount,
const Amount nMaximumAmount,
79 const Amount nMinimumSumAmount,
80 const uint64_t nMaximumCount) {
89 bool allow_used_addresses =
92 const int min_depth = {coinControl ? coinControl->
m_min_depth
94 const int max_depth = {coinControl ? coinControl->
m_max_depth
99 std::set<TxId> trusted_parents;
100 for (
const auto &entry :
wallet.mapWallet) {
101 const TxId &wtxid = entry.first;
104 if (
wallet.IsTxImmatureCoinBase(wtx)) {
108 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
138 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
142 if (only_safe && !safeTx) {
146 if (nDepth < min_depth || nDepth > max_depth) {
150 for (uint32_t i = 0; i < wtx.
tx->vout.size(); i++) {
153 !coinControl->
IsSelected(COutPoint(entry.first, i))) {
157 if (wtx.
tx->vout[i].nValue < nMinimumAmount ||
158 wtx.
tx->vout[i].nValue > nMaximumAmount) {
162 const COutPoint outpoint(wtxid, i);
170 if (
wallet.IsLockedCoin(outpoint)) {
174 if (
wallet.IsSpent(outpoint)) {
184 if (!allow_used_addresses &&
wallet.IsSpentKey(wtxid, i)) {
188 std::unique_ptr<SigningProvider> provider =
189 wallet.GetSolvingProvider(wtx.
tx->vout[i].scriptPubKey);
192 provider ?
IsSolvable(*provider, wtx.
tx->vout[i].scriptPubKey)
205 nTotal += wtx.
tx->vout[i].nValue;
207 if (nTotal >= nMinimumSumAmount) {
213 if (nMaximumCount > 0 &&
vCoins.size() >= nMaximumCount) {
225 std::vector<COutput>
vCoins;
228 if (out.fSpendable) {
229 balance += out.tx->tx->vout[out.i].nValue;
236 const CTransaction &tx,
int output) {
238 const CTransaction *ptx = &tx;
241 const COutPoint &prevout = ptx->vin[0].prevout;
242 auto it =
wallet.mapWallet.find(prevout.GetTxId());
243 if (it ==
wallet.mapWallet.end() ||
244 it->second.tx->vout.size() <= prevout.GetN() ||
245 !
wallet.IsMine(it->second.tx->vout[prevout.GetN()])) {
248 ptx = it->second.tx.get();
254std::map<CTxDestination, std::vector<COutput>>
258 std::map<CTxDestination, std::vector<COutput>> result;
259 std::vector<COutput> availableCoins;
263 for (
COutput &coin : availableCoins) {
265 if ((coin.fSpendable ||
272 result[address].emplace_back(std::move(coin));
276 std::vector<COutPoint> lockedCoins;
277 wallet.ListLockedCoins(lockedCoins);
279 const bool include_watch_only =
280 wallet.GetLegacyScriptPubKeyMan() &&
284 for (
const auto &output : lockedCoins) {
285 auto it =
wallet.mapWallet.find(output.GetTxId());
286 if (it !=
wallet.mapWallet.end()) {
287 int depth =
wallet.GetTxDepthInMainChain(it->second);
288 if (depth >= 0 && output.GetN() < it->second.tx->vout.size() &&
289 wallet.IsMine(it->second.tx->vout[output.GetN()]) ==
297 result[address].emplace_back(
298 wallet, it->second, output.GetN(), depth,
309std::vector<OutputGroup>
311 bool separate_coins,
const CFeeRate &effective_feerate,
314 std::vector<OutputGroup> groups_out;
316 if (separate_coins) {
318 for (
const COutput &output : outputs) {
320 if (!output.fSpendable) {
324 CInputCoin input_coin = output.GetInputCoin();
327 OutputGroup group{effective_feerate, long_term_feerate};
328 group.Insert(input_coin, output.nDepth,
333 if (positive_only && group.effective_value <=
Amount::zero()) {
336 if (group.m_outputs.size() > 0 &&
337 group.EligibleForSpending(filter)) {
338 groups_out.push_back(group);
354 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
355 for (
const auto &output : outputs) {
357 if (!output.fSpendable) {
361 CInputCoin input_coin = output.GetInputCoin();
364 std::vector<OutputGroup> &groups = spk_to_groups_map[spk];
366 if (groups.size() == 0) {
368 groups.emplace_back(effective_feerate, long_term_feerate);
383 groups.emplace_back(effective_feerate, long_term_feerate);
384 group = &groups.back();
388 group->
Insert(input_coin, output.nDepth,
394 for (
const auto &spk_and_groups_pair : spk_to_groups_map) {
395 const std::vector<OutputGroup> &groups_per_spk =
396 spk_and_groups_pair.second;
400 for (
auto group_it = groups_per_spk.rbegin();
401 group_it != groups_per_spk.rend(); group_it++) {
406 if (group_it == groups_per_spk.rbegin() &&
417 groups_out.push_back(group);
427 std::vector<COutput> coins,
428 std::set<CInputCoin> &setCoinsRet,
Amount &nValueRet,
450 effective_feerate, long_term_feerate, eligibility_filter,
454 Amount cost_of_change =
wallet.chain().relayDustFee().GetFee(
463 return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet,
464 nValueRet, not_input_fees);
473 return KnapsackSolver(nTargetValue, groups, setCoinsRet, nValueRet);
478 const std::vector<COutput> &vAvailableCoins,
479 const Amount nTargetValue, std::set<CInputCoin> &setCoinsRet,
482 std::vector<COutput>
vCoins(vAvailableCoins);
483 Amount value_to_select = nTargetValue;
492 if (!out.fSpendable) {
496 nValueRet += out.tx->tx->vout[out.i].nValue;
497 setCoinsRet.insert(out.GetInputCoin());
500 return (nValueRet >= nTargetValue);
504 std::set<CInputCoin> setPresetCoins;
507 std::vector<COutPoint> vPresetInputs;
510 for (
const COutPoint &outpoint : vPresetInputs) {
511 std::map<TxId, CWalletTx>::const_iterator it =
512 wallet.mapWallet.find(outpoint.GetTxId());
513 if (it !=
wallet.mapWallet.end()) {
516 if (wtx.
tx->vout.size() <= outpoint.GetN()) {
521 wtx.
tx, outpoint.GetN(),
536 setPresetCoins.insert(coin);
543 for (std::vector<COutput>::iterator it =
vCoins.begin();
545 if (setPresetCoins.count(it->GetInputCoin())) {
566 vCoins, setCoinsRet, nValueRet,
569 vCoins, setCoinsRet, nValueRet,
571 (
wallet.m_spend_zero_conf_change &&
575 (
wallet.m_spend_zero_conf_change &&
579 (
wallet.m_spend_zero_conf_change &&
583 (
wallet.m_spend_zero_conf_change &&
589 (
wallet.m_spend_zero_conf_change &&
609 nValueRet += nValueFromPresetInputs;
615 CWallet &
wallet,
const std::vector<CRecipient> &vecSend,
int change_pos,
624 int nChangePosInOut = change_pos;
629 :
wallet.m_default_change_type,
632 int nChangePosRequest = nChangePosInOut;
633 unsigned int nSubtractFeeFromAmount = 0;
634 for (
const auto &recipient : vecSend) {
636 return util::Error{
_(
"Transaction amounts must not be negative")};
639 nValue += recipient.nAmount;
641 if (recipient.fSubtractFeeFromAmount) {
642 nSubtractFeeFromAmount++;
646 if (vecSend.empty()) {
647 return util::Error{
_(
"Transaction must have at least one recipient")};
653 std::set<CInputCoin> setCoins;
662 std::vector<COutput> vAvailableCoins;
672 CScript scriptChange;
676 if (!std::get_if<CNoDestination>(&coin_control.
destChange)) {
694 error =
_(
"Transaction needs a change address, but we can't "
695 "generate it. Please call keypoolrefill first.");
713 nFeeRateNeeded > *coin_control.
m_feerate) {
715 _(
"Fee rate (%s) is lower than the minimum fee "
716 "rate setting (%s)"),
721 bool pick_new_inputs =
true;
730 nSubtractFeeFromAmount != 0;
733 nChangePosInOut = nChangePosRequest;
738 Amount nValueToSelect = nValue;
739 if (nSubtractFeeFromAmount == 0) {
740 nValueToSelect += nFeeRet;
750 for (
const auto &recipient : vecSend) {
751 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
753 if (recipient.fSubtractFeeFromAmount) {
754 assert(nSubtractFeeFromAmount != 0);
756 txout.
nValue -= nFeeRet / int(nSubtractFeeFromAmount);
762 txout.
nValue -= nFeeRet % int(nSubtractFeeFromAmount);
774 if (recipient.fSubtractFeeFromAmount &&
777 error =
_(
"The transaction amount is too small to "
780 error =
_(
"The transaction amount is too small to "
781 "send after the fee has been deducted");
784 error =
_(
"Transaction amount too small");
790 txNew.
vout.push_back(txout);
794 bool bnb_used =
false;
795 if (pick_new_inputs) {
799 change_prototype_txout, &
wallet);
802 if (change_spend_size == -1) {
807 size_t(change_spend_size);
811 setCoins, nValueIn, coin_control,
826 const Amount nChange = nValueIn - nValueToSelect;
829 CTxOut newTxOut(nChange, scriptChange);
836 nChangePosInOut = -1;
839 if (nChangePosInOut == -1) {
842 txNew.
vout.size() + 1);
843 }
else if ((
unsigned int)nChangePosInOut >
848 std::vector<CTxOut>::iterator position =
849 txNew.
vout.begin() + nChangePosInOut;
850 txNew.
vout.insert(position, newTxOut);
853 nChangePosInOut = -1;
858 for (
const auto &coin : setCoins) {
859 txNew.
vin.push_back(CTxIn(coin.outpoint, CScript()));
862 CTransaction txNewConst(txNew);
871 if (nFeeRet >= nFeeNeeded) {
882 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 &&
886 unsigned int tx_size_with_change =
889 wallet, tx_size_with_change, coin_control);
891 change_prototype_txout,
wallet.chain().relayDustFee());
893 fee_needed_with_change + minimum_value_for_change) {
894 pick_new_inputs =
false;
895 nFeeRet = fee_needed_with_change;
901 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 &&
902 nSubtractFeeFromAmount == 0) {
903 Amount extraFeePaid = nFeeRet - nFeeNeeded;
904 std::vector<CTxOut>::iterator change_position =
905 txNew.
vout.begin() + nChangePosInOut;
906 change_position->nValue += extraFeePaid;
907 nFeeRet -= extraFeePaid;
912 }
else if (!pick_new_inputs) {
918 _(
"Transaction fee and change calculation failed")};
922 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
923 Amount additionalFeeNeeded = nFeeNeeded - nFeeRet;
924 std::vector<CTxOut>::iterator change_position =
925 txNew.
vout.begin() + nChangePosInOut;
928 if (change_position->nValue >=
930 change_position->nValue -= additionalFeeNeeded;
931 nFeeRet += additionalFeeNeeded;
939 if (nSubtractFeeFromAmount > 0) {
940 pick_new_inputs =
false;
944 nFeeRet = nFeeNeeded;
950 if (scriptChange.empty() && nChangePosInOut != -1) {
956 std::vector<CInputCoin> selected_coins(setCoins.begin(),
958 Shuffle(selected_coins.begin(), selected_coins.end(),
963 for (
const auto &coin : selected_coins) {
965 CTxIn(coin.outpoint, CScript(),
966 std::numeric_limits<uint32_t>::max() - 1));
969 if (sign && !
wallet.SignTransaction(txNew)) {
982 if (nFeeRet >
wallet.m_default_max_tx_fee) {
996 int change_pos,
const CCoinControl &coin_control,
bool sign) {
1002 const auto &txr_ungrouped = *res;
1013 change_pos, tmp_cc, sign);
1017 const bool use_aps =
1018 txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee;
1020 "Fee non-grouped = %lld, grouped = %lld, using %s\n",
1021 txr_ungrouped.fee, txr_grouped->fee,
1022 use_aps ?
"grouped" :
"non-grouped");
1034 const std::set<int> &setSubtractFeeFromOutputs,
1036 std::vector<CRecipient> vecSend;
1039 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1042 setSubtractFeeFromOutputs.count(idx) == 1};
1043 vecSend.push_back(recipient);
1048 for (
const CTxIn &txin : tx.
vin) {
1049 coinControl.
Select(txin.prevout);
1062 const auto &txr = *res;
1065 nChangePosInOut = txr.change_pos;
1067 if (nChangePosInOut != -1) {
1068 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut,
1069 tx_new->vout[nChangePosInOut]);
1074 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1075 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1079 for (
const CTxIn &txin : tx_new->vin) {
1081 tx.
vin.push_back(txin);
1084 wallet.LockCoin(txin.prevout);
static constexpr Amount SATOSHI
static constexpr Amount MAX_MONEY
No amount larger than this (in satoshi) is valid.
#define CHECK_NONFATAL(condition)
Identity function.
std::optional< OutputType > m_change_type
Override the default change type if set, ignored if destChange is set.
std::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
bool IsSelected(const COutPoint &output) const
int m_max_depth
Maximum chain depth value for coin availability.
void Select(const COutPoint &output)
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
int m_min_depth
Minimum chain depth value for coin availability.
std::optional< CFeeRate > m_feerate
Override the wallet's m_pay_tx_fee if set.
bool m_add_inputs
If false, only selected inputs are used.
CTxDestination destChange
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
bool m_include_unsafe_inputs
If false, only safe inputs will be used (confirmed or self transfers)
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
void ListSelected(std::vector< COutPoint > &vOutpoints) const
Fee rate in satoshis per kilobyte: Amount / kB.
std::string ToString() const
Amount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::string ToString() const
An output of a transaction.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
A transaction with a bunch of additional info that only the owner cares about.
mapValue_t mapValue
Key/value map with information about the transaction.
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
A wrapper to reserve an address from a wallet.
std::string ToString() const
const int DEFAULT_MAX_DEPTH
const int DEFAULT_MIN_DEPTH
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
static std::vector< COutput > vCoins
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(Amount::zero()), 0, false)
void KeepDestination()
Keep the address.
bool GetReservedDestination(CTxDestination &pubkey, bool internal)
Reserve an address.
isminetype
IsMine() return codes.
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
bilingual_str TransactionErrorString(const TransactionError error)
bilingual_str ErrorString(const Result< T > &result)
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
is a home for public enum and struct type definitions that are used by internally by node code,...
Amount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
static constexpr unsigned int MAX_STANDARD_TX_SIZE
The maximum size for transactions we're willing to relay/mine.
static CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
bool CachedTxIsFromMe(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< TxId > &trusted_parents)
size_t GetSerializeSize(const T &t)
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.
int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *wallet, bool use_max_sig)
Get the marginal bytes of spending the specified output.
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...
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();.
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
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,...
const CTxOut & FindNonChangeParentOutput(const CWallet &wallet, const CTransaction &tx, int output)
Find non-change parent output.
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)
static const size_t OUTPUT_GROUP_MAX_ENTRIES
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...
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.
static util::Result< CreatedTransactionResult > CreateTransactionInternal(CWallet &wallet, const std::vector< CRecipient > &vecSend, int change_pos, const CCoinControl &coin_control, bool sign)
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.
Amount GetAvailableBalance(const CWallet &wallet, const CCoinControl *coinControl)
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...
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
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.
static constexpr Amount zero() noexcept
const bool m_include_partial_groups
Include partial destination groups when avoid_reuse and there are full groups.
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
bool m_avoid_partial_spends
size_t change_output_size
std::vector< CInputCoin > m_outputs
void Insert(const CInputCoin &output, int depth, bool from_me, bool positive_only)
bool EligibleForSpending(const CoinEligibilityFilter &eligibility_filter) const
A TxId is the identifier of a transaction.
bilingual_str _(const char *psz)
Translation function.
Amount GetMinimumFee(const CWallet &wallet, unsigned int nTxBytes, const CCoinControl &coin_control)
Estimate the minimum fee considering user set parameters and the required fee.
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control)
Estimate the minimum fee rate considering user set parameters and the required fee.
static constexpr size_t DUMMY_P2PKH_INPUT_SIZE
Pre-calculated constants for input size estimation.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_AVOID_REUSE