59 const CCoinControl* coin_control,
const bool tx_is_segwit,
60 const bool can_grind_r) {
63 const bool is_segwit =
IsSegwit(desc);
71 const int64_t witstack_len = is_segwit ?
GetSizeOfCompactSize(*elems_count) : (tx_is_segwit ? 1 : 0);
83 if (!provider)
return -1;
86 if (
const auto weight =
MaxInputWeight(*desc, {}, coin_control,
true, can_grind_r)) {
96 const std::unique_ptr<SigningProvider> provider =
wallet->GetSolvingProvider(txout.
scriptPubKey);
105 for (
const auto spkman:
wallet->GetScriptPubKeyMans(script_pubkey)) {
106 providers.
AddProvider(spkman->GetSolvingProvider(script_pubkey));
116 const CTxIn& txin,
const CTxOut& txo,
const bool tx_is_segwit,
117 const bool can_grind_r)
126 if (desc)
return MaxInputWeight(*desc, {txin}, coin_control, tx_is_segwit, can_grind_r);
138 bool is_segwit = std::any_of(txouts.begin(), txouts.end(), [&](
const CTxOut& txo) {
144 if (is_segwit) weight += 2;
150 for (uint32_t i = 0; i < txouts.size(); i++) {
152 if (!txin_weight)
return TxSize{-1, -1};
153 assert(*txin_weight > -1);
154 weight += *txin_weight;
163 std::vector<CTxOut> txouts;
168 if (mi !=
wallet->mapWallet.end()) {
170 txouts.emplace_back(mi->second.tx->vout.at(input.
prevout.
n));
171 }
else if (coin_control) {
173 if (!txout)
return TxSize{-1, -1};
174 txouts.emplace_back(*txout);
185 for (
const auto& it :
coins) {
186 size += it.second.size();
193 std::vector<COutput> all;
194 all.reserve(
coins.size());
195 for (
const auto& it :
coins) {
196 all.insert(all.end(), it.second.begin(), it.second.end());
207 for (
auto& [type, vec] :
coins) {
208 auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](
const COutput& coin) {
210 if (coins_to_remove.count(coin.outpoint) == 0)
return false;
217 vec.erase(remove_it, vec.end());
223 for (
auto& it :
coins) {
224 ::Shuffle(it.second.begin(), it.second.end(), rng_fast);
232 if (
out.HasEffectiveValue()) {
261 const bool can_grind_r =
wallet.CanGrindR();
262 std::map<COutPoint, CAmount> map_of_bump_fees =
wallet.chain().CalculateIndividualBumpFees(coin_control.ListSelected(), coin_selection_params.m_effective_feerate);
263 for (
const COutPoint& outpoint : coin_control.ListSelected()) {
264 int input_bytes = -1;
266 if (
auto ptr_wtx =
wallet.GetWalletTx(outpoint.hash)) {
268 if (ptr_wtx->tx->vout.size() <= outpoint.n) {
271 txout = ptr_wtx->tx->vout.at(outpoint.n);
275 const auto out{coin_control.GetExternalOutput(outpoint)};
283 if (input_bytes == -1) {
288 if (coin_control.HasInputWeight(outpoint)) {
292 if (input_bytes == -1) {
297 COutput output(outpoint, txout, 0, input_bytes,
true,
true,
true, 0,
false, coin_selection_params.m_effective_feerate);
299 result.
Insert(output, coin_selection_params.m_subtract_fee_outputs);
306 std::optional<CFeeRate> feerate,
318 const bool can_grind_r =
wallet.CanGrindR();
319 std::vector<COutPoint> outpoints;
321 std::set<uint256> trusted_parents;
322 for (
const auto& entry :
wallet.mapWallet)
324 const uint256& wtxid = entry.first;
330 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
356 if (nDepth == 0 && wtx.
mapValue.count(
"replaces_txid")) {
368 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
372 if (only_safe && !safeTx) {
376 if (nDepth < min_depth || nDepth > max_depth) {
382 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
383 const CTxOut& output = wtx.
tx->vout[i];
396 if (
wallet.IsSpent(outpoint))
409 std::unique_ptr<SigningProvider> provider =
wallet.GetSolvingProvider(output.
scriptPubKey);
414 bool solvable = input_bytes > -1;
421 std::vector<std::vector<uint8_t>> script_solutions;
428 bool is_from_p2sh{
false};
431 if (!provider->GetCScript(
CScriptID(
uint160(script_solutions[0])), script))
continue;
432 type =
Solver(script, script_solutions);
437 COutput(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.
GetTxTime(), tx_from_me, feerate));
439 outpoints.push_back(outpoint);
455 if (feerate.has_value()) {
456 std::map<COutPoint, CAmount> map_of_bump_fees =
wallet.chain().CalculateIndividualBumpFees(outpoints, feerate.value());
458 for (
auto& [
_, outputs] : result.
coins) {
459 for (
auto& output : outputs) {
460 output.ApplyBumpFee(map_of_bump_fees.at(output.outpoint));
484 if (!it || it->
tx->vout.size() <= prevout.
n ||
485 !
wallet.IsMine(it->
tx->vout[prevout.
n])) {
498 std::map<CTxDestination, std::vector<COutput>> result;
511 if (
auto pk_dest = std::get_if<PubKeyDestination>(&address)) {
512 address =
PKHash(pk_dest->GetPubKey());
517 result[address].emplace_back(coin);
526 const std::vector<SelectionFilter>& filters,
527 std::vector<OutputGroup>& ret_discarded_groups)
533 for (
const auto& [type, outputs] : coins.
coins) {
534 for (
const COutput& output : outputs) {
536 size_t ancestors, descendants;
537 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
541 group.Insert(std::make_shared<COutput>(output), ancestors, descendants);
544 bool accepted =
false;
545 for (
const auto& sel_filter : filters) {
546 const auto& filter = sel_filter.filter;
547 if (!
group.EligibleForSpending(filter))
continue;
548 filtered_groups[filter].Push(
group, type,
true,
true);
551 if (!accepted) ret_discarded_groups.emplace_back(
group);
554 return filtered_groups;
563 typedef std::map<std::pair<CScript, OutputType>, std::vector<OutputGroup>> ScriptPubKeyToOutgroup;
564 const auto& insert_output = [&](
565 const std::shared_ptr<COutput>& output,
OutputType type,
size_t ancestors,
size_t descendants,
566 ScriptPubKeyToOutgroup& groups_map) {
567 std::vector<OutputGroup>& groups = groups_map[std::make_pair(output->txout.scriptPubKey,type)];
569 if (groups.size() == 0) {
571 groups.emplace_back(coin_sel_params);
582 groups.emplace_back(coin_sel_params);
583 group = &groups.back();
586 group->Insert(output, ancestors, descendants);
589 ScriptPubKeyToOutgroup spk_to_groups_map;
590 ScriptPubKeyToOutgroup spk_to_positive_groups_map;
591 for (
const auto& [type, outs] : coins.
coins) {
592 for (
const COutput& output : outs) {
593 size_t ancestors, descendants;
594 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
596 const auto& shared_output = std::make_shared<COutput>(output);
598 if (output.GetEffectiveValue() > 0) {
599 insert_output(shared_output, type, ancestors, descendants, spk_to_positive_groups_map);
603 insert_output(shared_output, type, ancestors, descendants, spk_to_groups_map);
608 const auto& push_output_groups = [&](
const ScriptPubKeyToOutgroup& groups_map,
bool positive_only) {
609 for (
const auto& [script, groups] : groups_map) {
611 for (
auto group_it = groups.rbegin(); group_it != groups.rend(); group_it++) {
615 bool accepted =
false;
616 for (
const auto& sel_filter : filters) {
617 const auto& filter = sel_filter.filter;
618 if (!
group.EligibleForSpending(filter))
continue;
621 if (group_it == groups.rbegin() && groups.size() > 1 && !filter.m_include_partial_groups) {
627 filtered_groups[filter].Push(
group, type, positive_only, !positive_only);
630 if (!accepted) ret_discarded_groups.emplace_back(
group);
635 push_output_groups(spk_to_groups_map,
false);
636 push_output_groups(spk_to_positive_groups_map,
true);
638 return filtered_groups;
644 const std::vector<SelectionFilter>& filters)
646 std::vector<OutputGroup> unused;
657 std::vector<SelectionResult> results;
663 if (result) results.push_back(*result);
667 if (results.size() > 0)
return *std::min_element(results.begin(), results.end());
672 if (allow_mixed_output_types && groups.
TypesCount() > 1) {
683 std::vector<SelectionResult> results;
684 std::vector<util::Result<SelectionResult>> errors;
689 errors.emplace_back(result);
699 results.push_back(*bnb_result);
700 }
else append_error(bnb_result);
708 results.push_back(*knapsack_result);
709 }
else append_error(knapsack_result);
712 results.push_back(*srd_result);
713 }
else append_error(srd_result);
715 if (results.empty()) {
718 return errors.empty() ?
util::Error() : errors.front();
722 for (
auto& result : results) {
723 std::vector<COutPoint> outpoints;
724 std::set<std::shared_ptr<COutput>> coins = result.GetInputSet();
726 for (
auto& coin : coins) {
727 if (coin->depth > 0)
continue;
728 outpoints.push_back(coin->outpoint);
729 summed_bump_fees += coin->ancestor_bump_fees;
732 if (!combined_bump_fee.has_value()) {
733 return util::Error{
_(
"Failed to calculate bump fees, because unconfirmed UTXOs depend on enormous cluster of unconfirmed transactions.")};
735 CAmount bump_fee_overestimate = summed_bump_fees - combined_bump_fee.value();
736 if (bump_fee_overestimate) {
737 result.SetBumpFeeDiscount(bump_fee_overestimate);
744 return *std::min_element(results.begin(), results.end());
756 return util::Error{
_(
"The preselected coins total amount does not cover the transaction target. " 757 "Please allow other inputs to be automatically selected or include more coins manually")};
761 if (selection_target <= 0) {
772 if (selection_target > available_coins_total_amount) {
778 if (!op_selection_result)
return op_selection_result;
781 if (!pre_set_inputs.
coins.empty()) {
784 op_selection_result->Merge(preselected);
789 return op_selection_result;
794 unsigned int limit_ancestor_count = 0;
795 unsigned int limit_descendant_count = 0;
796 wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
797 const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
798 const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
813 std::vector<SelectionFilter> ordered_filters{
821 if (
wallet.m_spend_zero_conf_change) {
823 ordered_filters.push_back({
CoinEligibilityFilter(0, 1, std::min(
size_t{4}, max_ancestors/3), std::min(
size_t{4}, max_descendants/3))});
837 if (!fRejectLongChains) {
839 std::numeric_limits<uint64_t>::max(),
845 std::vector<OutputGroup> discarded_groups;
850 CAmount total_unconf_long_chain = 0;
851 for (
const auto&
group : discarded_groups) {
852 total_discarded +=
group.GetSelectionAmount();
853 if (
group.m_ancestors >= max_ancestors ||
group.m_descendants >= max_descendants) total_unconf_long_chain +=
group.GetSelectionAmount();
858 if (total_amount + total_unconf_long_chain > value_to_select) {
859 return util::Result<SelectionResult>({
_(
"Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool")});
867 std::vector<util::Result<SelectionResult>> res_detailed_errors;
868 for (
const auto& select_filter : ordered_filters) {
869 auto it = filtered_groups.find(select_filter.filter);
870 if (it == filtered_groups.end())
continue;
872 coin_selection_params, select_filter.allow_mixed_output_types)}) {
878 if (
HasErrorMsg(res)) res_detailed_errors.emplace_back(res);
883 if (!res_detailed_errors.empty())
return res_detailed_errors.front();
898 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
901 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
955 for (
const auto& in : tx.
vin) {
969 const std::vector<CRecipient>& vecSend,
977 int nChangePosInOut = change_pos;
983 coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
984 coin_selection_params.m_include_unsafe_inputs = coin_control.m_include_unsafe_inputs;
987 coin_selection_params.m_long_term_feerate =
wallet.m_consolidate_feerate;
990 const OutputType change_type =
wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type :
wallet.m_default_change_type, vecSend);
992 unsigned int outputs_to_subtract_fee_from = 0;
993 for (
const auto& recipient : vecSend) {
994 recipients_sum += recipient.nAmount;
996 if (recipient.fSubtractFeeFromAmount) {
997 outputs_to_subtract_fee_from++;
998 coin_selection_params.m_subtract_fee_outputs =
true;
1007 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
1032 CTxOut change_prototype_txout(0, scriptChange);
1033 coin_selection_params.change_output_size =
GetSerializeSize(change_prototype_txout);
1039 if (change_spend_size == -1) {
1042 coin_selection_params.change_spend_size = (size_t)change_spend_size;
1053 if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
1058 return util::Error{
strprintf(
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s."),
"-fallbackfee")};
1066 coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
1067 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;
1069 coin_selection_params.m_min_change_target =
GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
1074 const auto dust =
GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
1075 const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
1076 coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
1082 for (
const auto& recipient : vecSend)
1092 txNew.
vout.push_back(txout);
1096 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);
1097 CAmount selection_target = recipients_sum + not_input_fees;
1101 if (selection_target == 0 && !coin_control.HasSelected()) {
1102 return util::Error{
_(
"Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input")};
1107 if (coin_control.HasSelected()) {
1110 preset_inputs = *res_fetch_inputs;
1116 if (coin_control.m_allow_other_inputs) {
1117 available_coins =
AvailableCoins(
wallet, &coin_control, coin_selection_params.m_effective_feerate);
1121 auto select_coins_res =
SelectCoins(
wallet, available_coins, preset_inputs, selection_target, coin_control, coin_selection_params);
1122 if (!select_coins_res) {
1130 const CAmount change_amount = result.
GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
1131 if (change_amount > 0) {
1132 CTxOut newTxOut(change_amount, scriptChange);
1133 if (nChangePosInOut == -1) {
1135 nChangePosInOut = rng_fast.
randrange(txNew.
vout.size() + 1);
1136 }
else if ((
unsigned int)nChangePosInOut > txNew.
vout.size()) {
1137 return util::Error{
_(
"Transaction change output index out of range")};
1139 txNew.
vout.insert(txNew.
vout.begin() + nChangePosInOut, newTxOut);
1141 nChangePosInOut = -1;
1156 for (
const auto& coin : selected_coins) {
1157 txNew.
vin.emplace_back(coin->outpoint,
CScript(), nSequence);
1163 int nBytes = tx_sizes.vsize;
1165 return util::Error{
_(
"Missing solving data for estimating transaction size")};
1169 Assume(recipients_sum + change_amount == output_value);
1173 if (current_fee < 0) {
1178 if (nChangePosInOut != -1 && fee_needed < current_fee) {
1179 auto& change = txNew.
vout.at(nChangePosInOut);
1180 change.nValue += current_fee - fee_needed;
1182 if (fee_needed != current_fee) {
1188 if (coin_selection_params.m_subtract_fee_outputs) {
1189 CAmount to_reduce = fee_needed - current_fee;
1192 for (
const auto& recipient : vecSend)
1194 if (i == nChangePosInOut) {
1199 if (recipient.fSubtractFeeFromAmount)
1201 txout.
nValue -= to_reduce / outputs_to_subtract_fee_from;
1206 txout.
nValue -= to_reduce % outputs_to_subtract_fee_from;
1212 return util::Error{
_(
"The transaction amount is too small to pay the fee")};
1214 return util::Error{
_(
"The transaction amount is too small to send after the fee has been deducted")};
1221 if (fee_needed != current_fee) {
1228 if (fee_needed > current_fee) {
1233 if (scriptChange.
empty() && nChangePosInOut != -1) {
1237 if (sign && !
wallet.SignTransaction(txNew)) {
1251 if (current_fee >
wallet.m_default_max_tx_fee) {
1257 if (!
wallet.chain().checkChainLimits(tx)) {
1258 return util::Error{
_(
"Transaction has too long of a mempool chain")};
1267 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",
1280 const std::vector<CRecipient>& vecSend,
1285 if (vecSend.empty()) {
1286 return util::Error{
_(
"Transaction must have at least one recipient")};
1289 if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](
const auto& recipient){
return recipient.nAmount < 0; })) {
1290 return util::Error{
_(
"Transaction amounts must not be negative")};
1296 TRACE4(coin_selection, normal_create_tx_internal,
wallet.GetName().c_str(), bool(res),
1297 res ? res->fee : 0, res ? res->change_pos : 0);
1298 if (!res)
return res;
1299 const auto& txr_ungrouped = *res;
1302 TRACE1(coin_selection, attempting_aps_create_tx,
wallet.GetName().c_str());
1307 const int ungrouped_change_pos = txr_ungrouped.change_pos;
1308 if (ungrouped_change_pos != -1) {
1309 ExtractDestination(txr_ungrouped.tx->vout[ungrouped_change_pos].scriptPubKey, tmp_cc.destChange);
1314 const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee) :
false};
1315 TRACE5(coin_selection, aps_create_tx_internal,
wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
1316 txr_grouped.has_value() ? txr_grouped->fee : 0, txr_grouped.has_value() ? txr_grouped->change_pos : 0);
1318 wallet.WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n",
1319 txr_ungrouped.fee, txr_grouped->fee, use_aps ?
"grouped" :
"non-grouped");
1320 if (use_aps)
return txr_grouped;
1328 std::vector<CRecipient> vecSend;
1331 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
1335 CRecipient recipient = {dest, txOut.
nValue, setSubtractFeeFromOutputs.count(idx) == 1};
1336 vecSend.push_back(recipient);
1345 std::map<COutPoint, Coin> coins;
1349 wallet.chain().findCoins(coins);
1352 const auto& outPoint = txin.
prevout;
1353 if (
wallet.IsMine(outPoint)) {
1355 coinControl.
Select(outPoint);
1356 }
else if (coins[outPoint].
out.IsNull()) {
1357 error =
_(
"Unable to find UTXO for external input");
1370 const auto& txr = *res;
1373 nChangePosInOut = txr.change_pos;
1375 if (nChangePosInOut != -1) {
1376 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
1381 for (
unsigned int idx = 0; idx < tx.
vout.size(); idx++) {
1382 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
1386 for (
const CTxIn& txin : tx_new->vin) {
1388 tx.
vin.push_back(txin);
std::shared_ptr< const CTransaction > CTransactionRef
void Shuffle(FastRandomContext &rng_fast)
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.
util::Result< SelectionResult > SelectCoinsSRD(const std::vector< OutputGroup > &utxo_pool, CAmount target_value, CAmount change_fee, FastRandomContext &rng, int max_weight)
Select coins by Single Random Draw.
std::optional< CTxOut > GetExternalOutput(const COutPoint &outpoint) const
Returns the external output for the given outpoint if it exists.
COutPoint outpoint
The outpoint identifying this UTXO.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
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.
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size
std::map< OutputType, Groups > groups_by_type
static const int WITNESS_SCALE_FACTOR
Stores several 'Groups' whose were mapped by output type.
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
size_t Size() const
The following methods are provided so that CoinsResult can mimic a vector, i.e., methods can work wit...
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
std::vector< COutput > All() const
Concatenate and return all COutputs as one vector.
util::Result< SelectionResult > SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change, int max_weight)
std::optional< CAmount > total_effective_amount
Sum of all available coins effective value (each output value minus fees required to spend it) ...
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
void AddInputs(const std::set< std::shared_ptr< COutput >> &inputs, bool subtract_fee_outputs)
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().
const CTxOut & FindNonChangeParentOutput(const CWallet &wallet, const COutPoint &outpoint)
Find non-change parent output.
virtual bool isInitialBlockDownload()=0
Check if in IBD.
util::Result< SelectionResult > ChooseSelectionResult(interfaces::Chain &chain, const CAmount &nTargetValue, Groups &groups, const CoinSelectionParams &coin_selection_params)
Attempt to find a valid input set that meets the provided eligibility filter and target.
#define CHECK_NONFATAL(condition)
Identity function.
CoinsResult AvailableCoinsListUnspent(const CWallet &wallet, const CCoinControl *coinControl, CoinFilterParams params)
Wrapper function for AvailableCoins which skips the feerate and CoinFilterParams::only_spendable para...
CAmount CalculateOutputValue(const TxType &tx)
CFeeRate GetDiscardRate(const CWallet &wallet)
Return the maximum feerate for discarding change.
void ApplyBumpFee(CAmount bump_fee)
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
std::optional< CAmount > GetEffectiveTotalAmount()
Use sat/vB fee rate unit.
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)
static bool HasErrorMsg(const util::Result< SelectionResult > &res)
void AddProvider(std::unique_ptr< SigningProvider > provider)
CAmount GetChange(const CAmount min_viable_change, const CAmount change_fee) const
Get the amount for the change output after paying needed fees.
void SelectExternal(const COutPoint &outpoint, const CTxOut &txout)
Lock-in the given output as an external input for spending because it is not in the wallet...
bool IsSelected(const COutPoint &output) const
Returns true if the given output is pre-selected.
static int32_t GetTransactionWeight(const CTransaction &tx)
bool HasSelected() const
Returns true if there are pre-selected inputs.
const std::vector< CTxIn > vin
int64_t GetTxTime() const
size_t GetSerializeSize(const T &t, int nVersion=0)
CAmount GetTarget() const
void Select(const COutPoint &output)
Lock-in the given output for spending.
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
Returns the input weight.
bool include_immature_coinbase
CFeeRate m_effective_feerate
The targeted feerate of the transaction being built.
CAmount total_amount
Sum of all available coins raw value.
CAmount GetTotalBumpFees() const
static constexpr uint32_t MAX_BIP125_RBF_SEQUENCE
CAmount m_min_change_target
Mininmum change to target in Knapsack solver: select coins to cover the payment and at least this val...
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
std::vector< OutputGroup > positive_group
An input of a transaction.
SelectionAlgorithm GetAlgo() const
int CalculateMaximumSignedInputSize(const CTxOut &txout, const COutPoint outpoint, const SigningProvider *provider, bool can_grind_r, const CCoinControl *coin_control)
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', call 'AutomaticCoinSelection' to select a set of coins such that nTargetValue - pre_set_inputs.total_amount is met.
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)
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
#define TRACE4(context, event, a, b, c, d)
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
const std::vector< CTxOut > vout
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
static std::optional< int64_t > MaxInputWeight(const Descriptor &desc, const std::optional< CTxIn > &txin, const CCoinControl *coin_control, const bool tx_is_segwit, const bool can_grind_r)
Get the size of an input (in witness units) once it's signed.
CAmount m_cost_of_change
Cost of creating the change output + cost of spending the change output in the future.
util::Result< SelectionResult > KnapsackSolver(std::vector< OutputGroup > &groups, const CAmount &nTargetValue, CAmount change_target, FastRandomContext &rng, int max_weight)
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
A signing provider to be used to interface with multiple signing providers at once.
bool IsExternalSelected(const COutPoint &output) const
Returns true if the given output is selected as an external input.
virtual std::optional< CAmount > CalculateCombinedBumpFee(const std::vector< COutPoint > &outpoints, const CFeeRate &target_feerate)=0
Calculate the combined bump fee for an input set per the same strategy.
An output of a transaction.
A group of UTXOs paid to the same output script.
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.
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)
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
#define Assume(val)
Assume is the identity function.
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.
size_t tx_noinputs_size
Size of the transaction before coin selection, consisting of the header and recipient output(s)...
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.
size_t change_output_size
Size of a change output in bytes, determined by the output type.
static bool UseMaxSig(const std::optional< CTxIn > &txin, const CCoinControl *coin_control)
Whether to assume ECDSA signatures' will be high-r.
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee rate considering user set parameters and the required fee.
util::Result< SelectionResult > AutomaticCoinSelection(const CWallet &wallet, CoinsResult &available_coins, const CAmount &value_to_select, const CoinSelectionParams &coin_selection_params)
Select a set of coins such that nTargetValue is met; never select unconfirmed coins if they are not o...
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
util::Result< SelectionResult > AttemptSelection(interfaces::Chain &chain, const CAmount &nTargetValue, OutputGroupTypeMap &groups, const CoinSelectionParams &coin_selection_params, bool allow_mixed_output_types)
Attempt to find a valid input set that preserves privacy by not mixing OutputTypes.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
const int DEFAULT_MAX_DEPTH
Parameters for filtering which OutputGroups we may use in coin selection.
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.
bool m_include_unsafe_inputs
When true, allow unsafe coins to be selected during Coin Selection.
std::vector< OutputGroup > mixed_group
const int DEFAULT_MIN_DEPTH
static constexpr int32_t MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int m_min_depth
Minimum chain depth value for coin availability.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
An interface to be implemented by keystores that support signing.
void Erase(const std::unordered_set< COutPoint, SaltedOutpointHasher > &coins_to_remove)
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
void KeepDestination()
Keep the address. Do not return its key to the keypool when this object goes out of scope...
bool error(const char *fmt, const Args &... args)
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 ...
static std::unique_ptr< Descriptor > GetDescriptor(const CWallet *wallet, const CCoinControl *coin_control, const CScript script_pubkey)
Infer a descriptor for the given output script.
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.
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.
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.
#define STR_INTERNAL_BUG(msg)
static const unsigned int LOCKTIME_THRESHOLD
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.
virtual std::optional< OutputType > GetOutputType() const =0
int64_t GetTime()
DEPRECATED, see GetTime.
A UTXO under consideration for use in funding a new transaction.
std::vector< std::shared_ptr< COutput > > GetShuffledInputVector() const
Get the vector of COutputs that will be used to fill in a CTransaction's vin.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX –...
static std::optional< int64_t > GetSignedTxinWeight(const CWallet *wallet, const CCoinControl *coin_control, const CTxIn &txin, const CTxOut &txo, const bool tx_is_segwit, const bool can_grind_r)
Infer the maximum size of this input after it will be signed.
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...
std::string StringForFeeReason(FeeReason reason)
FilteredOutputGroups GroupOutputs(const CWallet &wallet, const CoinsResult &coins, const CoinSelectionParams &coin_sel_params, const std::vector< SelectionFilter > &filters, std::vector< OutputGroup > &ret_discarded_groups)
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
Returns true if the input weight is set.
CAmount m_change_fee
Cost of creating the change output.
Interface for parsed descriptor objects.
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
#define Assert(val)
Identity function.
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS
Default for -walletrejectlongchains.
std::map< CoinEligibilityFilter, OutputGroupTypeMap > FilteredOutputGroups