45 const std::unique_ptr<SigningProvider> provider =
wallet->GetSolvingProvider(txout.
scriptPubKey);
53 if (!
wallet->DummySignTx(txNew, txouts, coin_control)) {
59 return TxSize{vsize, weight};
64 std::vector<CTxOut> txouts;
69 if (mi !=
wallet->mapWallet.end()) {
71 txouts.emplace_back(mi->second.tx->vout.at(input.
prevout.
n));
72 }
else if (coin_control) {
77 txouts.emplace_back(txout);
88 for (
const auto& it :
coins) {
89 size += it.second.size();
96 std::vector<COutput> all;
97 all.reserve(
coins.size());
98 for (
const auto& it :
coins) {
99 all.insert(all.end(), it.second.begin(), it.second.end());
110 for (
auto& [type, vec] :
coins) {
111 auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](
const COutput& coin) {
113 if (coins_to_remove.count(coin.outpoint) == 0) return false;
116 total_amount -= coin.txout.nValue;
117 if (coin.HasEffectiveValue()) total_effective_amount = *total_effective_amount - coin.GetEffectiveValue();
120 vec.erase(remove_it, vec.end());
126 for (
auto& it :
coins) {
127 ::Shuffle(it.second.begin(), it.second.end(), rng_fast);
133 coins[type].emplace_back(out);
164 std::vector<COutPoint> vPresetInputs;
165 coin_control.ListSelected(vPresetInputs);
166 for (
const COutPoint& outpoint : vPresetInputs) {
167 int input_bytes = -1;
169 if (
auto ptr_wtx =
wallet.GetWalletTx(outpoint.hash)) {
171 if (ptr_wtx->tx->vout.size() <= outpoint.n) {
174 txout = ptr_wtx->tx->vout.at(outpoint.n);
178 if (!coin_control.GetExternalOutput(outpoint, txout)) {
183 if (input_bytes == -1) {
188 if (coin_control.HasInputWeight(outpoint)) {
192 if (input_bytes == -1) {
197 COutput output(outpoint, txout, 0, input_bytes,
true,
true,
true, 0,
false, coin_selection_params.m_effective_feerate);
198 result.
Insert(output, coin_selection_params.m_subtract_fee_outputs);
205 std::optional<CFeeRate> feerate,
218 std::set<uint256> trusted_parents;
219 for (
const auto& entry :
wallet.mapWallet)
221 const uint256& wtxid = entry.first;
227 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
253 if (nDepth == 0 && wtx.
mapValue.count(
"replaces_txid")) {
265 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
269 if (only_safe && !safeTx) {
273 if (nDepth < min_depth || nDepth > max_depth) {
279 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
280 const CTxOut& output = wtx.
tx->vout[i];
293 if (
wallet.IsSpent(outpoint))
306 std::unique_ptr<SigningProvider> provider =
wallet.GetSolvingProvider(output.
scriptPubKey);
311 bool solvable = input_bytes > -1;
318 std::vector<std::vector<uint8_t>> script_solutions;
325 bool is_from_p2sh{
false};
328 if (!provider->GetCScript(
CScriptID(
uint160(script_solutions[0])), script))
continue;
329 type =
Solver(script, script_solutions);
334 COutput(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.
GetTxTime(), tx_from_me, feerate));
375 if (!it || it->
tx->vout.size() <= prevout.
n ||
376 !
wallet.IsMine(it->
tx->vout[prevout.
n])) {
389 std::map<CTxDestination, std::vector<COutput>> result;
401 result[address].emplace_back(coin);
409 std::vector<OutputGroup> groups_out;
413 for (
const COutput& output : outputs) {
415 if (!output.spendable)
continue;
417 size_t ancestors, descendants;
418 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
422 group.Insert(output, ancestors, descendants, positive_only);
425 if (positive_only && group.GetSelectionAmount() <= 0)
continue;
426 if (group.m_outputs.size() > 0 && group.EligibleForSpending(filter)) groups_out.push_back(group);
437 std::map<CScript, std::vector<OutputGroup>> spk_to_groups_map;
438 for (
const auto& output : outputs) {
440 if (!output.spendable)
continue;
442 size_t ancestors, descendants;
443 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
444 CScript spk = output.txout.scriptPubKey;
446 std::vector<OutputGroup>& groups = spk_to_groups_map[spk];
448 if (groups.size() == 0) {
461 groups.emplace_back(coin_sel_params);
462 group = &groups.back();
466 group->
Insert(output, ancestors, descendants, positive_only);
470 for (
const auto& spk_and_groups_pair: spk_to_groups_map) {
471 const std::vector<OutputGroup>& groups_per_spk= spk_and_groups_pair.second;
474 for (
auto group_it = groups_per_spk.rbegin(); group_it != groups_per_spk.rend(); group_it++) {
498 std::vector<SelectionResult> results;
499 for (
const auto& it : available_coins.
coins) {
504 if (result) results.push_back(*result);
508 if (results.size() > 0)
return *std::min_element(results.begin(), results.end());
513 if (allow_mixed_output_types && available_coins.
TypesCount() > 1) {
524 std::vector<SelectionResult> results;
526 std::vector<OutputGroup> positive_groups =
GroupOutputs(
wallet, available_coins, coin_selection_params, eligibility_filter,
true);
528 results.push_back(*bnb_result);
532 std::vector<OutputGroup> all_groups =
GroupOutputs(
wallet, available_coins, coin_selection_params, eligibility_filter,
false);
535 results.push_back(*knapsack_result);
540 results.push_back(*srd_result);
543 if (results.empty()) {
548 std::vector<SelectionResult> eligible_results;
549 std::copy_if(results.begin(), results.end(), std::back_inserter(eligible_results), [coin_selection_params](
const SelectionResult& result) {
550 const auto initWeight{coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR};
554 if (eligible_results.empty()) {
555 return util::Error{
_(
"The inputs size exceeds the maximum weight. "
556 "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")};
561 auto& best_result = *std::min_element(eligible_results.begin(), eligible_results.end());
574 return util::Error{
_(
"The preselected coins total amount does not cover the transaction target. "
575 "Please allow other inputs to be automatically selected or include more coins manually")};
579 if (selection_target <= 0) {
590 if (selection_target > available_coins_total_amount) {
596 if (!op_selection_result)
return op_selection_result;
599 if (!pre_set_inputs.
coins.empty()) {
602 op_selection_result->Merge(preselected);
607 return op_selection_result;
612 bool allow_mixed_output_types{
true};
617 unsigned int limit_ancestor_count = 0;
618 unsigned int limit_descendant_count = 0;
619 wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
620 const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
621 const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
638 std::vector<SelectionFilter> ordered_filters{
646 if (
wallet.m_spend_zero_conf_change) {
648 ordered_filters.push_back({
CoinEligibilityFilter(0, 1, std::min(
size_t{4}, max_ancestors/3), std::min(
size_t{4}, max_descendants/3))});
662 if (!fRejectLongChains) {
664 std::numeric_limits<uint64_t>::max(),
672 std::vector<util::Result<SelectionResult>> res_detailed_errors;
673 for (
const auto& select_filter : ordered_filters) {
675 coin_selection_params, select_filter.allow_mixed_output_types)}) {
681 if (
HasErrorMsg(res)) res_detailed_errors.emplace_back(res);
696 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
699 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
753 for (
const auto& in : tx.
vin) {
767 const std::vector<CRecipient>& vecSend,
775 int nChangePosInOut = change_pos;
781 coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
784 coin_selection_params.m_long_term_feerate =
wallet.m_consolidate_feerate;
787 const OutputType change_type =
wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type :
wallet.m_default_change_type, vecSend);
789 unsigned int outputs_to_subtract_fee_from = 0;
790 for (
const auto& recipient : vecSend) {
791 recipients_sum += recipient.nAmount;
793 if (recipient.fSubtractFeeFromAmount) {
794 outputs_to_subtract_fee_from++;
795 coin_selection_params.m_subtract_fee_outputs =
true;
804 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
829 CTxOut change_prototype_txout(0, scriptChange);
830 coin_selection_params.change_output_size =
GetSerializeSize(change_prototype_txout);
836 if (change_spend_size == -1) {
839 coin_selection_params.change_spend_size = (size_t)change_spend_size;
850 if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
855 return util::Error{
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.")};
863 coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
864 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;
866 coin_selection_params.m_min_change_target =
GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
871 const auto dust =
GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
872 const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
873 coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
879 for (
const auto& recipient : vecSend)
881 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
889 txNew.
vout.push_back(txout);
893 const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.m_subtract_fee_outputs ? 0 : coin_selection_params.tx_noinputs_size);
894 CAmount selection_target = recipients_sum + not_input_fees;
898 if (coin_control.HasSelected()) {
901 preset_inputs = *res_fetch_inputs;
907 if (coin_control.m_allow_other_inputs) {
908 available_coins =
AvailableCoins(
wallet, &coin_control, coin_selection_params.m_effective_feerate);
912 auto select_coins_res =
SelectCoins(
wallet, available_coins, preset_inputs, selection_target, coin_control, coin_selection_params);
913 if (!select_coins_res) {
921 const CAmount change_amount = result.
GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
922 if (change_amount > 0) {
923 CTxOut newTxOut(change_amount, scriptChange);
924 if (nChangePosInOut == -1) {
927 }
else if ((
unsigned int)nChangePosInOut > txNew.
vout.size()) {
928 return util::Error{
_(
"Transaction change output index out of range")};
930 txNew.
vout.insert(txNew.
vout.begin() + nChangePosInOut, newTxOut);
932 nChangePosInOut = -1;
947 for (
const auto& coin : selected_coins) {
954 int nBytes = tx_sizes.
vsize;
956 return util::Error{
_(
"Missing solving data for estimating transaction size")};
958 CAmount fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes);
960 Assume(recipients_sum + change_amount == output_value);
964 if (current_fee < 0) {
969 if (nChangePosInOut != -1 && fee_needed < current_fee) {
970 auto& change = txNew.
vout.at(nChangePosInOut);
971 change.nValue += current_fee - fee_needed;
973 if (fee_needed != current_fee) {
979 if (coin_selection_params.m_subtract_fee_outputs) {
980 CAmount to_reduce = fee_needed - current_fee;
983 for (
const auto& recipient : vecSend)
985 if (i == nChangePosInOut) {
990 if (recipient.fSubtractFeeFromAmount)
992 txout.
nValue -= to_reduce / outputs_to_subtract_fee_from;
997 txout.
nValue -= to_reduce % outputs_to_subtract_fee_from;
1003 return util::Error{
_(
"The transaction amount is too small to pay the fee")};
1005 return util::Error{
_(
"The transaction amount is too small to send after the fee has been deducted")};
1012 if (fee_needed != current_fee) {
1019 if (fee_needed > current_fee) {
1024 if (scriptChange.
empty() && nChangePosInOut != -1) {
1028 if (sign && !
wallet.SignTransaction(txNew)) {
1042 if (current_fee >
wallet.m_default_max_tx_fee) {
1048 if (!
wallet.chain().checkChainLimits(tx)) {
1049 return util::Error{
_(
"Transaction has too long of a mempool chain")};
1057 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",
1070 const std::vector<CRecipient>& vecSend,
1075 if (vecSend.empty()) {
1076 return util::Error{
_(
"Transaction must have at least one recipient")};
1079 if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](
const auto& recipient){ return recipient.nAmount < 0; })) {
1080 return util::Error{
_(
"Transaction amounts must not be negative")};
1086 TRACE4(coin_selection, normal_create_tx_internal,
wallet.GetName().c_str(),
bool(res),
1087 res ? res->fee : 0, res ? res->change_pos : 0);
1088 if (!res)
return res;
1089 const auto& txr_ungrouped = *res;
1092 TRACE1(coin_selection, attempting_aps_create_tx,
wallet.GetName().c_str());
1097 const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee) :
false};
1098 TRACE5(coin_selection, aps_create_tx_internal,
wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
1099 txr_grouped.has_value() ? txr_grouped->fee : 0, txr_grouped.has_value() ? txr_grouped->change_pos : 0);
1101 wallet.WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n",
1102 txr_ungrouped.fee, txr_grouped->fee, use_aps ?
"grouped" :
"non-grouped");
1103 if (use_aps)
return txr_grouped;
1111 std::vector<CRecipient> vecSend;
1114 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1117 vecSend.push_back(recipient);
1126 std::map<COutPoint, Coin> coins;
1130 wallet.chain().findCoins(coins);
1133 const auto& outPoint = txin.
prevout;
1134 if (
wallet.IsMine(outPoint)) {
1136 coinControl.
Select(outPoint);
1137 }
else if (coins[outPoint].out.IsNull()) {
1138 error =
_(
"Unable to find UTXO for external input");
1151 const auto& txr = *res;
1154 nChangePosInOut = txr.change_pos;
1156 if (nChangePosInOut != -1) {
1157 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
1162 for (
unsigned int idx = 0; idx < tx.
vout.size(); idx++) {
1163 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1167 for (
const CTxIn& txin : tx_new->vin) {
1169 tx.
vin.push_back(txin);
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
int64_t CAmount
Amount in satoshis (Can be negative)
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
#define STR_INTERNAL_BUG(msg)
#define Assume(val)
Assume is the identity function.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization (see script.h)
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const std::vector< CTxIn > vin
An input of a transaction.
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65).
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime/IsFinalTx().
An output of a transaction.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
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...
virtual bool isInitialBlockDownload()=0
Check if in IBD.
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
Helper for findBlock to selectively return pieces of block data.
void emplace_back(Args &&... args)
void Select(const COutPoint &output)
void SelectExternal(const COutPoint &outpoint, const CTxOut &txout)
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
bool IsSelected(const COutPoint &output) const
int m_min_depth
Minimum chain depth value for coin availability.
bool m_allow_other_inputs
If true, the selection process can add extra unselected inputs from the wallet while requires all sel...
int m_max_depth
Maximum chain depth value for coin availability.
bool m_include_unsafe_inputs
If false, only safe inputs will be used.
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
bool GetExternalOutput(const COutPoint &outpoint, CTxOut &txout) const
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.
int64_t GetTxTime() const
A wrapper to reserve an address from a wallet.
static int64_t GetTransactionWeight(const CTransaction &tx)
bilingual_str TransactionErrorString(const TransactionError err)
@ SAT_VB
Use sat/vB fee rate unit.
void KeepDestination()
Keep the address. Do not return its key to the keypool when this object goes out of scope.
util::Result< CTxDestination > GetReservedDestination(bool internal)
Reserve an address.
bool DummySignInput(const SigningProvider &provider, CTxIn &tx_in, const CTxOut &txout, const CCoinControl *coin_control)
bilingual_str ErrorString(const Result< T > &result)
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size
const CTxOut & FindNonChangeParentOutput(const CWallet &wallet, const COutPoint &outpoint)
Find non-change parent output.
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)
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
bool FundTransaction(CWallet &wallet, CMutableTransaction &tx, CAmount &nFeeRet, int &nChangePosInOut, bilingual_str &error, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, CCoinControl coinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
CAmount GetAvailableBalance(const CWallet &wallet, const CCoinControl *coinControl)
const int DEFAULT_MIN_DEPTH
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 CachedTxIsFromMe(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
util::Result< PreSelectedInputs > FetchSelectedInputs(const CWallet &wallet, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
Fetch and validate coin control selected inputs.
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< uint256 > &trusted_parents)
const int DEFAULT_MAX_DEPTH
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...
util::Result< SelectionResult > SelectCoins(const CWallet &wallet, CoinsResult &available_coins, const PreSelectedInputs &pre_set_inputs, const CAmount &nTargetValue, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params)
Select all coins from coin_control, and if coin_control 'm_allow_other_inputs=true',...
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee rate considering user set parameters and the required fee.
std::optional< SelectionResult > SelectCoinsSRD(const std::vector< OutputGroup > &utxo_pool, CAmount target_value, FastRandomContext &rng)
Select coins by Single Random Draw.
std::optional< SelectionResult > KnapsackSolver(std::vector< OutputGroup > &groups, const CAmount &nTargetValue, CAmount change_target, FastRandomContext &rng)
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
CoinsResult AvailableCoinsListUnspent(const CWallet &wallet, const CCoinControl *coinControl, CoinFilterParams params)
Wrapper function for AvailableCoins which skips the feerate and CoinFilterParams::only_spendable para...
util::Result< 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.
std::string GetAlgorithmName(const SelectionAlgorithm algo)
TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const CCoinControl *coin_control)
static bool HasErrorMsg(const util::Result< SelectionResult > &res)
int CalculateMaximumSignedInputSize(const CTxOut &txout, const COutPoint outpoint, const SigningProvider *provider, const CCoinControl *coin_control)
std::vector< OutputGroup > GroupOutputs(const CWallet &wallet, const std::vector< COutput > &outputs, const CoinSelectionParams &coin_sel_params, const CoinEligibilityFilter &filter, bool positive_only)
std::optional< SelectionResult > SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change)
CFeeRate GetDiscardRate(const CWallet &wallet)
Return the maximum feerate for discarding change.
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...
@ WALLET_FLAG_AVOID_REUSE
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
static bool IsCurrentForAntiFeeSniping(interfaces::Chain &chain, const uint256 &block_hash)
int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *wallet, const CCoinControl *coin_control)
Get the marginal bytes if spending the specified output from this transaction.
util::Result< SelectionResult > AutomaticCoinSelection(const CWallet &wallet, CoinsResult &available_coins, const CAmount &value_to_select, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params)
Select a set of coins such that nTargetValue is met; never select unconfirmed coins if they are not o...
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 ...
static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES
util::Result< 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.
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS
Default for -walletrejectlongchains.
CoinsResult AvailableCoins(const CWallet &wallet, const CCoinControl *coinControl, std::optional< CFeeRate > feerate, const CoinFilterParams ¶ms)
Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
CAmount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
static constexpr unsigned int MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
CAmount CalculateOutputValue(const TxType &tx)
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
static const unsigned int LOCKTIME_THRESHOLD
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
size_t GetSerializeSize(const T &t, int nVersion=0)
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
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, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
A mutable version of CTransaction.
std::vector< CTxOut > vout
A UTXO under consideration for use in funding a new transaction.
CTxOut txout
The output itself.
CAmount GetEffectiveValue() const
bool HasEffectiveValue() const
Parameters for filtering which OutputGroups we may use in coin selection.
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 include_immature_coinbase
Parameters for one iteration of Coin Selection.
FastRandomContext & rng_fast
Randomness to use in the context of coin selection.
CAmount m_min_change_target
Mininmum change to target in Knapsack solver: select coins to cover the payment and at least this val...
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
CAmount min_viable_change
Minimum amount for creating a change output.
CAmount m_cost_of_change
Cost of creating the change output + cost of spending the change output in the future.
CAmount m_change_fee
Cost of creating the change output.
bool m_avoid_partial_spends
When true, always spend all (up to OUTPUT_GROUP_MAX_ENTRIES) or none of the outputs associated with t...
COutputs available for spending, stored by OutputType.
std::optional< CAmount > GetEffectiveTotalAmount()
size_t TypesCount() const
Return how many different output types this struct stores.
CAmount total_amount
Sum of all available coins raw value.
void Add(OutputType type, const COutput &out)
std::vector< COutput > All() const
Concatenate and return all COutputs as one vector.
size_t Size() const
The following methods are provided so that CoinsResult can mimic a vector, i.e., methods can work wit...
std::map< OutputType, std::vector< COutput > > coins
void Shuffle(FastRandomContext &rng_fast)
std::optional< CAmount > total_effective_amount
Sum of all available coins effective value (each output value minus fees required to spend it)
void Erase(const std::unordered_set< COutPoint, SaltedOutpointHasher > &coins_to_remove)
A group of UTXOs paid to the same output script.
void Insert(const COutput &output, size_t ancestors, size_t descendants, bool positive_only)
CAmount GetSelectionAmount() const
std::vector< COutput > m_outputs
The list of UTXOs contained in this output group.
bool EligibleForSpending(const CoinEligibilityFilter &eligibility_filter) const
CoinEligibilityFilter filter
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.
void AddInputs(const std::set< COutput > &inputs, bool subtract_fee_outputs)
std::vector< COutput > GetShuffledInputVector() const
Get the vector of COutputs that will be used to fill in a CTransaction's vin.
CAmount GetChange(const CAmount min_viable_change, const CAmount change_fee) const
Get the amount for the change output after paying needed fees.
CAmount GetSelectedValue() const
Get the sum of the input values.
CAmount GetTarget() const
SelectionAlgorithm GetAlgo() const
bool error(const char *fmt, const Args &... args)
static secp256k1_context * ctx
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define TRACE5(context, event, a, b, c, d, e)
#define TRACE4(context, event, a, b, c, d)
#define TRACE1(context, event, a)
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::string StringForFeeReason(FeeReason reason)
static constexpr uint32_t MAX_BIP125_RBF_SEQUENCE
static const int PROTOCOL_VERSION
network protocol versioning
static void AvailableCoins(benchmark::Bench &bench, const std::vector< OutputType > &output_type)