31 unsigned int out,
bool use_max_sig) {
43 txn.
vin.push_back(CTxIn(COutPoint()));
44 if (!
wallet->DummySignInput(txn.
vin[0], txout, use_max_sig)) {
53 const std::vector<CTxOut> &txouts,
56 if (!
wallet->DummySignTx(txNew, txouts, use_max_sig)) {
64 std::vector<CTxOut> txouts;
65 for (
auto &input : tx.vin) {
66 const auto mi =
wallet->mapWallet.find(input.prevout.GetTxId());
68 if (mi ==
wallet->mapWallet.end()) {
71 assert(input.prevout.GetN() < mi->second.tx->vout.size());
72 txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]);
79 const Amount nMinimumAmount,
const Amount nMaximumAmount,
80 const Amount nMinimumSumAmount,
81 const uint64_t nMaximumCount) {
90 bool allow_used_addresses =
93 const int min_depth = {coinControl ? coinControl->
m_min_depth
95 const int max_depth = {coinControl ? coinControl->
m_max_depth
100 std::set<TxId> trusted_parents;
101 for (
const auto &entry :
wallet.mapWallet) {
102 const TxId &wtxid = entry.first;
105 if (
wallet.IsTxImmatureCoinBase(wtx)) {
109 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
139 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
143 if (only_safe && !safeTx) {
147 if (nDepth < min_depth || nDepth > max_depth) {
151 for (uint32_t i = 0; i < wtx.
tx->vout.size(); i++) {
154 !coinControl->
IsSelected(COutPoint(entry.first, i))) {
158 if (wtx.
tx->vout[i].nValue < nMinimumAmount ||
159 wtx.
tx->vout[i].nValue > nMaximumAmount) {
163 const COutPoint outpoint(wtxid, i);
171 if (
wallet.IsLockedCoin(outpoint)) {
175 if (
wallet.IsSpent(outpoint)) {
185 if (!allow_used_addresses &&
wallet.IsSpentKey(wtxid, i)) {
189 std::unique_ptr<SigningProvider> provider =
190 wallet.GetSolvingProvider(wtx.
tx->vout[i].scriptPubKey);
193 provider ?
IsSolvable(*provider, wtx.
tx->vout[i].scriptPubKey)
206 nTotal += wtx.
tx->vout[i].nValue;
208 if (nTotal >= nMinimumSumAmount) {
214 if (nMaximumCount > 0 &&
vCoins.size() >= nMaximumCount) {
226 std::vector<COutput>
vCoins;
229 if (
out.fSpendable) {
237 const CTransaction &tx,
int output) {
239 const CTransaction *ptx = &tx;
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()])) {
249 ptx = it->second.tx.get();
255std::map<CTxDestination, std::vector<COutput>>
259 std::map<CTxDestination, std::vector<COutput>> result;
260 std::vector<COutput> availableCoins;
264 for (
COutput &coin : availableCoins) {
266 if ((coin.fSpendable ||
273 result[address].emplace_back(std::move(coin));
277 std::vector<COutPoint> lockedCoins;
278 wallet.ListLockedCoins(lockedCoins);
280 const bool include_watch_only =
281 wallet.GetLegacyScriptPubKeyMan() &&
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()]) ==
298 result[address].emplace_back(
299 wallet, it->second, output.GetN(), depth,
310std::vector<OutputGroup>
312 bool separate_coins,
const CFeeRate &effective_feerate,
315 std::vector<OutputGroup> groups_out;
317 if (separate_coins) {
319 for (
const COutput &output : outputs) {
321 if (!output.fSpendable) {
325 CInputCoin input_coin = output.GetInputCoin();
329 group.Insert(input_coin, output.nDepth,
337 if (
group.m_outputs.size() > 0 &&
338 group.EligibleForSpending(filter)) {
339 groups_out.push_back(
group);
355 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
356 for (
const auto &output : outputs) {
358 if (!output.fSpendable) {
362 CInputCoin input_coin = output.GetInputCoin();
365 std::vector<OutputGroup> &groups = spk_to_groups_map[spk];
367 if (groups.size() == 0) {
369 groups.emplace_back(effective_feerate, long_term_feerate);
384 groups.emplace_back(effective_feerate, long_term_feerate);
385 group = &groups.back();
389 group->Insert(input_coin, output.nDepth,
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;
401 for (
auto group_it = groups_per_spk.rbegin();
402 group_it != groups_per_spk.rend(); group_it++) {
407 if (group_it == groups_per_spk.rbegin() &&
416 if (
group.m_outputs.size() > 0 &&
417 group.EligibleForSpending(filter)) {
418 groups_out.push_back(
group);
428 std::vector<COutput> coins,
429 std::set<CInputCoin> &setCoinsRet,
Amount &nValueRet,
451 effective_feerate, long_term_feerate, eligibility_filter,
455 Amount cost_of_change =
wallet.chain().relayDustFee().GetFee(
464 return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet,
465 nValueRet, not_input_fees);
474 return KnapsackSolver(nTargetValue, groups, setCoinsRet, nValueRet);
479 const std::vector<COutput> &vAvailableCoins,
480 const Amount nTargetValue, std::set<CInputCoin> &setCoinsRet,
483 std::vector<COutput>
vCoins(vAvailableCoins);
484 Amount value_to_select = nTargetValue;
493 if (!
out.fSpendable) {
497 nValueRet +=
out.tx->tx->vout[
out.i].nValue;
498 setCoinsRet.insert(
out.GetInputCoin());
501 return (nValueRet >= nTargetValue);
505 std::set<CInputCoin> setPresetCoins;
508 std::vector<COutPoint> vPresetInputs;
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()) {
517 if (wtx.
tx->vout.size() <= outpoint.GetN()) {
522 wtx.
tx, outpoint.GetN(),
537 setPresetCoins.insert(coin);
544 for (std::vector<COutput>::iterator it =
vCoins.begin();
546 if (setPresetCoins.count(it->GetInputCoin())) {
567 vCoins, setCoinsRet, nValueRet,
570 vCoins, setCoinsRet, nValueRet,
572 (
wallet.m_spend_zero_conf_change &&
576 (
wallet.m_spend_zero_conf_change &&
580 (
wallet.m_spend_zero_conf_change &&
584 (
wallet.m_spend_zero_conf_change &&
590 (
wallet.m_spend_zero_conf_change &&
610 nValueRet += nValueFromPresetInputs;
616 CWallet &
wallet,
const std::vector<CRecipient> &vecSend,
int change_pos,
625 int nChangePosInOut = change_pos;
630 :
wallet.m_default_change_type,
633 int nChangePosRequest = nChangePosInOut;
634 unsigned int nSubtractFeeFromAmount = 0;
635 for (
const auto &recipient : vecSend) {
637 return util::Error{
_(
"Transaction amounts must not be negative")};
640 nValue += recipient.nAmount;
642 if (recipient.fSubtractFeeFromAmount) {
643 nSubtractFeeFromAmount++;
647 if (vecSend.empty()) {
648 return util::Error{
_(
"Transaction must have at least one recipient")};
654 std::set<CInputCoin> setCoins;
663 std::vector<COutput> vAvailableCoins;
673 CScript scriptChange;
677 if (!std::get_if<CNoDestination>(&coin_control.
destChange)) {
695 error =
_(
"Transaction needs a change address, but we can't "
696 "generate it. Please call keypoolrefill first.");
714 nFeeRateNeeded > *coin_control.
m_feerate) {
716 _(
"Fee rate (%s) is lower than the minimum fee "
717 "rate setting (%s)"),
722 bool pick_new_inputs =
true;
731 nSubtractFeeFromAmount != 0;
734 nChangePosInOut = nChangePosRequest;
739 Amount nValueToSelect = nValue;
740 if (nSubtractFeeFromAmount == 0) {
741 nValueToSelect += nFeeRet;
751 for (
const auto &recipient : vecSend) {
752 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
754 if (recipient.fSubtractFeeFromAmount) {
755 assert(nSubtractFeeFromAmount != 0);
757 txout.
nValue -= nFeeRet / int(nSubtractFeeFromAmount);
763 txout.
nValue -= nFeeRet % int(nSubtractFeeFromAmount);
775 if (recipient.fSubtractFeeFromAmount &&
778 error =
_(
"The transaction amount is too small to "
781 error =
_(
"The transaction amount is too small to "
782 "send after the fee has been deducted");
785 error =
_(
"Transaction amount too small");
791 txNew.
vout.push_back(txout);
795 bool bnb_used =
false;
796 if (pick_new_inputs) {
800 change_prototype_txout, &
wallet);
803 if (change_spend_size == -1) {
808 size_t(change_spend_size);
812 setCoins, nValueIn, coin_control,
827 const Amount nChange = nValueIn - nValueToSelect;
830 CTxOut newTxOut(nChange, scriptChange);
837 nChangePosInOut = -1;
840 if (nChangePosInOut == -1) {
843 txNew.
vout.size() + 1);
844 }
else if ((
unsigned int)nChangePosInOut >
849 std::vector<CTxOut>::iterator position =
850 txNew.
vout.begin() + nChangePosInOut;
851 txNew.
vout.insert(position, newTxOut);
854 nChangePosInOut = -1;
859 for (
const auto &coin : setCoins) {
860 txNew.
vin.push_back(CTxIn(coin.outpoint, CScript()));
863 CTransaction txNewConst(txNew);
872 if (nFeeRet >= nFeeNeeded) {
883 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 &&
887 unsigned int tx_size_with_change =
890 wallet, tx_size_with_change, coin_control);
892 change_prototype_txout,
wallet.chain().relayDustFee());
894 fee_needed_with_change + minimum_value_for_change) {
895 pick_new_inputs =
false;
896 nFeeRet = fee_needed_with_change;
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;
913 }
else if (!pick_new_inputs) {
919 _(
"Transaction fee and change calculation failed")};
923 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
924 Amount additionalFeeNeeded = nFeeNeeded - nFeeRet;
925 std::vector<CTxOut>::iterator change_position =
926 txNew.
vout.begin() + nChangePosInOut;
929 if (change_position->nValue >=
931 change_position->nValue -= additionalFeeNeeded;
932 nFeeRet += additionalFeeNeeded;
940 if (nSubtractFeeFromAmount > 0) {
941 pick_new_inputs =
false;
945 nFeeRet = nFeeNeeded;
951 if (scriptChange.empty() && nChangePosInOut != -1) {
957 std::vector<CInputCoin> selected_coins(setCoins.begin(),
959 Shuffle(selected_coins.begin(), selected_coins.end(),
964 for (
const auto &coin : selected_coins) {
966 CTxIn(coin.outpoint, CScript(),
967 std::numeric_limits<uint32_t>::max() - 1));
970 if (sign && !
wallet.SignTransaction(txNew)) {
983 if (nFeeRet >
wallet.m_default_max_tx_fee) {
997 int change_pos,
const CCoinControl &coin_control,
bool sign) {
1003 const auto &txr_ungrouped = *res;
1014 change_pos, tmp_cc, sign);
1018 const bool use_aps =
1019 txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee;
1021 "Fee non-grouped = %lld, grouped = %lld, using %s\n",
1022 txr_ungrouped.fee, txr_grouped->fee,
1023 use_aps ?
"grouped" :
"non-grouped");
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);
1063 const auto &txr = *res;
1066 nChangePosInOut = txr.change_pos;
1068 if (nChangePosInOut != -1) {
1069 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut,
1070 tx_new->vout[nChangePosInOut]);
1075 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1076 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1080 for (
const CTxIn &txin : tx_new->vin) {
1082 tx.
vin.push_back(txin);
1085 wallet.LockCoin(txin.prevout);
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 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 virtualbyte: Amount / vB the feerate is represented internally as FeeFrac.
Amount GetFee(int32_t virtual_bytes) const
Return the fee in satoshis for the given size in bytes.
std::string ToString() const
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...
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
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