25 unsigned int out,
bool use_max_sig) {
37 txn.
vin.push_back(CTxIn(COutPoint()));
38 if (!
wallet->DummySignInput(txn.
vin[0], txout, use_max_sig)) {
47 const std::vector<CTxOut> &txouts,
50 if (!
wallet->DummySignTx(txNew, txouts, use_max_sig)) {
58 std::vector<CTxOut> txouts;
59 for (
auto &input : tx.vin) {
60 const auto mi =
wallet->mapWallet.find(input.prevout.GetTxId());
62 if (mi ==
wallet->mapWallet.end()) {
65 assert(input.prevout.GetN() < mi->second.tx->vout.size());
66 txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]);
73 const Amount nMinimumAmount,
const Amount nMaximumAmount,
74 const Amount nMinimumSumAmount,
75 const uint64_t nMaximumCount) {
84 bool allow_used_addresses =
87 const int min_depth = {coinControl ? coinControl->
m_min_depth
89 const int max_depth = {coinControl ? coinControl->
m_max_depth
94 std::set<TxId> trusted_parents;
95 for (
const auto &entry :
wallet.mapWallet) {
96 const TxId &wtxid = entry.first;
99 if (
wallet.IsTxImmatureCoinBase(wtx)) {
103 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
133 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
137 if (only_safe && !safeTx) {
141 if (nDepth < min_depth || nDepth > max_depth) {
145 for (uint32_t i = 0; i < wtx.
tx->vout.size(); i++) {
148 !coinControl->
IsSelected(COutPoint(entry.first, i))) {
152 if (wtx.
tx->vout[i].nValue < nMinimumAmount ||
153 wtx.
tx->vout[i].nValue > nMaximumAmount) {
157 const COutPoint outpoint(wtxid, i);
165 if (
wallet.IsLockedCoin(outpoint)) {
169 if (
wallet.IsSpent(outpoint)) {
179 if (!allow_used_addresses &&
wallet.IsSpentKey(wtxid, i)) {
183 std::unique_ptr<SigningProvider> provider =
184 wallet.GetSolvingProvider(wtx.
tx->vout[i].scriptPubKey);
187 provider ?
IsSolvable(*provider, wtx.
tx->vout[i].scriptPubKey)
200 nTotal += wtx.
tx->vout[i].nValue;
202 if (nTotal >= nMinimumSumAmount) {
208 if (nMaximumCount > 0 &&
vCoins.size() >= nMaximumCount) {
220 std::vector<COutput>
vCoins;
223 if (out.fSpendable) {
224 balance += out.tx->tx->vout[out.i].nValue;
231 const CTransaction &tx,
int output) {
233 const CTransaction *ptx = &tx;
236 const COutPoint &prevout = ptx->vin[0].prevout;
237 auto it =
wallet.mapWallet.find(prevout.GetTxId());
238 if (it ==
wallet.mapWallet.end() ||
239 it->second.tx->vout.size() <= prevout.GetN() ||
240 !
wallet.IsMine(it->second.tx->vout[prevout.GetN()])) {
243 ptx = it->second.tx.get();
249std::map<CTxDestination, std::vector<COutput>>
253 std::map<CTxDestination, std::vector<COutput>> result;
254 std::vector<COutput> availableCoins;
258 for (
COutput &coin : availableCoins) {
260 if ((coin.fSpendable ||
267 result[address].emplace_back(std::move(coin));
271 std::vector<COutPoint> lockedCoins;
272 wallet.ListLockedCoins(lockedCoins);
274 const bool include_watch_only =
275 wallet.GetLegacyScriptPubKeyMan() &&
279 for (
const auto &output : lockedCoins) {
280 auto it =
wallet.mapWallet.find(output.GetTxId());
281 if (it !=
wallet.mapWallet.end()) {
282 int depth =
wallet.GetTxDepthInMainChain(it->second);
283 if (depth >= 0 && output.GetN() < it->second.tx->vout.size() &&
284 wallet.IsMine(it->second.tx->vout[output.GetN()]) ==
292 result[address].emplace_back(
293 wallet, it->second, output.GetN(), depth,
304std::vector<OutputGroup>
306 bool separate_coins,
const CFeeRate &effective_feerate,
309 std::vector<OutputGroup> groups_out;
311 if (separate_coins) {
313 for (
const COutput &output : outputs) {
315 if (!output.fSpendable) {
319 CInputCoin input_coin = output.GetInputCoin();
322 OutputGroup group{effective_feerate, long_term_feerate};
323 group.Insert(input_coin, output.nDepth,
328 if (positive_only && group.effective_value <=
Amount::zero()) {
331 if (group.m_outputs.size() > 0 &&
332 group.EligibleForSpending(filter)) {
333 groups_out.push_back(group);
349 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
350 for (
const auto &output : outputs) {
352 if (!output.fSpendable) {
356 CInputCoin input_coin = output.GetInputCoin();
359 std::vector<OutputGroup> &groups = spk_to_groups_map[spk];
361 if (groups.size() == 0) {
363 groups.emplace_back(effective_feerate, long_term_feerate);
378 groups.emplace_back(effective_feerate, long_term_feerate);
379 group = &groups.back();
383 group->
Insert(input_coin, output.nDepth,
389 for (
const auto &spk_and_groups_pair : spk_to_groups_map) {
390 const std::vector<OutputGroup> &groups_per_spk =
391 spk_and_groups_pair.second;
395 for (
auto group_it = groups_per_spk.rbegin();
396 group_it != groups_per_spk.rend(); group_it++) {
401 if (group_it == groups_per_spk.rbegin() &&
412 groups_out.push_back(group);
422 std::vector<COutput> coins,
423 std::set<CInputCoin> &setCoinsRet,
Amount &nValueRet,
445 effective_feerate, long_term_feerate, eligibility_filter,
449 Amount cost_of_change =
wallet.chain().relayDustFee().GetFee(
458 return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet,
459 nValueRet, not_input_fees);
468 return KnapsackSolver(nTargetValue, groups, setCoinsRet, nValueRet);
473 const std::vector<COutput> &vAvailableCoins,
474 const Amount nTargetValue, std::set<CInputCoin> &setCoinsRet,
477 std::vector<COutput>
vCoins(vAvailableCoins);
478 Amount value_to_select = nTargetValue;
487 if (!out.fSpendable) {
491 nValueRet += out.tx->tx->vout[out.i].nValue;
492 setCoinsRet.insert(out.GetInputCoin());
495 return (nValueRet >= nTargetValue);
499 std::set<CInputCoin> setPresetCoins;
502 std::vector<COutPoint> vPresetInputs;
505 for (
const COutPoint &outpoint : vPresetInputs) {
506 std::map<TxId, CWalletTx>::const_iterator it =
507 wallet.mapWallet.find(outpoint.GetTxId());
508 if (it !=
wallet.mapWallet.end()) {
511 if (wtx.
tx->vout.size() <= outpoint.GetN()) {
516 wtx.
tx, outpoint.GetN(),
531 setPresetCoins.insert(coin);
538 for (std::vector<COutput>::iterator it =
vCoins.begin();
540 if (setPresetCoins.count(it->GetInputCoin())) {
561 vCoins, setCoinsRet, nValueRet,
564 vCoins, setCoinsRet, nValueRet,
566 (
wallet.m_spend_zero_conf_change &&
570 (
wallet.m_spend_zero_conf_change &&
574 (
wallet.m_spend_zero_conf_change &&
578 (
wallet.m_spend_zero_conf_change &&
584 (
wallet.m_spend_zero_conf_change &&
604 nValueRet += nValueFromPresetInputs;
610 CWallet &
wallet,
const std::vector<CRecipient> &vecSend,
int change_pos,
619 int nChangePosInOut = change_pos;
624 :
wallet.m_default_change_type,
627 int nChangePosRequest = nChangePosInOut;
628 unsigned int nSubtractFeeFromAmount = 0;
629 for (
const auto &recipient : vecSend) {
631 return util::Error{
_(
"Transaction amounts must not be negative")};
634 nValue += recipient.nAmount;
636 if (recipient.fSubtractFeeFromAmount) {
637 nSubtractFeeFromAmount++;
641 if (vecSend.empty()) {
642 return util::Error{
_(
"Transaction must have at least one recipient")};
648 std::set<CInputCoin> setCoins;
657 std::vector<COutput> vAvailableCoins;
667 CScript scriptChange;
671 if (!std::get_if<CNoDestination>(&coin_control.
destChange)) {
689 error =
_(
"Transaction needs a change address, but we can't "
690 "generate it. Please call keypoolrefill first.");
708 nFeeRateNeeded > *coin_control.
m_feerate) {
710 _(
"Fee rate (%s) is lower than the minimum fee "
711 "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,
821 const Amount nChange = nValueIn - nValueToSelect;
824 CTxOut newTxOut(nChange, scriptChange);
831 nChangePosInOut = -1;
834 if (nChangePosInOut == -1) {
836 nChangePosInOut = GetRand<int>(txNew.
vout.size() + 1);
837 }
else if ((
unsigned int)nChangePosInOut >
842 std::vector<CTxOut>::iterator position =
843 txNew.
vout.begin() + nChangePosInOut;
844 txNew.
vout.insert(position, newTxOut);
847 nChangePosInOut = -1;
852 for (
const auto &coin : setCoins) {
853 txNew.
vin.push_back(CTxIn(coin.outpoint, CScript()));
856 CTransaction txNewConst(txNew);
865 if (nFeeRet >= nFeeNeeded) {
876 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 &&
880 unsigned int tx_size_with_change =
883 wallet, tx_size_with_change, coin_control);
885 change_prototype_txout,
wallet.chain().relayDustFee());
887 fee_needed_with_change + minimum_value_for_change) {
888 pick_new_inputs =
false;
889 nFeeRet = fee_needed_with_change;
895 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 &&
896 nSubtractFeeFromAmount == 0) {
897 Amount extraFeePaid = nFeeRet - nFeeNeeded;
898 std::vector<CTxOut>::iterator change_position =
899 txNew.
vout.begin() + nChangePosInOut;
900 change_position->nValue += extraFeePaid;
901 nFeeRet -= extraFeePaid;
906 }
else if (!pick_new_inputs) {
912 _(
"Transaction fee and change calculation failed")};
916 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
917 Amount additionalFeeNeeded = nFeeNeeded - nFeeRet;
918 std::vector<CTxOut>::iterator change_position =
919 txNew.
vout.begin() + nChangePosInOut;
922 if (change_position->nValue >=
924 change_position->nValue -= additionalFeeNeeded;
925 nFeeRet += additionalFeeNeeded;
933 if (nSubtractFeeFromAmount > 0) {
934 pick_new_inputs =
false;
938 nFeeRet = nFeeNeeded;
944 if (scriptChange.empty() && nChangePosInOut != -1) {
950 std::vector<CInputCoin> selected_coins(setCoins.begin(),
952 Shuffle(selected_coins.begin(), selected_coins.end(),
957 for (
const auto &coin : selected_coins) {
959 CTxIn(coin.outpoint, CScript(),
960 std::numeric_limits<uint32_t>::max() - 1));
963 if (sign && !
wallet.SignTransaction(txNew)) {
976 if (nFeeRet >
wallet.m_default_max_tx_fee) {
990 int change_pos,
const CCoinControl &coin_control,
bool sign) {
996 const auto &txr_ungrouped = *res;
1007 change_pos, tmp_cc, sign);
1011 const bool use_aps =
1012 txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee;
1014 "Fee non-grouped = %lld, grouped = %lld, using %s\n",
1015 txr_ungrouped.fee, txr_grouped->fee,
1016 use_aps ?
"grouped" :
"non-grouped");
1028 const std::set<int> &setSubtractFeeFromOutputs,
1030 std::vector<CRecipient> vecSend;
1033 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1036 setSubtractFeeFromOutputs.count(idx) == 1};
1037 vecSend.push_back(recipient);
1042 for (
const CTxIn &txin : tx.
vin) {
1043 coinControl.
Select(txin.prevout);
1056 const auto &txr = *res;
1059 nChangePosInOut = txr.change_pos;
1061 if (nChangePosInOut != -1) {
1062 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut,
1063 tx_new->vout[nChangePosInOut]);
1068 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1069 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1073 for (
const CTxIn &txin : tx_new->vin) {
1075 tx.
vin.push_back(txin);
1078 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
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.
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 ErrorString(const Result< T > &result)
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.
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.
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