63 const CCoinControl* coin_control,
const bool tx_is_segwit,
64 const bool can_grind_r) {
67 const bool is_segwit =
IsSegwit(desc);
75 const int64_t witstack_len = is_segwit ?
GetSizeOfCompactSize(*elems_count) : (tx_is_segwit ? 1 : 0);
87 if (!provider)
return -1;
90 if (
const auto weight =
MaxInputWeight(*desc, {}, coin_control,
true, can_grind_r)) {
100 const std::unique_ptr<SigningProvider> provider =
wallet->GetSolvingProvider(txout.
scriptPubKey);
109 for (
const auto spkman:
wallet->GetScriptPubKeyMans(script_pubkey)) {
110 providers.
AddProvider(spkman->GetSolvingProvider(script_pubkey));
120 const CTxIn& txin,
const CTxOut& txo,
const bool tx_is_segwit,
121 const bool can_grind_r)
124 std::optional<int64_t> weight;
126 return weight.value();
131 if (desc)
return MaxInputWeight(*desc, {txin}, coin_control, tx_is_segwit, can_grind_r);
143 bool is_segwit = std::any_of(txouts.begin(), txouts.end(), [&](
const CTxOut& txo) {
149 if (is_segwit) weight += 2;
155 for (uint32_t i = 0; i < txouts.size(); i++) {
157 if (!txin_weight)
return TxSize{-1, -1};
158 assert(*txin_weight > -1);
159 weight += *txin_weight;
168 std::vector<CTxOut> txouts;
173 if (mi !=
wallet->mapWallet.end()) {
175 txouts.emplace_back(mi->second.tx->vout.at(input.
prevout.
n));
176 }
else if (coin_control) {
178 if (!txout)
return TxSize{-1, -1};
179 txouts.emplace_back(*txout);
190 for (
const auto& it :
coins) {
191 size += it.second.size();
198 std::vector<COutput> all;
199 all.reserve(
coins.size());
200 for (
const auto& it :
coins) {
201 all.insert(all.end(), it.second.begin(), it.second.end());
212 for (
auto& [type, vec] :
coins) {
213 auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](
const COutput& coin) {
215 if (coins_to_remove.count(coin.outpoint) == 0)
return false;
222 vec.erase(remove_it, vec.end());
228 for (
auto& it :
coins) {
229 std::shuffle(it.second.begin(), it.second.end(), rng_fast);
237 if (
out.HasEffectiveValue()) {
266 const bool can_grind_r =
wallet.CanGrindR();
269 int64_t input_bytes = coin_control.
GetInputWeight(outpoint).value_or(-1);
270 if (input_bytes != -1) {
274 if (
auto ptr_wtx =
wallet.GetWalletTx(outpoint.hash)) {
276 if (ptr_wtx->tx->vout.size() <= outpoint.n) {
279 txout = ptr_wtx->tx->vout.at(outpoint.n);
280 if (input_bytes == -1) {
293 if (input_bytes == -1) {
297 if (input_bytes == -1) {
311 std::optional<CFeeRate> feerate,
323 const bool can_grind_r =
wallet.CanGrindR();
324 std::vector<COutPoint> outpoints;
326 std::set<uint256> trusted_parents;
327 for (
const auto& entry :
wallet.mapWallet)
329 const uint256& txid = entry.first;
335 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
361 if (nDepth == 0 && wtx.
mapValue.count(
"replaces_txid")) {
373 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
377 if (only_safe && !safeTx) {
381 if (nDepth < min_depth || nDepth > max_depth) {
387 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
388 const CTxOut& output = wtx.
tx->vout[i];
401 if (
wallet.IsSpent(outpoint))
414 std::unique_ptr<SigningProvider> provider =
wallet.GetSolvingProvider(output.
scriptPubKey);
419 bool solvable = input_bytes > -1;
426 std::vector<std::vector<uint8_t>> script_solutions;
433 bool is_from_p2sh{
false};
442 COutput(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.
GetTxTime(), tx_from_me, feerate));
444 outpoints.push_back(outpoint);
460 if (feerate.has_value()) {
461 std::map<COutPoint, CAmount> map_of_bump_fees =
wallet.chain().calculateIndividualBumpFees(outpoints, feerate.value());
463 for (
auto& [
_, outputs] : result.
coins) {
464 for (
auto& output : outputs) {
465 output.ApplyBumpFee(map_of_bump_fees.at(output.outpoint));
489 if (!it || it->
tx->vout.size() <= prevout.
n ||
490 !
wallet.IsMine(it->
tx->vout[prevout.
n])) {
503 std::map<CTxDestination, std::vector<COutput>> result;
516 if (
auto pk_dest = std::get_if<PubKeyDestination>(&address)) {
517 address =
PKHash(pk_dest->GetPubKey());
522 result[address].emplace_back(coin);
531 const std::vector<SelectionFilter>& filters,
532 std::vector<OutputGroup>& ret_discarded_groups)
538 for (
const auto& [type, outputs] : coins.
coins) {
539 for (
const COutput& output : outputs) {
541 size_t ancestors, descendants;
542 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
546 group.Insert(std::make_shared<COutput>(output), ancestors, descendants);
549 bool accepted =
false;
550 for (
const auto& sel_filter : filters) {
551 const auto& filter = sel_filter.filter;
552 if (!
group.EligibleForSpending(filter))
continue;
553 filtered_groups[filter].Push(
group, type,
true,
true);
556 if (!accepted) ret_discarded_groups.emplace_back(
group);
559 return filtered_groups;
568 typedef std::map<std::pair<CScript, OutputType>, std::vector<OutputGroup>> ScriptPubKeyToOutgroup;
569 const auto& insert_output = [&](
570 const std::shared_ptr<COutput>& output,
OutputType type,
size_t ancestors,
size_t descendants,
571 ScriptPubKeyToOutgroup& groups_map) {
572 std::vector<OutputGroup>& groups = groups_map[std::make_pair(output->txout.scriptPubKey,type)];
574 if (groups.size() == 0) {
576 groups.emplace_back(coin_sel_params);
587 groups.emplace_back(coin_sel_params);
588 group = &groups.back();
591 group->Insert(output, ancestors, descendants);
594 ScriptPubKeyToOutgroup spk_to_groups_map;
595 ScriptPubKeyToOutgroup spk_to_positive_groups_map;
596 for (
const auto& [type, outs] : coins.
coins) {
597 for (
const COutput& output : outs) {
598 size_t ancestors, descendants;
599 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
601 const auto& shared_output = std::make_shared<COutput>(output);
603 if (output.GetEffectiveValue() > 0) {
604 insert_output(shared_output, type, ancestors, descendants, spk_to_positive_groups_map);
608 insert_output(shared_output, type, ancestors, descendants, spk_to_groups_map);
613 const auto& push_output_groups = [&](
const ScriptPubKeyToOutgroup& groups_map,
bool positive_only) {
614 for (
const auto& [
script, groups] : groups_map) {
616 for (
auto group_it = groups.rbegin(); group_it != groups.rend(); group_it++) {
620 bool accepted =
false;
621 for (
const auto& sel_filter : filters) {
622 const auto& filter = sel_filter.filter;
623 if (!
group.EligibleForSpending(filter))
continue;
626 if (group_it == groups.rbegin() && groups.size() > 1 && !filter.m_include_partial_groups) {
632 filtered_groups[filter].Push(
group, type, positive_only, !positive_only);
635 if (!accepted) ret_discarded_groups.emplace_back(
group);
640 push_output_groups(spk_to_groups_map,
false);
641 push_output_groups(spk_to_positive_groups_map,
true);
643 return filtered_groups;
649 const std::vector<SelectionFilter>& filters)
651 std::vector<OutputGroup> unused;
662 std::vector<SelectionResult> results;
668 if (result) results.push_back(*result);
672 if (results.size() > 0)
return *std::min_element(results.begin(), results.end());
677 if (allow_mixed_output_types && groups.
TypesCount() > 1) {
688 std::vector<SelectionResult> results;
689 std::vector<util::Result<SelectionResult>> errors;
694 errors.emplace_back(std::move(result));
701 int max_selection_weight = max_transaction_weight - tx_weight_no_input;
702 if (max_selection_weight <= 0) {
703 return util::Error{
_(
"Maximum transaction weight is less than transaction weight without inputs")};
709 results.push_back(*bnb_result);
710 }
else append_error(std::move(bnb_result));
715 max_selection_weight -= change_outputs_weight;
716 if (max_selection_weight < 0 && results.empty()) {
717 return util::Error{
_(
"Maximum transaction weight is too low, can not accommodate change output")};
722 results.push_back(*knapsack_result);
723 }
else append_error(std::move(knapsack_result));
728 results.push_back(*cg_result);
730 append_error(std::move(cg_result));
735 results.push_back(*srd_result);
736 }
else append_error(std::move(srd_result));
738 if (results.empty()) {
741 return errors.empty() ?
util::Error() : std::move(errors.front());
745 for (
auto& result : results) {
746 std::vector<COutPoint> outpoints;
747 std::set<std::shared_ptr<COutput>> coins = result.GetInputSet();
749 for (
auto& coin : coins) {
750 if (coin->depth > 0)
continue;
751 outpoints.push_back(coin->outpoint);
752 summed_bump_fees += coin->ancestor_bump_fees;
755 if (!combined_bump_fee.has_value()) {
756 return util::Error{
_(
"Failed to calculate bump fees, because unconfirmed UTXOs depend on enormous cluster of unconfirmed transactions.")};
758 CAmount bump_fee_overestimate = summed_bump_fees - combined_bump_fee.value();
759 if (bump_fee_overestimate) {
760 result.SetBumpFeeDiscount(bump_fee_overestimate);
767 return *std::min_element(results.begin(), results.end());
779 return util::Error{
_(
"The preselected coins total amount does not cover the transaction target. " 780 "Please allow other inputs to be automatically selected or include more coins manually")};
784 if (selection_target <= 0) {
795 if (selection_target > available_coins_total_amount) {
801 if (!op_selection_result)
return op_selection_result;
804 if (!pre_set_inputs.
coins.empty()) {
807 op_selection_result->Merge(preselected);
814 if (op_selection_result->GetWeight() > max_inputs_weight) {
815 return util::Error{
_(
"The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. " 816 "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")};
819 return op_selection_result;
824 unsigned int limit_ancestor_count = 0;
825 unsigned int limit_descendant_count = 0;
826 wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
827 const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
828 const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
843 std::vector<SelectionFilter> ordered_filters{
851 if (
wallet.m_spend_zero_conf_change) {
853 ordered_filters.push_back({
CoinEligibilityFilter(0, 1, std::min(
size_t{4}, max_ancestors/3), std::min(
size_t{4}, max_descendants/3))});
867 if (!fRejectLongChains) {
869 std::numeric_limits<uint64_t>::max(),
875 std::vector<OutputGroup> discarded_groups;
880 CAmount total_unconf_long_chain = 0;
881 for (
const auto&
group : discarded_groups) {
882 total_discarded +=
group.GetSelectionAmount();
883 if (
group.m_ancestors >= max_ancestors ||
group.m_descendants >= max_descendants) total_unconf_long_chain +=
group.GetSelectionAmount();
888 if (total_amount + total_unconf_long_chain > value_to_select) {
889 return util::Error{
_(
"Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool")};
897 std::vector<util::Result<SelectionResult>> res_detailed_errors;
898 for (
const auto& select_filter : ordered_filters) {
899 auto it = filtered_groups.find(select_filter.filter);
900 if (it == filtered_groups.end())
continue;
902 coin_selection_params, select_filter.allow_mixed_output_types)}) {
908 if (
HasErrorMsg(res)) res_detailed_errors.emplace_back(std::move(res));
913 if (!res_detailed_errors.empty())
return std::move(res_detailed_errors.front());
926 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
929 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
983 for (
const auto& in : tx.
vin) {
1007 const std::vector<CRecipient>& vecSend,
1008 std::optional<unsigned int> change_pos,
1017 if (coin_control.m_version) {
1018 txNew.
version = coin_control.m_version.value();
1022 coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
1023 coin_selection_params.m_include_unsafe_inputs = coin_control.m_include_unsafe_inputs;
1026 if (coin_selection_params.m_max_tx_weight.value() < minimum_tx_weight || coin_selection_params.m_max_tx_weight.value() >
MAX_STANDARD_TX_WEIGHT) {
1030 coin_selection_params.m_long_term_feerate =
wallet.m_consolidate_feerate;
1035 const OutputType change_type =
wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type :
wallet.m_default_change_type, vecSend);
1037 unsigned int outputs_to_subtract_fee_from = 0;
1038 for (
const auto& recipient : vecSend) {
1039 if (
IsDust(recipient,
wallet.chain().relayDustFee())) {
1045 recipients_sum += recipient.nAmount;
1047 if (recipient.fSubtractFeeFromAmount) {
1048 outputs_to_subtract_fee_from++;
1049 coin_selection_params.m_subtract_fee_outputs =
true;
1058 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
1083 CTxOut change_prototype_txout(0, scriptChange);
1084 coin_selection_params.change_output_size =
GetSerializeSize(change_prototype_txout);
1090 if (change_spend_size == -1) {
1093 coin_selection_params.change_spend_size = change_spend_size;
1104 if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
1109 return util::Error{
strprintf(
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s."),
"-fallbackfee")};
1117 coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
1118 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;
1120 coin_selection_params.m_min_change_target =
GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
1125 const auto dust =
GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
1126 const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
1127 coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
1130 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);
1131 CAmount selection_target = recipients_sum + not_input_fees;
1135 if (selection_target == 0 && !coin_control.HasSelected()) {
1136 return util::Error{
_(
"Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input")};
1141 if (coin_control.HasSelected()) {
1144 preset_inputs = *res_fetch_inputs;
1150 if (coin_control.m_allow_other_inputs) {
1151 available_coins =
AvailableCoins(
wallet, &coin_control, coin_selection_params.m_effective_feerate);
1155 auto select_coins_res =
SelectCoins(
wallet, available_coins, preset_inputs, selection_target, coin_control, coin_selection_params);
1156 if (!select_coins_res) {
1162 TRACE5(coin_selection, selected_coins,
1163 wallet.GetName().c_str(),
1170 for (
const auto& recipient : vecSend)
1174 const CAmount change_amount = result.
GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
1175 if (change_amount > 0) {
1176 CTxOut newTxOut(change_amount, scriptChange);
1180 }
else if ((
unsigned int)*change_pos > txNew.
vout.size()) {
1181 return util::Error{
_(
"Transaction change output index out of range")};
1183 txNew.
vout.insert(txNew.
vout.begin() + *change_pos, newTxOut);
1185 change_pos = std::nullopt;
1191 if (coin_control.HasSelected() && coin_control.HasSelectedOrder()) {
1196 std::stable_sort(selected_coins.begin(), selected_coins.end(),
1197 [&coin_control](
const std::shared_ptr<COutput>& a,
const std::shared_ptr<COutput>& b) {
1198 auto a_pos = coin_control.GetSelectionPos(a->outpoint);
1199 auto b_pos = coin_control.GetSelectionPos(b->outpoint);
1200 if (a_pos.has_value() && b_pos.has_value()) {
1201 return a_pos.value() < b_pos.value();
1202 }
else if (a_pos.has_value() && !b_pos.has_value()) {
1218 bool use_anti_fee_sniping =
true;
1220 for (
const auto& coin : selected_coins) {
1221 std::optional<uint32_t>
sequence = coin_control.GetSequence(coin->outpoint);
1224 use_anti_fee_sniping =
false;
1226 txNew.
vin.emplace_back(coin->outpoint,
CScript{},
sequence.value_or(default_sequence));
1228 auto scripts = coin_control.GetScripts(coin->outpoint);
1229 if (scripts.first) {
1230 txNew.
vin.back().scriptSig = *scripts.first;
1232 if (scripts.second) {
1233 txNew.
vin.back().scriptWitness = *scripts.second;
1236 if (coin_control.m_locktime) {
1237 txNew.
nLockTime = coin_control.m_locktime.value();
1239 use_anti_fee_sniping =
false;
1241 if (use_anti_fee_sniping) {
1247 int nBytes = tx_sizes.
vsize;
1249 return util::Error{
_(
"Missing solving data for estimating transaction size")};
1253 Assume(recipients_sum + change_amount == output_value);
1257 if (current_fee < 0) {
1262 if (change_pos && fee_needed < current_fee) {
1263 auto& change = txNew.
vout.at(*change_pos);
1264 change.nValue += current_fee - fee_needed;
1266 if (fee_needed != current_fee) {
1272 if (coin_selection_params.m_subtract_fee_outputs) {
1273 CAmount to_reduce = fee_needed - current_fee;
1276 for (
const auto& recipient : vecSend)
1278 if (change_pos && i == *change_pos) {
1283 if (recipient.fSubtractFeeFromAmount)
1285 txout.
nValue -= to_reduce / outputs_to_subtract_fee_from;
1290 txout.
nValue -= to_reduce % outputs_to_subtract_fee_from;
1296 return util::Error{
_(
"The transaction amount is too small to pay the fee")};
1298 return util::Error{
_(
"The transaction amount is too small to send after the fee has been deducted")};
1305 if (fee_needed != current_fee) {
1312 if (fee_needed > current_fee) {
1317 if (scriptChange.
empty() && change_pos) {
1321 if (sign && !
wallet.SignTransaction(txNew)) {
1335 if (current_fee >
wallet.m_default_max_tx_fee) {
1341 auto result =
wallet.chain().checkChainLimits(tx);
1352 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",
1365 const std::vector<CRecipient>& vecSend,
1366 std::optional<unsigned int> change_pos,
1370 if (vecSend.empty()) {
1371 return util::Error{
_(
"Transaction must have at least one recipient")};
1374 if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](
const auto& recipient){
return recipient.nAmount < 0; })) {
1375 return util::Error{
_(
"Transaction amounts must not be negative")};
1381 TRACE4(coin_selection, normal_create_tx_internal,
1382 wallet.GetName().c_str(),
1385 res && res->change_pos.has_value() ? int32_t(*res->change_pos) : -1);
1386 if (!res)
return res;
1387 const auto& txr_ungrouped = *res;
1390 TRACE1(coin_selection, attempting_aps_create_tx,
wallet.GetName().c_str());
1395 if (txr_ungrouped.change_pos) {
1396 ExtractDestination(txr_ungrouped.tx->vout[*txr_ungrouped.change_pos].scriptPubKey, tmp_cc.destChange);
1401 const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee) :
false};
1402 TRACE5(coin_selection, aps_create_tx_internal,
1403 wallet.GetName().c_str(),
1405 txr_grouped.has_value(),
1406 txr_grouped.has_value() ? txr_grouped->fee : 0,
1407 txr_grouped.has_value() && txr_grouped->change_pos.has_value() ? int32_t(*txr_grouped->change_pos) : -1);
1409 wallet.WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n",
1410 txr_ungrouped.fee, txr_grouped->fee, use_aps ?
"grouped" :
"non-grouped");
1411 if (use_aps)
return txr_grouped;
1435 std::map<COutPoint, Coin> coins;
1439 wallet.chain().findCoins(coins);
1442 const auto& outPoint = txin.
prevout;
1444 if (!
wallet.IsMine(outPoint)) {
1445 if (coins[outPoint].
out.IsNull()) {
1446 return util::Error{
_(
"Unable to find UTXO for external input")};
1463 for (
const CTxIn& txin : res->tx->vin) {
std::shared_ptr< const CTransaction > CTransactionRef
void Shuffle(FastRandomContext &rng_fast)
Helper for findBlock to selectively return pieces of block data.
std::optional< CTxOut > GetExternalOutput(const COutPoint &outpoint) const
Returns the external output for the given outpoint if it exists.
void RecalculateWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee)
Calculates and stores the waste for this result given the cost of change and the opportunity cost of ...
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.
util::Result< SelectionResult > KnapsackSolver(std::vector< OutputGroup > &groups, const CAmount &nTargetValue, CAmount change_target, FastRandomContext &rng, int max_selection_weight)
CAmount min_viable_change
Minimum amount for creating a change output.
mapValue_t mapValue
Key/value map with information about the transaction.
std::optional< uint32_t > m_locktime
Locktime.
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...
int tx_noinputs_size
Size of the transaction before coin selection, consisting of the header and recipient output(s)...
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
std::string StringForFeeReason(FeeReason reason)
is a home for simple string functions returning descriptive messages that are used in RPC and GUI int...
std::vector< COutput > All() const
Concatenate and return all COutputs as one vector.
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.
CScriptWitness scriptWitness
Only serialized through CTransaction.
void AddInputs(const std::set< std::shared_ptr< COutput >> &inputs, bool subtract_fee_outputs)
size_t GetSerializeSize(const T &t)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
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.
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs...
std::optional< uint32_t > m_version
Version.
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.
static int32_t GetTransactionWeight(const CTransaction &tx)
bool HasSelected() const
Returns true if there are pre-selected inputs.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
bilingual_str TransactionErrorString(const TransactionError err)
const std::vector< CTxIn > vin
util::Result< SelectionResult > CoinGrinder(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, CAmount change_target, int max_selection_weight)
int64_t GetTxTime() const
int change_output_size
Size of a change output in bytes, determined by the output type.
CAmount GetTarget() const
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.
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 and CoinGrinder: select coins to cover the payment and a...
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
std::vector< OutputGroup > positive_group
An input of a transaction.
util::Result< CreatedTransactionResult > CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, std::optional< unsigned 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 > SelectCoinsSRD(const std::vector< OutputGroup > &utxo_pool, CAmount target_value, CAmount change_fee, FastRandomContext &rng, int max_selection_weight)
Select coins by Single Random Draw.
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.
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
bool IsDust(const CRecipient &recipient, const CFeeRate &dustRelayFee)
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.
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.
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.
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.
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
util::Result< SelectionResult > SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change, int max_selection_weight)
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
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.
const int DEFAULT_MAX_DEPTH
Parameters for filtering which OutputGroups we may use in coin selection.
size_t GetSerializeSizeForRecipient(const CRecipient &recipient)
util::Result< PreSelectedInputs > FetchSelectedInputs(const CWallet &wallet, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params)
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.
std::optional< int > m_max_tx_weight
The maximum weight for this transaction.
static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int m_min_depth
Minimum chain depth value for coin availability.
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...
Serialized script, used inside transaction inputs and outputs.
static transaction_identifier FromUint256(const uint256 &id)
CreatedTransactionResult FundTransaction(CWallet &wallet, const CMutableTransaction &tx, const std::vector< CRecipient > &recipients, const UniValue &options, CCoinControl &coinControl, bool override_min_fee)
std::optional< int64_t > GetInputWeight(const COutPoint &outpoint) const
Returns the input weight.
static constexpr unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE
The minimum non-witness size for transactions we're willing to relay/mine: one larger than 64...
bool m_include_unsafe_inputs
If false, only safe inputs will be used.
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 ...
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
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.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
bilingual_str ErrorString(const Result< T > &result)
A reference to a CScript: the Hash160 of its serialization.
A mutable version of CTransaction.
bool IsExternalSelected(const COutPoint &outpoint) const
Returns true if the given output is selected as an external input.
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
static util::Result< CreatedTransactionResult > CreateTransactionInternal(CWallet &wallet, const std::vector< CRecipient > &vecSend, std::optional< unsigned int > change_pos, const CCoinControl &coin_control, bool sign) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
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
is a home for public enum and struct type definitions that are used by internally by node code...
int64_t GetTime()
DEPRECATED, see GetTime.
A UTXO under consideration for use in funding a new transaction.
bool IsSelected(const COutPoint &outpoint) const
Returns true if the given output is pre-selected.
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 – 5 ...
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...
bilingual_str _(ConstevalStringLiteral str)
Translation function.
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)
std::vector< COutPoint > ListSelected() const
List the selected inputs.
PreselectedInput & Select(const COutPoint &outpoint)
Lock-in the given output for spending.
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