42 const std::unique_ptr<SigningProvider> provider =
wallet->GetSolvingProvider(txout.
scriptPubKey);
50 if (!
wallet->DummySignTx(txNew, txouts, coin_control)) {
56 return TxSize{vsize, weight};
61 std::vector<CTxOut> txouts;
66 if (mi !=
wallet->mapWallet.end()) {
68 txouts.emplace_back(mi->second.tx->vout.at(input.
prevout.
n));
69 }
else if (coin_control) {
74 txouts.emplace_back(txout);
85 for (
const auto& it :
coins) {
86 size += it.second.size();
93 std::vector<COutput> all;
94 all.reserve(
coins.size());
95 for (
const auto& it :
coins) {
96 all.insert(all.end(), it.second.begin(), it.second.end());
107 for (
auto& [type, vec] :
coins) {
108 auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](
const COutput& coin) {
109 return coins_to_remove.count(coin.outpoint) == 1;
111 vec.erase(remove_it, vec.end());
117 for (
auto& it :
coins) {
118 ::Shuffle(it.second.begin(), it.second.end(), rng_fast);
124 coins[type].emplace_back(out);
146 std::optional<CFeeRate> feerate,
149 const CAmount& nMinimumSumAmount,
150 const uint64_t nMaximumCount,
163 std::set<uint256> trusted_parents;
164 for (
const auto& entry :
wallet.mapWallet)
166 const uint256& wtxid = entry.first;
169 if (
wallet.IsTxImmatureCoinBase(wtx))
172 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
198 if (nDepth == 0 && wtx.
mapValue.count(
"replaces_txid")) {
210 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
214 if (only_safe && !safeTx) {
218 if (nDepth < min_depth || nDepth > max_depth) {
224 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
225 const CTxOut& output = wtx.
tx->vout[i];
228 if (output.
nValue < nMinimumAmount || output.
nValue > nMaximumAmount)
234 if (
wallet.IsLockedCoin(outpoint))
237 if (
wallet.IsSpent(outpoint))
250 std::unique_ptr<SigningProvider> provider =
wallet.GetSolvingProvider(output.
scriptPubKey);
255 bool solvable = input_bytes > -1;
259 if (!spendable && only_spendable)
continue;
266 bool is_from_p2sh{
false};
272 if (!provider->GetCScript(hash, script))
279 COutput coin(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.
GetTxTime(), tx_from_me, feerate);
283 std::vector<std::vector<uint8_t>> return_values_unused;
285 type =
Solver(script, return_values_unused);
298 if (nMaximumCount > 0 && result.
Size() >= nMaximumCount) {
309 return AvailableCoins(
wallet, coinControl, std::nullopt, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount,
false);
331 auto it =
wallet.mapWallet.find(prevout.
hash);
332 if (it ==
wallet.mapWallet.end() || it->second.tx->vout.size() <= prevout.
n ||
333 !
wallet.IsMine(it->second.tx->vout[prevout.
n])) {
336 ptx = it->second.tx.get();
352 std::map<CTxDestination, std::vector<COutput>> result;
358 result[address].emplace_back(std::move(coin));
362 std::vector<COutPoint> lockedCoins;
363 wallet.ListLockedCoins(lockedCoins);
367 for (
const COutPoint& output : lockedCoins) {
368 auto it =
wallet.mapWallet.find(output.hash);
369 if (it !=
wallet.mapWallet.end()) {
370 const auto& wtx = it->second;
371 int depth =
wallet.GetTxDepthInMainChain(wtx);
372 if (depth >= 0 && output.n < wtx.tx->vout.size() &&
373 wallet.IsMine(wtx.tx->vout[output.n]) == is_mine_filter
377 const auto out = wtx.tx->vout.at(output.n);
378 result[address].emplace_back(
379 COutPoint(wtx.GetHash(), output.n), out, depth,
CalculateMaximumSignedInputSize(out, &
wallet,
nullptr),
true,
true,
false, wtx.GetTxTime(),
CachedTxIsFromMe(
wallet, wtx,
ISMINE_ALL));
390 std::vector<OutputGroup> groups_out;
394 for (
const COutput& output : outputs) {
396 if (!output.spendable)
continue;
398 size_t ancestors, descendants;
399 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
403 group.Insert(output, ancestors, descendants, positive_only);
406 if (positive_only && group.GetSelectionAmount() <= 0)
continue;
407 if (group.m_outputs.size() > 0 && group.EligibleForSpending(filter)) groups_out.push_back(group);
418 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
419 for (
const auto& output : outputs) {
421 if (!output.spendable)
continue;
423 size_t ancestors, descendants;
424 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
425 CScript spk = output.txout.scriptPubKey;
427 std::vector<OutputGroup>& groups = spk_to_groups_map[spk];
429 if (groups.size() == 0) {
442 groups.emplace_back(coin_sel_params);
443 group = &groups.back();
447 group->
Insert(output, ancestors, descendants, positive_only);
451 for (
const auto& spk_and_groups_pair: spk_to_groups_map) {
452 const std::vector<OutputGroup>& groups_per_spk= spk_and_groups_pair.second;
455 for (
auto group_it = groups_per_spk.rbegin(); group_it != groups_per_spk.rend(); group_it++) {
476 std::vector<SelectionResult> results;
477 for (
const auto& it : available_coins.
coins) {
479 results.push_back(*result);
484 if (results.size() > 0)
return *std::min_element(results.begin(), results.end());
488 if (allow_mixed_output_types) {
501 std::vector<SelectionResult> results;
503 std::vector<OutputGroup> positive_groups =
GroupOutputs(
wallet, available_coins, coin_selection_params, eligibility_filter,
true);
505 results.push_back(*bnb_result);
509 std::vector<OutputGroup> all_groups =
GroupOutputs(
wallet, available_coins, coin_selection_params, eligibility_filter,
false);
512 results.push_back(*knapsack_result);
517 results.push_back(*srd_result);
520 if (results.size() == 0) {
527 auto& best_result = *std::min_element(results.begin(), results.end());
533 CAmount value_to_select = nTargetValue;
538 std::set<COutPoint> preset_coins;
540 std::vector<COutPoint> vPresetInputs;
542 for (
const COutPoint& outpoint : vPresetInputs) {
543 int input_bytes = -1;
545 auto ptr_wtx =
wallet.GetWalletTx(outpoint.hash);
548 if (ptr_wtx->tx->vout.size() <= outpoint.n) {
551 txout = ptr_wtx->tx->vout.at(outpoint.n);
560 if (input_bytes == -1) {
569 if (input_bytes == -1) {
580 preset_coins.insert(outpoint);
584 preset_inputs.
Insert(output, 0, 0,
false);
604 available_coins.
Erase(preset_coins);
607 unsigned int limit_ancestor_count = 0;
608 unsigned int limit_descendant_count = 0;
609 wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
610 const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
611 const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
624 preselected.
AddInput(preset_inputs);
629 std::optional<SelectionResult> res = [&] {
641 if (
wallet.m_spend_zero_conf_change) {
644 available_coins, coin_selection_params,
true)}) {
648 available_coins, coin_selection_params,
true)}) {
655 available_coins, coin_selection_params,
true)}) {
663 available_coins, coin_selection_params,
true)}) {
670 if (!fRejectLongChains) {
672 CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(),
true ),
673 available_coins, coin_selection_params,
true)}) {
679 return std::optional<SelectionResult>();
682 if (!res)
return std::nullopt;
685 res->Merge(preselected);
698 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
701 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
755 for (
const auto& in : tx.
vin) {
769 const std::vector<CRecipient>& vecSend,
778 int nChangePosInOut = change_pos;
784 coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
787 coin_selection_params.m_long_term_feerate =
wallet.m_consolidate_feerate;
790 const OutputType change_type =
wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type :
wallet.m_default_change_type, vecSend);
792 unsigned int outputs_to_subtract_fee_from = 0;
793 for (
const auto& recipient : vecSend) {
794 recipients_sum += recipient.nAmount;
796 if (recipient.fSubtractFeeFromAmount) {
797 outputs_to_subtract_fee_from++;
798 coin_selection_params.m_subtract_fee_outputs =
true;
807 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
832 CTxOut change_prototype_txout(0, scriptChange);
833 coin_selection_params.change_output_size =
GetSerializeSize(change_prototype_txout);
839 if (change_spend_size == -1) {
842 coin_selection_params.change_spend_size = (size_t)change_spend_size;
853 if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
858 return util::Error{
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.")};
866 coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
867 coin_selection_params.m_cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + coin_selection_params.m_change_fee;
869 coin_selection_params.m_min_change_target =
GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
874 const auto dust =
GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
875 const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
876 coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
879 if (!coin_selection_params.m_subtract_fee_outputs) {
880 coin_selection_params.tx_noinputs_size = 10;
883 for (
const auto& recipient : vecSend)
885 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
888 if (!coin_selection_params.m_subtract_fee_outputs) {
895 txNew.
vout.push_back(txout);
899 const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
900 CAmount selection_target = recipients_sum + not_input_fees;
905 coin_selection_params.m_effective_feerate,
912 std::optional<SelectionResult> result =
SelectCoins(
wallet, available_coins, selection_target, coin_control, coin_selection_params);
916 TRACE5(coin_selection, selected_coins,
wallet.GetName().c_str(),
GetAlgorithmName(result->GetAlgo()).c_str(), result->GetTarget(), result->GetWaste(), result->GetSelectedValue());
918 const CAmount change_amount = result->GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
919 if (change_amount > 0) {
920 CTxOut newTxOut(change_amount, scriptChange);
921 if (nChangePosInOut == -1) {
924 }
else if ((
unsigned int)nChangePosInOut > txNew.
vout.size()) {
925 return util::Error{
_(
"Transaction change output index out of range")};
927 txNew.
vout.insert(txNew.
vout.begin() + nChangePosInOut, newTxOut);
929 nChangePosInOut = -1;
933 std::vector<COutput> selected_coins = result->GetShuffledInputVector();
944 for (
const auto& coin : selected_coins) {
951 int nBytes = tx_sizes.vsize;
953 return util::Error{
_(
"Missing solving data for estimating transaction size")};
955 CAmount fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes);
956 nFeeRet = result->GetSelectedValue() - recipients_sum - change_amount;
960 assert(coin_selection_params.m_subtract_fee_outputs || fee_needed <= nFeeRet);
963 if (nChangePosInOut != -1 && fee_needed < nFeeRet) {
964 auto& change = txNew.
vout.at(nChangePosInOut);
965 change.nValue += nFeeRet - fee_needed;
966 nFeeRet = fee_needed;
970 if (coin_selection_params.m_subtract_fee_outputs) {
971 CAmount to_reduce = fee_needed - nFeeRet;
974 for (
const auto& recipient : vecSend)
976 if (i == nChangePosInOut) {
981 if (recipient.fSubtractFeeFromAmount)
983 txout.
nValue -= to_reduce / outputs_to_subtract_fee_from;
988 txout.
nValue -= to_reduce % outputs_to_subtract_fee_from;
994 return util::Error{
_(
"The transaction amount is too small to pay the fee")};
996 return util::Error{
_(
"The transaction amount is too small to send after the fee has been deducted")};
1002 nFeeRet = fee_needed;
1006 if (scriptChange.
empty() && nChangePosInOut != -1) {
1010 if (sign && !
wallet.SignTransaction(txNew)) {
1024 if (nFeeRet >
wallet.m_default_max_tx_fee) {
1030 if (!
wallet.chain().checkChainLimits(tx)) {
1031 return util::Error{
_(
"Transaction has too long of a mempool chain")};
1039 wallet.WalletLogPrintf(
"Fee Calculation: Fee:%d Bytes:%u Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
1052 const std::vector<CRecipient>& vecSend,
1057 if (vecSend.empty()) {
1058 return util::Error{
_(
"Transaction must have at least one recipient")};
1061 if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](
const auto& recipient){
return recipient.nAmount < 0; })) {
1062 return util::Error{
_(
"Transaction amounts must not be negative")};
1068 TRACE4(coin_selection, normal_create_tx_internal,
wallet.GetName().c_str(), bool(res),
1069 res ? res->fee : 0, res ? res->change_pos : 0);
1070 if (!res)
return res;
1071 const auto& txr_ungrouped = *res;
1074 TRACE1(coin_selection, attempting_aps_create_tx,
wallet.GetName().c_str());
1079 const int ungrouped_change_pos = txr_ungrouped.change_pos;
1080 if (ungrouped_change_pos != -1) {
1081 ExtractDestination(txr_ungrouped.tx->vout[ungrouped_change_pos].scriptPubKey, tmp_cc.destChange);
1086 const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee) :
false};
1087 TRACE5(coin_selection, aps_create_tx_internal,
wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
1088 txr_grouped.has_value() ? txr_grouped->fee : 0, txr_grouped.has_value() ? txr_grouped->change_pos : 0);
1090 wallet.WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n",
1091 txr_ungrouped.fee, txr_grouped->fee, use_aps ?
"grouped" :
"non-grouped");
1092 if (use_aps)
return txr_grouped;
1100 std::vector<CRecipient> vecSend;
1103 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1106 vecSend.push_back(recipient);
1115 std::map<COutPoint, Coin> coins;
1119 wallet.chain().findCoins(coins);
1122 const auto& outPoint = txin.
prevout;
1123 if (
wallet.IsMine(outPoint)) {
1125 coinControl.
Select(outPoint);
1126 }
else if (coins[outPoint].out.IsNull()) {
1127 error =
_(
"Unable to find UTXO for external input");
1140 const auto& txr = *res;
1143 nChangePosInOut = txr.change_pos;
1145 if (nChangePosInOut != -1) {
1146 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
1151 for (
unsigned int idx = 0; idx < tx.
vout.size(); idx++) {
1152 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1156 for (
const CTxIn& txin : tx_new->vin) {
1158 tx.
vin.push_back(txin);
std::shared_ptr< const CTransaction > CTransactionRef
void Shuffle(FastRandomContext &rng_fast)
static int64_t GetTransactionWeight(const CTransaction &tx)
void FundTransaction(CWallet &wallet, CMutableTransaction &tx, CAmount &fee_out, int &change_position, const UniValue &options, CCoinControl &coinControl, bool override_min_fee)
Helper for findBlock to selectively return pieces of block data.
const bool m_include_partial_groups
When avoid_reuse=true and there are full groups (OUTPUT_GROUP_MAX_ENTRIES), whether or not to use any...
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
FastRandomContext & rng_fast
Randomness to use in the context of coin selection.
CAmount min_viable_change
Minimum amount for creating a change output.
mapValue_t mapValue
Key/value map with information about the transaction.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
CAmount GetEffectiveValue() const
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
std::optional< SelectionResult > AttemptSelection(const CWallet &wallet, const CAmount &nTargetValue, const CoinEligibilityFilter &eligibility_filter, const CoinsResult &available_coins, const CoinSelectionParams &coin_selection_params, bool allow_mixed_output_types)
Attempt to find a valid input set that preserves privacy by not mixing OutputTypes.
size_t Size() const
The following methods are provided so that CoinsResult can mimic a vector, i.e., methods can work wit...
CoinsResult AvailableCoins(const CWallet &wallet, const CCoinControl *coinControl, std::optional< CFeeRate > feerate, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount, bool only_spendable)
Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
std::vector< COutput > All() const
Concatenate and return all COutputs as one vector.
void AddInput(const OutputGroup &group)
bool IsPayToScriptHash() const
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
static util::Result< CreatedTransactionResult > CreateTransactionInternal(CWallet &wallet, const std::vector< CRecipient > &vecSend, int change_pos, const CCoinControl &coin_control, bool sign) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime/IsFinalTx().
virtual bool isInitialBlockDownload()=0
Check if in IBD.
#define CHECK_NONFATAL(condition)
Identity function.
void Insert(const COutput &output, size_t ancestors, size_t descendants, bool positive_only)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
CFeeRate GetDiscardRate(const CWallet &wallet)
Return the maximum feerate for discarding change.
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
Use sat/vB fee rate unit.
std::optional< SelectionResult > SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change)
bilingual_str TransactionErrorString(const TransactionError err)
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs...
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
static bool IsCurrentForAntiFeeSniping(interfaces::Chain &chain, const uint256 &block_hash)
void SelectExternal(const COutPoint &outpoint, const CTxOut &txout)
bool IsSelected(const COutPoint &output) const
const std::vector< CTxIn > vin
size_t GetSerializeSize(const T &t, int nVersion=0)
int64_t GetTxTime() const
CTxOut txout
The output itself.
void Select(const COutPoint &output)
std::map< OutputType, std::vector< COutput > > coins
int64_t CAmount
Amount in satoshis (Can be negative)
#define TRACE1(context, event, a)
COutputs available for spending, stored by OutputType.
A transaction with a bunch of additional info that only the owner cares about.
int64_t GetInputWeight(const COutPoint &outpoint) const
CAmount GetAvailableBalance(const CWallet &wallet, const CCoinControl *coinControl)
CFeeRate m_effective_feerate
The targeted feerate of the transaction being built.
CAmount total_amount
Sum of all available coins.
bool EligibleForSpending(const CoinEligibilityFilter &eligibility_filter) const
static constexpr uint32_t MAX_BIP125_RBF_SEQUENCE
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
CAmount m_min_change_target
Mininmum change to target in Knapsack solver: select coins to cover the payment and at least this val...
An input of a transaction.
CAmount GetSelectedEffectiveValue() const
bilingual_str _(const char *psz)
Translation function.
util::Result< CTxDestination > GetReservedDestination(bool internal)
Reserve an address.
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< uint256 > &trusted_parents)
static secp256k1_context * ctx
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
static constexpr unsigned int MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
#define TRACE4(context, event, a, b, c, d)
const std::vector< CTxOut > vout
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
std::optional< SelectionResult > ChooseSelectionResult(const CWallet &wallet, const CAmount &nTargetValue, const CoinEligibilityFilter &eligibility_filter, const std::vector< COutput > &available_coins, const CoinSelectionParams &coin_selection_params)
Attempt to find a valid input set that meets the provided eligibility filter and target.
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
CAmount m_cost_of_change
Cost of creating the change output + cost of spending the change output in the future.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
CAmount GetSelectionAmount() const
An output of a transaction.
A group of UTXOs paid to the same output script.
const CTxOut & FindNonChangeParentOutput(const CWallet &wallet, const CTransaction &tx, int output)
Find non-change parent output.
void ComputeAndSetWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee)
Calculates and stores the waste for this selection via GetSelectionWaste.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
bool GetExternalOutput(const COutPoint &outpoint, CTxOut &txout) const
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
CAmount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
bool m_avoid_partial_spends
When true, always spend all (up to OUTPUT_GROUP_MAX_ENTRIES) or none of the outputs associated with t...
#define TRACE5(context, event, a, b, c, d, e)
TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector< CTxOut > &txouts, const CCoinControl *coin_control)
Calculate the size of the transaction using CoinControl to determine whether to expect signature grin...
Parameters for one iteration of Coin Selection.
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee rate considering user set parameters and the required fee.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
const int DEFAULT_MAX_DEPTH
Parameters for filtering which OutputGroups we may use in coin selection.
const int DEFAULT_MIN_DEPTH
static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::optional< SelectionResult > SelectCoinsSRD(const std::vector< OutputGroup > &utxo_pool, CAmount target_value, FastRandomContext &rng)
Select coins by Single Random Draw.
int CalculateMaximumSignedInputSize(const CTxOut &txout, const COutPoint outpoint, const SigningProvider *provider, const CCoinControl *coin_control)
int m_min_depth
Minimum chain depth value for coin availability.
An interface to be implemented by keystores that support signing.
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
void KeepDestination()
Keep the address. Do not return it's key to the keypool when this object goes out of scope...
Serialized script, used inside transaction inputs and outputs.
bool m_include_unsafe_inputs
If false, only safe inputs will be used.
static const int PROTOCOL_VERSION
network protocol versioning
static void DiscourageFeeSniping(CMutableTransaction &tx, FastRandomContext &rng_fast, interfaces::Chain &chain, const uint256 &block_hash, int block_height)
Set a height-based locktime for new transactions (uses the height of the current chain tip unless we ...
void ListSelected(std::vector< COutPoint > &vOutpoints) const
std::optional< SelectionResult > SelectCoins(const CWallet &wallet, CoinsResult &available_coins, const CAmount &nTargetValue, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params)
Select a set of coins such that nTargetValue is met and at least all coins from coin_control are sele...
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
bool m_allow_other_inputs
If true, the selection process can add extra unselected inputs from the wallet while requires all sel...
std::string GetAlgorithmName(const SelectionAlgorithm algo)
A wrapper to reserve an address from a wallet.
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
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...
bilingual_str ErrorString(const Result< T > &result)
A reference to a CScript: the Hash160 of its serialization (see script.h)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
A mutable version of CTransaction.
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65)...
CAmount GetSelectedValue() const
Get the sum of the input values.
static const unsigned int LOCKTIME_THRESHOLD
std::vector< OutputGroup > GroupOutputs(const CWallet &wallet, const std::vector< COutput > &outputs, const CoinSelectionParams &coin_sel_params, const CoinEligibilityFilter &filter, bool positive_only)
The basic transaction that is broadcasted on the network and contained in blocks. ...
void Add(OutputType type, const COutput &out)
int m_max_depth
Maximum chain depth value for coin availability.
std::optional< SelectionResult > KnapsackSolver(std::vector< OutputGroup > &groups, const CAmount &nTargetValue, CAmount change_target, FastRandomContext &rng)
int64_t GetTime()
DEPRECATED, see GetTime.
bool DummySignInput(const SigningProvider &provider, CTxIn &tx_in, const CTxOut &txout, const CCoinControl *coin_control)
A UTXO under consideration for use in funding a new transaction.
CAmount GenerateChangeTarget(const CAmount payment_value, const CAmount change_fee, FastRandomContext &rng)
Choose a random change target for each transaction to make it harder to fingerprint the Core wallet b...
bool error(const char *fmt, const Args &... args)
std::string StringForFeeReason(FeeReason reason)
CoinsResult AvailableCoinsListUnspent(const CWallet &wallet, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount)
Wrapper function for AvailableCoins which skips the feerate parameter.
bool CachedTxIsFromMe(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
bool HasInputWeight(const COutPoint &outpoint) const
CAmount m_change_fee
Cost of creating the change output.
void Erase(const std::set< COutPoint > &coins_to_remove)
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
void emplace_back(Args &&... args)
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS
Default for -walletrejectlongchains.
std::vector< COutput > m_outputs
The list of UTXOs contained in this output group.