27 unsigned int out,
bool use_max_sig) {
39 txn.
vin.push_back(CTxIn(COutPoint()));
40 if (!
wallet->DummySignInput(txn.
vin[0], txout, use_max_sig)) {
49 const std::vector<CTxOut> &txouts,
52 if (!
wallet->DummySignTx(txNew, txouts, use_max_sig)) {
60 std::vector<CTxOut> txouts;
61 for (
auto &input : tx.vin) {
62 const auto mi =
wallet->mapWallet.find(input.prevout.GetTxId());
64 if (mi ==
wallet->mapWallet.end()) {
67 assert(input.prevout.GetN() < mi->second.tx->vout.size());
68 txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]);
75 const Amount nMinimumAmount,
const Amount nMaximumAmount,
76 const Amount nMinimumSumAmount,
77 const uint64_t nMaximumCount) {
86 bool allow_used_addresses =
89 const int min_depth = {coinControl ? coinControl->
m_min_depth
91 const int max_depth = {coinControl ? coinControl->
m_max_depth
96 std::set<TxId> trusted_parents;
97 for (
const auto &entry :
wallet.mapWallet) {
98 const TxId &wtxid = entry.first;
101 if (
wallet.IsTxImmatureCoinBase(wtx)) {
105 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
135 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
139 if (only_safe && !safeTx) {
143 if (nDepth < min_depth || nDepth > max_depth) {
147 for (uint32_t i = 0; i < wtx.
tx->vout.size(); i++) {
150 !coinControl->
IsSelected(COutPoint(entry.first, i))) {
154 if (wtx.
tx->vout[i].nValue < nMinimumAmount ||
155 wtx.
tx->vout[i].nValue > nMaximumAmount) {
159 const COutPoint outpoint(wtxid, i);
167 if (
wallet.IsLockedCoin(outpoint)) {
171 if (
wallet.IsSpent(outpoint)) {
181 if (!allow_used_addresses &&
wallet.IsSpentKey(wtxid, i)) {
185 std::unique_ptr<SigningProvider> provider =
186 wallet.GetSolvingProvider(wtx.
tx->vout[i].scriptPubKey);
189 provider ?
IsSolvable(*provider, wtx.
tx->vout[i].scriptPubKey)
202 nTotal += wtx.
tx->vout[i].nValue;
204 if (nTotal >= nMinimumSumAmount) {
210 if (nMaximumCount > 0 &&
vCoins.size() >= nMaximumCount) {
222 std::vector<COutput>
vCoins;
225 if (out.fSpendable) {
226 balance += out.tx->tx->vout[out.i].nValue;
233 const CTransaction &tx,
int output) {
235 const CTransaction *ptx = &tx;
238 const COutPoint &prevout = ptx->vin[0].prevout;
239 auto it =
wallet.mapWallet.find(prevout.GetTxId());
240 if (it ==
wallet.mapWallet.end() ||
241 it->second.tx->vout.size() <= prevout.GetN() ||
242 !
wallet.IsMine(it->second.tx->vout[prevout.GetN()])) {
245 ptx = it->second.tx.get();
251std::map<CTxDestination, std::vector<COutput>>
255 std::map<CTxDestination, std::vector<COutput>> result;
256 std::vector<COutput> availableCoins;
260 for (
COutput &coin : availableCoins) {
262 if ((coin.fSpendable ||
269 result[address].emplace_back(std::move(coin));
273 std::vector<COutPoint> lockedCoins;
274 wallet.ListLockedCoins(lockedCoins);
276 const bool include_watch_only =
277 wallet.GetLegacyScriptPubKeyMan() &&
281 for (
const auto &output : lockedCoins) {
282 auto it =
wallet.mapWallet.find(output.GetTxId());
283 if (it !=
wallet.mapWallet.end()) {
284 int depth =
wallet.GetTxDepthInMainChain(it->second);
285 if (depth >= 0 && output.GetN() < it->second.tx->vout.size() &&
286 wallet.IsMine(it->second.tx->vout[output.GetN()]) ==
294 result[address].emplace_back(
295 wallet, it->second, output.GetN(), depth,
306std::vector<OutputGroup>
308 bool separate_coins,
const CFeeRate &effective_feerate,
311 std::vector<OutputGroup> groups_out;
313 if (separate_coins) {
315 for (
const COutput &output : outputs) {
317 if (!output.fSpendable) {
321 CInputCoin input_coin = output.GetInputCoin();
324 OutputGroup group{effective_feerate, long_term_feerate};
325 group.Insert(input_coin, output.nDepth,
330 if (positive_only && group.effective_value <=
Amount::zero()) {
333 if (group.m_outputs.size() > 0 &&
334 group.EligibleForSpending(filter)) {
335 groups_out.push_back(group);
351 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
352 for (
const auto &output : outputs) {
354 if (!output.fSpendable) {
358 CInputCoin input_coin = output.GetInputCoin();
361 std::vector<OutputGroup> &groups = spk_to_groups_map[spk];
363 if (groups.size() == 0) {
365 groups.emplace_back(effective_feerate, long_term_feerate);
380 groups.emplace_back(effective_feerate, long_term_feerate);
381 group = &groups.back();
385 group->
Insert(input_coin, output.nDepth,
391 for (
const auto &spk_and_groups_pair : spk_to_groups_map) {
392 const std::vector<OutputGroup> &groups_per_spk =
393 spk_and_groups_pair.second;
397 for (
auto group_it = groups_per_spk.rbegin();
398 group_it != groups_per_spk.rend(); group_it++) {
403 if (group_it == groups_per_spk.rbegin() &&
414 groups_out.push_back(group);
424 std::vector<COutput> coins,
425 std::set<CInputCoin> &setCoinsRet,
Amount &nValueRet,
447 effective_feerate, long_term_feerate, eligibility_filter,
451 Amount cost_of_change =
wallet.chain().relayDustFee().GetFee(
460 return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet,
461 nValueRet, not_input_fees);
470 return KnapsackSolver(nTargetValue, groups, setCoinsRet, nValueRet);
475 const std::vector<COutput> &vAvailableCoins,
476 const Amount nTargetValue, std::set<CInputCoin> &setCoinsRet,
479 std::vector<COutput>
vCoins(vAvailableCoins);
480 Amount value_to_select = nTargetValue;
489 if (!out.fSpendable) {
493 nValueRet += out.tx->tx->vout[out.i].nValue;
494 setCoinsRet.insert(out.GetInputCoin());
497 return (nValueRet >= nTargetValue);
501 std::set<CInputCoin> setPresetCoins;
504 std::vector<COutPoint> vPresetInputs;
507 for (
const COutPoint &outpoint : vPresetInputs) {
508 std::map<TxId, CWalletTx>::const_iterator it =
509 wallet.mapWallet.find(outpoint.GetTxId());
510 if (it !=
wallet.mapWallet.end()) {
513 if (wtx.
tx->vout.size() <= outpoint.GetN()) {
518 wtx.
tx, outpoint.GetN(),
533 setPresetCoins.insert(coin);
540 for (std::vector<COutput>::iterator it =
vCoins.begin();
542 if (setPresetCoins.count(it->GetInputCoin())) {
563 vCoins, setCoinsRet, nValueRet,
566 vCoins, setCoinsRet, nValueRet,
568 (
wallet.m_spend_zero_conf_change &&
572 (
wallet.m_spend_zero_conf_change &&
576 (
wallet.m_spend_zero_conf_change &&
580 (
wallet.m_spend_zero_conf_change &&
586 (
wallet.m_spend_zero_conf_change &&
606 nValueRet += nValueFromPresetInputs;
622 :
wallet.m_default_change_type,
625 int nChangePosRequest = nChangePosInOut;
626 unsigned int nSubtractFeeFromAmount = 0;
627 for (
const auto &recipient : vecSend) {
629 error =
_(
"Transaction amounts must not be negative");
633 nValue += recipient.nAmount;
635 if (recipient.fSubtractFeeFromAmount) {
636 nSubtractFeeFromAmount++;
640 if (vecSend.empty()) {
641 error =
_(
"Transaction must have at least one recipient");
648 std::set<CInputCoin> setCoins;
657 std::vector<COutput> vAvailableCoins;
667 CScript scriptChange;
670 if (!std::get_if<CNoDestination>(&coin_control.
destChange)) {
688 error =
_(
"Transaction needs a change address, but we can't "
689 "generate it. Please call keypoolrefill first.");
707 nFeeRateNeeded > *coin_control.
m_feerate) {
709 "rate setting (%s)"),
716 bool pick_new_inputs =
true;
725 nSubtractFeeFromAmount != 0;
728 nChangePosInOut = nChangePosRequest;
733 Amount nValueToSelect = nValue;
734 if (nSubtractFeeFromAmount == 0) {
735 nValueToSelect += nFeeRet;
745 for (
const auto &recipient : vecSend) {
746 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
748 if (recipient.fSubtractFeeFromAmount) {
749 assert(nSubtractFeeFromAmount != 0);
751 txout.
nValue -= nFeeRet / int(nSubtractFeeFromAmount);
757 txout.
nValue -= nFeeRet % int(nSubtractFeeFromAmount);
769 if (recipient.fSubtractFeeFromAmount &&
772 error =
_(
"The transaction amount is too small to "
775 error =
_(
"The transaction amount is too small to "
776 "send after the fee has been deducted");
779 error =
_(
"Transaction amount too small");
785 txNew.
vout.push_back(txout);
789 bool bnb_used =
false;
790 if (pick_new_inputs) {
794 change_prototype_txout, &
wallet);
797 if (change_spend_size == -1) {
802 size_t(change_spend_size);
806 setCoins, nValueIn, coin_control,
814 error =
_(
"Insufficient funds");
822 const Amount nChange = nValueIn - nValueToSelect;
825 CTxOut newTxOut(nChange, scriptChange);
832 nChangePosInOut = -1;
835 if (nChangePosInOut == -1) {
837 nChangePosInOut = GetRand<int>(txNew.
vout.size() + 1);
838 }
else if ((
unsigned int)nChangePosInOut >
840 error =
_(
"Change index out of range");
844 std::vector<CTxOut>::iterator position =
845 txNew.
vout.begin() + nChangePosInOut;
846 txNew.
vout.insert(position, newTxOut);
849 nChangePosInOut = -1;
854 for (
const auto &coin : setCoins) {
855 txNew.
vin.push_back(CTxIn(coin.outpoint, CScript()));
858 CTransaction txNewConst(txNew);
862 error =
_(
"Signing transaction failed");
868 if (nFeeRet >= nFeeNeeded) {
879 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 &&
883 unsigned int tx_size_with_change =
886 wallet, tx_size_with_change, coin_control);
888 change_prototype_txout,
wallet.chain().relayDustFee());
890 fee_needed_with_change + minimum_value_for_change) {
891 pick_new_inputs =
false;
892 nFeeRet = fee_needed_with_change;
898 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 &&
899 nSubtractFeeFromAmount == 0) {
900 Amount extraFeePaid = nFeeRet - nFeeNeeded;
901 std::vector<CTxOut>::iterator change_position =
902 txNew.
vout.begin() + nChangePosInOut;
903 change_position->nValue += extraFeePaid;
904 nFeeRet -= extraFeePaid;
909 }
else if (!pick_new_inputs) {
914 error =
_(
"Transaction fee and change calculation failed");
919 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
920 Amount additionalFeeNeeded = nFeeNeeded - nFeeRet;
921 std::vector<CTxOut>::iterator change_position =
922 txNew.
vout.begin() + nChangePosInOut;
925 if (change_position->nValue >=
927 change_position->nValue -= additionalFeeNeeded;
928 nFeeRet += additionalFeeNeeded;
936 if (nSubtractFeeFromAmount > 0) {
937 pick_new_inputs =
false;
941 nFeeRet = nFeeNeeded;
947 if (scriptChange.empty() && nChangePosInOut != -1) {
953 std::vector<CInputCoin> selected_coins(setCoins.begin(),
955 Shuffle(selected_coins.begin(), selected_coins.end(),
960 for (
const auto &coin : selected_coins) {
962 CTxIn(coin.outpoint, CScript(),
963 std::numeric_limits<uint32_t>::max() - 1));
966 if (sign && !
wallet.SignTransaction(txNew)) {
967 error =
_(
"Signing transaction failed");
976 error =
_(
"Transaction too large");
981 if (nFeeRet >
wallet.m_default_max_tx_fee) {
997 int nChangePosIn = nChangePosInOut;
1001 error, coin_control, sign);
1011 int nChangePosInOut2 = nChangePosIn;
1015 nChangePosInOut2, error2, tmp_cc, sign)) {
1018 const bool use_aps = nFeeRet2 <= nFeeRet +
wallet.m_max_aps_fee;
1020 "Fee non-grouped = %lld, grouped = %lld, using %s\n", nFeeRet,
1021 nFeeRet2, use_aps ?
"grouped" :
"non-grouped");
1025 nChangePosInOut = nChangePosInOut2;
1035 const std::set<int> &setSubtractFeeFromOutputs,
1037 std::vector<CRecipient> vecSend;
1040 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1043 setSubtractFeeFromOutputs.count(idx) == 1};
1044 vecSend.push_back(recipient);
1049 for (
const CTxIn &txin : tx.
vin) {
1050 coinControl.
Select(txin.prevout);
1059 error, coinControl,
false)) {
1063 if (nChangePosInOut != -1) {
1064 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut,
1065 tx_new->vout[nChangePosInOut]);
1070 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1071 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1075 for (
const CTxIn &txin : tx_new->vin) {
1077 tx.
vin.push_back(txin);
1080 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.
A wrapper to reserve an address from a wallet.
std::string ToString() const
Helper for findBlock to selectively return pieces of block data.
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)
bilingual_str TransactionErrorString(const TransactionError error)
void KeepDestination()
Keep the address.
bool GetReservedDestination(CTxDestination &pubkey, bool internal)
Reserve an address.
isminetype
IsMine() return codes.
bool error(const char *fmt, const Args &...args)
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
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, int nVersion=0)
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.
bool CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, CTransactionRef &tx, Amount &nFeeRet, int &nChangePosInOut, bilingual_str &error, const CCoinControl &coin_control, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
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 bool CreateTransactionInternal(CWallet &wallet, const std::vector< CRecipient > &vecSend, CTransactionRef &tx, Amount &nFeeRet, int &nChangePosInOut, bilingual_str &error, const CCoinControl &coin_control, bool sign)
static const size_t OUTPUT_GROUP_MAX_ENTRIES
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.
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.
static const int PROTOCOL_VERSION
network protocol versioning
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