70 const CCoinControl* coin_control,
const bool tx_is_segwit,
71 const bool can_grind_r) {
74 const bool is_segwit =
IsSegwit(desc);
82 const int64_t witstack_len = is_segwit ?
GetSizeOfCompactSize(*elems_count) : (tx_is_segwit ? 1 : 0);
94 if (!provider)
return -1;
97 if (
const auto weight =
MaxInputWeight(*desc, {}, coin_control,
true, can_grind_r)) {
107 const std::unique_ptr<SigningProvider> provider =
wallet->GetSolvingProvider(txout.
scriptPubKey);
116 for (
const auto spkman:
wallet->GetScriptPubKeyMans(script_pubkey)) {
117 providers.
AddProvider(spkman->GetSolvingProvider(script_pubkey));
127 const CTxIn& txin,
const CTxOut& txo,
const bool tx_is_segwit,
128 const bool can_grind_r)
131 std::optional<int64_t> weight;
133 return weight.value();
138 if (desc)
return MaxInputWeight(*desc, {txin}, coin_control, tx_is_segwit, can_grind_r);
150 bool is_segwit = std::any_of(txouts.begin(), txouts.end(), [&](
const CTxOut& txo) {
151 std::unique_ptr<Descriptor> desc{GetDescriptor(wallet, coin_control, txo.scriptPubKey)};
156 if (is_segwit) weight += 2;
162 for (uint32_t i = 0; i < txouts.size(); i++) {
164 if (!txin_weight)
return TxSize{-1, -1};
165 assert(*txin_weight > -1);
166 weight += *txin_weight;
175 std::vector<CTxOut> txouts;
180 if (mi !=
wallet->mapWallet.end()) {
182 txouts.emplace_back(mi->second.tx->vout.at(input.
prevout.
n));
183 }
else if (coin_control) {
185 if (!txout)
return TxSize{-1, -1};
186 txouts.emplace_back(*txout);
194size_t CoinsResult::Size()
const
197 for (
const auto& it : coins) {
198 size += it.second.size();
203std::vector<COutput> CoinsResult::All()
const
205 std::vector<COutput> all;
206 all.reserve(coins.size());
207 for (
const auto& it : coins) {
208 all.insert(all.end(), it.second.begin(), it.second.end());
213void CoinsResult::Clear() {
217void CoinsResult::Erase(
const std::unordered_set<COutPoint, SaltedOutpointHasher>& coins_to_remove)
219 for (
auto& [type, vec] : coins) {
220 auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](
const COutput& coin) {
222 if (!coins_to_remove.contains(coin.outpoint)) return false;
225 total_amount -= coin.txout.nValue;
226 if (coin.HasEffectiveValue()) total_effective_amount = *total_effective_amount - coin.GetEffectiveValue();
229 vec.erase(remove_it, vec.end());
235 for (
auto& it : coins) {
236 std::shuffle(it.second.begin(), it.second.end(), rng_fast);
242 coins[type].emplace_back(
out);
243 total_amount +=
out.txout.nValue;
244 if (
out.HasEffectiveValue()) {
245 total_effective_amount = total_effective_amount.has_value() ?
246 *total_effective_amount +
out.GetEffectiveValue() :
out.GetEffectiveValue();
273 const bool can_grind_r =
wallet.CanGrindR();
276 int64_t input_bytes = coin_control.
GetInputWeight(outpoint).value_or(-1);
277 if (input_bytes != -1) {
281 if (
auto txo =
wallet.GetTXO(outpoint)) {
282 txout = txo->GetTxOut();
283 if (input_bytes == -1) {
286 const CWalletTx& parent_tx = txo->GetWalletTx();
287 if (
wallet.GetTxDepthInMainChain(parent_tx) == 0) {
291 return util::Error{
strprintf(
_(
"Can't spend unconfirmed version %d pre-selected input with a version 3 tx"), parent_tx.
tx->version)};
304 if (input_bytes == -1) {
308 if (input_bytes == -1) {
322 std::optional<CFeeRate> feerate,
329 std::vector<std::pair<OutputType, COutput>> unconfirmed_truc_coins;
330 std::unordered_map<Txid, CAmount, SaltedTxidHasher> truc_txid_by_value;
337 const bool can_grind_r =
wallet.CanGrindR();
338 std::vector<COutPoint> outpoints;
340 std::set<Txid> trusted_parents;
342 std::unordered_map<Txid, std::pair<bool, bool>,
SaltedTxidHasher> tx_safe_cache;
343 for (
const auto& [outpoint, txo] :
wallet.GetTXOs()) {
344 const CWalletTx& wtx = txo.GetWalletTx();
345 const CTxOut& output = txo.GetTxOut();
347 if (tx_safe_cache.contains(outpoint.hash) && !tx_safe_cache.at(outpoint.hash).first) {
351 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
354 if (!tx_safe_cache.contains(outpoint.hash)) {
355 tx_safe_cache[outpoint.hash] = {
false,
false};
385 if (nDepth == 0 && wtx.
mapValue.contains(
"replaces_txid")) {
397 if (nDepth == 0 && wtx.
mapValue.contains(
"replaced_by_txid")) {
408 size_t ancestors, descendants;
409 wallet.chain().getTransactionAncestry(wtx.
tx->GetHash(), ancestors, descendants);
410 if (ancestors > 1)
continue;
416 if (only_safe && !safeTx) {
420 if (nDepth < min_depth || nDepth > max_depth) {
424 tx_safe_cache[outpoint.hash] = {
true, safeTx};
426 const auto& [tx_ok, tx_safe] = tx_safe_cache.at(outpoint.hash);
441 if (
wallet.IsSpent(outpoint))
450 std::unique_ptr<SigningProvider> provider =
wallet.GetSolvingProvider(output.
scriptPubKey);
455 bool solvable = input_bytes > -1;
458 std::vector<std::vector<uint8_t>> script_solutions;
465 bool is_from_p2sh{
false};
473 auto available_output_type =
GetOutputType(type, is_from_p2sh);
474 auto available_output =
COutput(outpoint, output, nDepth, input_bytes, solvable, tx_safe, wtx.
GetTxTime(), tx_from_me, feerate);
476 unconfirmed_truc_coins.emplace_back(available_output_type, available_output);
477 auto [it,
_] = truc_txid_by_value.try_emplace(wtx.
tx->GetHash(), 0);
478 it->second += output.
nValue;
480 result.
Add(available_output_type, available_output);
483 outpoints.push_back(outpoint);
503 auto highest_value_truc_tx = std::max_element(truc_txid_by_value.begin(), truc_txid_by_value.end(), [](
const auto& tx1,
const auto& tx2){
504 return tx1.second < tx2.second;
507 const Txid& truc_txid = highest_value_truc_tx->first;
508 for (
const auto& [type, output] : unconfirmed_truc_coins) {
509 if (output.outpoint.hash == truc_txid) {
510 result.
Add(type, output);
515 if (feerate.has_value()) {
516 std::map<COutPoint, CAmount> map_of_bump_fees =
wallet.chain().calculateIndividualBumpFees(outpoints, feerate.value());
518 for (
auto& [
_, outputs] : result.
coins) {
519 for (
auto& output : outputs) {
520 output.ApplyBumpFee(map_of_bump_fees.at(output.outpoint));
538 if (!it || it->
tx->vout.size() <= prevout.
n ||
539 !
wallet.IsMine(it->
tx->vout[prevout.
n])) {
552 std::map<CTxDestination, std::vector<COutput>> result;
561 if (
auto pk_dest = std::get_if<PubKeyDestination>(&address)) {
562 address =
PKHash(pk_dest->GetPubKey());
567 result[address].emplace_back(coin);
575 const std::vector<SelectionFilter>& filters,
576 std::vector<OutputGroup>& ret_discarded_groups)
582 for (
const auto& [type, outputs] : coins.
coins) {
583 for (
const COutput& output : outputs) {
585 size_t ancestors, descendants;
586 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
590 group.Insert(std::make_shared<COutput>(output), ancestors, descendants);
593 bool accepted =
false;
594 for (
const auto& sel_filter : filters) {
595 const auto& filter = sel_filter.filter;
596 if (!
group.EligibleForSpending(filter))
continue;
597 filtered_groups[filter].Push(
group, type,
true,
true);
600 if (!accepted) ret_discarded_groups.emplace_back(
group);
603 return filtered_groups;
612 typedef std::map<std::pair<CScript, OutputType>, std::vector<OutputGroup>> ScriptPubKeyToOutgroup;
613 const auto& insert_output = [&](
614 const std::shared_ptr<COutput>& output,
OutputType type,
size_t ancestors,
size_t descendants,
615 ScriptPubKeyToOutgroup& groups_map) {
616 std::vector<OutputGroup>& groups = groups_map[std::make_pair(output->txout.scriptPubKey,type)];
618 if (groups.size() == 0) {
620 groups.emplace_back(coin_sel_params);
631 groups.emplace_back(coin_sel_params);
632 group = &groups.back();
635 group->Insert(output, ancestors, descendants);
638 ScriptPubKeyToOutgroup spk_to_groups_map;
639 ScriptPubKeyToOutgroup spk_to_positive_groups_map;
640 for (
const auto& [type, outs] : coins.
coins) {
641 for (
const COutput& output : outs) {
642 size_t ancestors, descendants;
643 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
645 const auto& shared_output = std::make_shared<COutput>(output);
647 if (output.GetEffectiveValue() > 0) {
648 insert_output(shared_output, type, ancestors, descendants, spk_to_positive_groups_map);
652 insert_output(shared_output, type, ancestors, descendants, spk_to_groups_map);
657 const auto& push_output_groups = [&](
const ScriptPubKeyToOutgroup& groups_map,
bool positive_only) {
658 for (
const auto& [
script, groups] : groups_map) {
660 for (
auto group_it = groups.rbegin(); group_it != groups.rend(); group_it++) {
664 bool accepted =
false;
665 for (
const auto& sel_filter : filters) {
666 const auto& filter = sel_filter.filter;
667 if (!
group.EligibleForSpending(filter))
continue;
670 if (group_it == groups.rbegin() && groups.size() > 1 && !filter.m_include_partial_groups) {
676 filtered_groups[filter].Push(
group, type, positive_only, !positive_only);
679 if (!accepted) ret_discarded_groups.emplace_back(
group);
684 push_output_groups(spk_to_groups_map,
false);
685 push_output_groups(spk_to_positive_groups_map,
true);
687 return filtered_groups;
693 const std::vector<SelectionFilter>& filters)
695 std::vector<OutputGroup> unused;
706 std::vector<SelectionResult> results;
712 if (result) results.push_back(*result);
716 if (results.size() > 0)
return *std::min_element(results.begin(), results.end());
721 if (allow_mixed_output_types && groups.
TypesCount() > 1) {
732 std::vector<SelectionResult> results;
733 std::vector<util::Result<SelectionResult>> errors;
738 errors.emplace_back(std::move(result));
745 int max_selection_weight = max_transaction_weight - tx_weight_no_input;
746 if (max_selection_weight <= 0) {
747 return util::Error{
_(
"Maximum transaction weight is less than transaction weight without inputs")};
753 results.push_back(*bnb_result);
754 }
else append_error(std::move(bnb_result));
759 max_selection_weight -= change_outputs_weight;
760 if (max_selection_weight < 0 && results.empty()) {
761 return util::Error{
_(
"Maximum transaction weight is too low, can not accommodate change output")};
766 results.push_back(*knapsack_result);
767 }
else append_error(std::move(knapsack_result));
772 results.push_back(*cg_result);
774 append_error(std::move(cg_result));
779 results.push_back(*srd_result);
780 }
else append_error(std::move(srd_result));
782 if (results.empty()) {
785 return errors.empty() ?
util::Error() : std::move(errors.front());
789 for (
auto& result : results) {
790 std::vector<COutPoint> outpoints;
791 std::set<std::shared_ptr<COutput>> coins = result.GetInputSet();
793 for (
auto& coin : coins) {
794 if (coin->depth > 0)
continue;
795 outpoints.push_back(coin->outpoint);
796 summed_bump_fees += coin->ancestor_bump_fees;
799 if (!combined_bump_fee.has_value()) {
800 return util::Error{
_(
"Failed to calculate bump fees, because unconfirmed UTXOs depend on an enormous cluster of unconfirmed transactions.")};
802 CAmount bump_fee_overestimate = summed_bump_fees - combined_bump_fee.value();
803 if (bump_fee_overestimate) {
804 result.SetBumpFeeDiscount(bump_fee_overestimate);
811 return *std::min_element(results.begin(), results.end());
823 return util::Error{
_(
"The preselected coins total amount does not cover the transaction target. "
824 "Please allow other inputs to be automatically selected or include more coins manually")};
828 if (selection_target <= 0) {
839 if (selection_target > available_coins_total_amount) {
845 if (!op_selection_result)
return op_selection_result;
848 if (!pre_set_inputs.
coins.empty()) {
851 op_selection_result->Merge(preselected);
858 if (op_selection_result->GetWeight() > max_inputs_weight) {
859 return util::Error{
_(
"The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. "
860 "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")};
863 return op_selection_result;
868 unsigned int limit_ancestor_count = 0;
869 unsigned int limit_descendant_count = 0;
870 wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
871 const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
872 const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
887 std::vector<SelectionFilter> ordered_filters{
895 if (
wallet.m_spend_zero_conf_change) {
897 ordered_filters.push_back({
CoinEligibilityFilter(0, 1, std::min(
size_t{4}, max_ancestors/3), std::min(
size_t{4}, max_descendants/3))});
911 if (!fRejectLongChains) {
913 std::numeric_limits<uint64_t>::max(),
919 std::vector<OutputGroup> discarded_groups;
924 CAmount total_unconf_long_chain = 0;
925 for (
const auto&
group : discarded_groups) {
926 total_discarded +=
group.GetSelectionAmount();
927 if (
group.m_ancestors >= max_ancestors ||
group.m_descendants >= max_descendants) total_unconf_long_chain +=
group.GetSelectionAmount();
932 if (total_amount + total_unconf_long_chain > value_to_select) {
933 return util::Error{
_(
"Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool")};
941 std::vector<util::Result<SelectionResult>> res_detailed_errors;
943 for (
const auto& select_filter : ordered_filters) {
944 auto it = filtered_groups.find(select_filter.filter);
945 if (it == filtered_groups.end())
continue;
946 if (updated_selection_params.
m_version ==
TRUC_VERSION && (select_filter.filter.conf_mine == 0 || select_filter.filter.conf_theirs == 0)) {
952 updated_selection_params, select_filter.allow_mixed_output_types)}) {
958 if (
HasErrorMsg(res)) res_detailed_errors.emplace_back(std::move(res));
963 if (!res_detailed_errors.empty())
return std::move(res_detailed_errors.front());
976 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
979 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
1029 for (
const auto& in : tx.
vin) {
1053 const std::vector<CRecipient>& vecSend,
1054 std::optional<unsigned int> change_pos,
1063 txNew.
version = coin_control.m_version;
1066 coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
1067 coin_selection_params.m_include_unsafe_inputs = coin_control.m_include_unsafe_inputs;
1069 coin_selection_params.m_version = coin_control.m_version;
1071 if (coin_selection_params.m_max_tx_weight.value() < minimum_tx_weight || coin_selection_params.m_max_tx_weight.value() >
MAX_STANDARD_TX_WEIGHT) {
1075 coin_selection_params.m_long_term_feerate =
wallet.m_consolidate_feerate;
1080 const OutputType change_type =
wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type :
wallet.m_default_change_type, vecSend);
1082 unsigned int outputs_to_subtract_fee_from = 0;
1083 for (
const auto& recipient : vecSend) {
1084 if (
IsDust(recipient,
wallet.chain().relayDustFee())) {
1090 recipients_sum += recipient.nAmount;
1092 if (recipient.fSubtractFeeFromAmount) {
1093 outputs_to_subtract_fee_from++;
1094 coin_selection_params.m_subtract_fee_outputs =
true;
1103 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
1128 CTxOut change_prototype_txout(0, scriptChange);
1129 coin_selection_params.change_output_size =
GetSerializeSize(change_prototype_txout);
1135 if (change_spend_size == -1) {
1138 coin_selection_params.change_spend_size = change_spend_size;
1149 if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
1154 return util::Error{
strprintf(
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s."),
"-fallbackfee")};
1162 coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
1163 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;
1165 coin_selection_params.m_min_change_target =
GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
1170 const auto dust =
GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
1171 const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
1172 coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
1175 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);
1176 CAmount selection_target = recipients_sum + not_input_fees;
1180 if (selection_target == 0 && !coin_control.HasSelected()) {
1181 return util::Error{
_(
"Transaction requires one destination of non-zero value, a non-zero feerate, or a pre-selected input")};
1186 if (coin_control.HasSelected()) {
1189 preset_inputs = *res_fetch_inputs;
1195 if (coin_control.m_allow_other_inputs) {
1196 available_coins =
AvailableCoins(
wallet, &coin_control, coin_selection_params.m_effective_feerate);
1200 auto select_coins_res =
SelectCoins(
wallet, available_coins, preset_inputs, selection_target, coin_control, coin_selection_params);
1201 if (!select_coins_res) {
1208 wallet.GetName().c_str(),
1215 txNew.
vout.reserve(vecSend.size() + 1);
1216 for (
const auto& recipient : vecSend)
1220 const CAmount change_amount = result.
GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
1221 if (change_amount > 0) {
1222 CTxOut newTxOut(change_amount, scriptChange);
1226 }
else if ((
unsigned int)*change_pos > txNew.
vout.size()) {
1227 return util::Error{
_(
"Transaction change output index out of range")};
1229 txNew.
vout.insert(txNew.
vout.begin() + *change_pos, newTxOut);
1231 change_pos = std::nullopt;
1237 if (coin_control.HasSelected() && coin_control.HasSelectedOrder()) {
1242 std::stable_sort(selected_coins.begin(), selected_coins.end(),
1243 [&coin_control](
const std::shared_ptr<COutput>& a,
const std::shared_ptr<COutput>& b) {
1244 auto a_pos = coin_control.GetSelectionPos(a->outpoint);
1245 auto b_pos = coin_control.GetSelectionPos(b->outpoint);
1246 if (a_pos.has_value() && b_pos.has_value()) {
1247 return a_pos.value() < b_pos.value();
1248 }
else if (a_pos.has_value() && !b_pos.has_value()) {
1264 bool use_anti_fee_sniping =
true;
1266 txNew.vin.reserve(selected_coins.size());
1267 for (
const auto& coin : selected_coins) {
1268 std::optional<uint32_t>
sequence = coin_control.GetSequence(coin->outpoint);
1271 use_anti_fee_sniping =
false;
1273 txNew.vin.emplace_back(coin->outpoint,
CScript{},
sequence.value_or(default_sequence));
1275 auto scripts = coin_control.GetScripts(coin->outpoint);
1276 if (scripts.first) {
1277 txNew.vin.back().scriptSig = *scripts.first;
1279 if (scripts.second) {
1280 txNew.vin.back().scriptWitness = *scripts.second;
1283 if (coin_control.m_locktime) {
1284 txNew.nLockTime = coin_control.m_locktime.value();
1286 use_anti_fee_sniping =
false;
1288 if (use_anti_fee_sniping) {
1294 int nBytes = tx_sizes.vsize;
1296 return util::Error{
_(
"Missing solving data for estimating transaction size")};
1298 CAmount fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes) + result.GetTotalBumpFees();
1300 Assume(recipients_sum + change_amount == output_value);
1301 CAmount current_fee = result.GetSelectedValue() - output_value;
1304 if (current_fee < 0) {
1309 if (change_pos && fee_needed < current_fee) {
1310 auto& change = txNew.vout.at(*change_pos);
1311 change.nValue += current_fee - fee_needed;
1313 if (fee_needed != current_fee) {
1319 if (coin_selection_params.m_subtract_fee_outputs) {
1320 CAmount to_reduce = fee_needed - current_fee;
1323 for (
const auto& recipient : vecSend)
1325 if (change_pos && i == *change_pos) {
1328 CTxOut& txout = txNew.vout[i];
1330 if (recipient.fSubtractFeeFromAmount)
1332 txout.
nValue -= to_reduce / outputs_to_subtract_fee_from;
1337 txout.
nValue -= to_reduce % outputs_to_subtract_fee_from;
1343 return util::Error{
_(
"The transaction amount is too small to pay the fee")};
1345 return util::Error{
_(
"The transaction amount is too small to send after the fee has been deducted")};
1352 if (fee_needed != current_fee) {
1359 if (fee_needed > current_fee) {
1364 if (scriptChange.empty() && change_pos) {
1368 if (
sign && !
wallet.SignTransaction(txNew)) {
1382 if (current_fee >
wallet.m_default_max_tx_fee) {
1388 auto result =
wallet.chain().checkChainLimits(tx);
1396 reservedest.KeepDestination();
1398 wallet.WalletLogPrintf(
"Coin Selection: Algorithm:%s, Waste Metric Score:%d\n",
GetAlgorithmName(result.GetAlgo()), result.GetWaste());
1399 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",
1400 current_fee, nBytes, feeCalc.returnedTarget, feeCalc.desiredTarget,
StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
1401 feeCalc.est.pass.start, feeCalc.est.pass.end,
1402 (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool) > 0.0 ? 100 * feeCalc.est.pass.withinTarget / (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool) : 0.0,
1403 feeCalc.est.pass.withinTarget, feeCalc.est.pass.totalConfirmed, feeCalc.est.pass.inMempool, feeCalc.est.pass.leftMempool,
1404 feeCalc.est.fail.start, feeCalc.est.fail.end,
1405 (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) > 0.0 ? 100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) : 0.0,
1406 feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
1407 return CreatedTransactionResult(tx, current_fee, change_pos, feeCalc);
1412 const std::vector<CRecipient>& vecSend,
1413 std::optional<unsigned int> change_pos,
1417 if (vecSend.empty()) {
1418 return util::Error{
_(
"Transaction must have at least one recipient")};
1421 if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](
const auto& recipient){ return recipient.nAmount < 0; })) {
1422 return util::Error{
_(
"Transaction amounts must not be negative")};
1428 TRACEPOINT(coin_selection, normal_create_tx_internal,
1429 wallet.GetName().c_str(),
1432 res && res->change_pos.has_value() ? int32_t(*res->change_pos) : -1);
1433 if (!res)
return res;
1434 const auto& txr_ungrouped = *res;
1437 TRACEPOINT(coin_selection, attempting_aps_create_tx,
wallet.GetName().c_str());
1442 if (txr_ungrouped.change_pos) {
1448 const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee) :
false};
1449 TRACEPOINT(coin_selection, aps_create_tx_internal,
1450 wallet.GetName().c_str(),
1452 txr_grouped.has_value(),
1453 txr_grouped.has_value() ? txr_grouped->fee : 0,
1454 txr_grouped.has_value() && txr_grouped->change_pos.has_value() ? int32_t(*txr_grouped->change_pos) : -1);
1456 wallet.WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n",
1457 txr_ungrouped.fee, txr_grouped->fee, use_aps ?
"grouped" :
"non-grouped");
1458 if (use_aps)
return txr_grouped;
1482 std::map<COutPoint, Coin> coins;
1486 wallet.chain().findCoins(coins);
1489 const auto& outPoint = txin.
prevout;
1491 if (!
wallet.IsMine(outPoint)) {
1492 if (coins[outPoint].
out.IsNull()) {
1493 return util::Error{
_(
"Unable to find UTXO for external input")};
1510 for (
const CTxIn& txin : res->tx->vin) {
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
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.
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
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.
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().
CScriptWitness scriptWitness
Only serialized through CTransaction.
An output of a transaction.
A signing provider to be used to interface with multiple signing providers at once.
void AddProvider(std::unique_ptr< SigningProvider > provider)
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
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 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.
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.
bool IsSelected(const COutPoint &outpoint) const
Returns true if the given output is pre-selected.
std::optional< CTxOut > GetExternalOutput(const COutPoint &outpoint) const
Returns the external output for the given outpoint if it exists.
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
std::optional< int64_t > GetInputWeight(const COutPoint &outpoint) const
Returns the input weight.
PreselectedInput & Select(const COutPoint &outpoint)
Lock-in the given output for spending.
bool HasSelected() const
Returns true if there are pre-selected inputs.
bool IsExternalSelected(const COutPoint &outpoint) const
Returns true if the given output is selected as an external input.
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.
uint32_t m_version
Version.
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs.
CTxDestination destChange
Custom change destination, if not set an address is generated.
std::vector< COutPoint > ListSelected() const
List the selected inputs.
std::optional< uint32_t > m_locktime
Locktime.
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.
std::optional< Txid > truc_child_in_mempool
int64_t GetTxTime() const
A wrapper to reserve an address from a wallet.
util::Result< CTxDestination > GetReservedDestination(bool internal)
Reserve an address.
static int32_t GetTransactionWeight(const CTransaction &tx)
static const int WITNESS_SCALE_FACTOR
@ SAT_VB
Use sat/vB fee rate unit.
is a home for simple string functions returning descriptive messages that are used in RPC and GUI int...
static int sign(const secp256k1_context *ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64)
bilingual_str TransactionErrorString(const TransactionError err)
std::string StringForFeeReason(FeeReason reason)
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.
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
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...
util::Result< CreatedTransactionResult > FundTransaction(CWallet &wallet, const CMutableTransaction &tx, const std::vector< CRecipient > &vecSend, std::optional< unsigned int > change_pos, bool lockUnspents, CCoinControl coinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
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...
bool CachedTxIsFromMe(const CWallet &wallet, const CWalletTx &wtx)
const int DEFAULT_MIN_DEPTH
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< Txid > &trusted_parents)
util::Result< SelectionResult > SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change, int max_selection_weight)
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.
static bool UseMaxSig(const std::optional< CTxIn > &txin, const CCoinControl *coin_control)
Whether to assume ECDSA signatures' will be high-r.
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.
util::Result< SelectionResult > CoinGrinder(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, CAmount change_target, int max_selection_weight)
util::Result< PreSelectedInputs > FetchSelectedInputs(const CWallet &wallet, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params)
Fetch and validate coin control selected inputs.
bool IsDust(const CRecipient &recipient, const CFeeRate &dustRelayFee)
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
const int DEFAULT_MAX_DEPTH
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.
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.
util::Result< SelectionResult > KnapsackSolver(std::vector< OutputGroup > &groups, const CAmount &nTargetValue, CAmount change_target, FastRandomContext &rng, int max_selection_weight)
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.
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::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *wallet, const CCoinControl *coin_control)
Get the marginal bytes if spending the specified output from this transaction.
std::string GetAlgorithmName(const SelectionAlgorithm algo)
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 ...
TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const CCoinControl *coin_control)
static bool HasErrorMsg(const util::Result< SelectionResult > &res)
CFeeRate GetDiscardRate(const CWallet &wallet)
Return the maximum feerate for discarding change.
std::map< CoinEligibilityFilter, OutputGroupTypeMap > FilteredOutputGroups
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...
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)
@ WALLET_FLAG_AVOID_REUSE
static bool IsCurrentForAntiFeeSniping(interfaces::Chain &chain, const uint256 &block_hash)
FilteredOutputGroups GroupOutputs(const CWallet &wallet, const CoinsResult &coins, const CoinSelectionParams ¶ms, const std::vector< SelectionFilter > &filters)
Group coins by the provided filters.
static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES
int CalculateMaximumSignedInputSize(const CTxOut &txout, const COutPoint outpoint, const SigningProvider *provider, bool can_grind_r, const CCoinControl *coin_control)
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.
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS
Default for -walletrejectlongchains.
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 (SRD).
uint64_t GetSerializeSizeForRecipient(const CRecipient &recipient)
is a home for public enum and struct type definitions that are used internally by node code,...
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).
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
static constexpr int32_t 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
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
static const unsigned int LOCKTIME_THRESHOLD
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 byt...
uint64_t GetSerializeSize(const T &t)
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
TRACEPOINT_SEMAPHORE(coin_selection, selected_coins)
A mutable version of CTransaction.
std::vector< CTxOut > vout
Interface for parsed descriptor objects.
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
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.
virtual std::optional< OutputType > GetOutputType() const =0
A UTXO under consideration for use in funding a new transaction.
COutPoint outpoint
The outpoint identifying this UTXO.
void ApplyBumpFee(CAmount bump_fee)
Parameters for filtering which OutputGroups we may use in coin selection.
bool check_version_trucness
bool include_immature_coinbase
Parameters for one iteration of Coin Selection.
uint32_t m_version
The version of the transaction we are trying to create.
FastRandomContext & rng_fast
Randomness to use in the context of coin selection.
CAmount m_min_change_target
Mininmum change to target in Knapsack solver and CoinGrinder: select coins to cover the payment and a...
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
bool m_include_unsafe_inputs
When true, allow unsafe coins to be selected during Coin Selection.
CFeeRate m_effective_feerate
The targeted feerate of the transaction being built.
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.
int change_output_size
Size of a change output in bytes, determined by the output type.
int tx_noinputs_size
Size of the transaction before coin selection, consisting of the header and recipient output(s),...
std::optional< int > m_max_tx_weight
The maximum weight for this transaction.
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()
void Add(OutputType type, const COutput &out)
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::vector< OutputGroup > positive_group
std::vector< OutputGroup > mixed_group
A group of UTXOs paid to the same output script.
Stores several 'Groups' whose were mapped by output type.
std::map< OutputType, Groups > groups_by_type
CAmount GetChange(CAmount min_viable_change, CAmount change_fee) const
Get the amount for the change output after paying needed fees.
void RecalculateWaste(CAmount min_viable_change, CAmount change_cost, CAmount change_fee)
Calculates and stores the waste for this result given the cost of change and the opportunity cost of ...
CAmount GetSelectedValue() const
Get the sum of the input values.
CAmount GetTarget() const
SelectionAlgorithm GetAlgo() const
void AddInputs(const std::set< std::shared_ptr< COutput > > &inputs, bool subtract_fee_outputs)
std::vector< std::shared_ptr< COutput > > GetShuffledInputVector() const
Get the vector of COutputs that will be used to fill in a CTransaction's vin.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define TRACEPOINT(context,...)
consteval auto _(util::TranslatedLiteral str)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
static constexpr decltype(CTransaction::version) TRUC_VERSION
static constexpr int64_t TRUC_CHILD_MAX_WEIGHT
static constexpr uint32_t MAX_BIP125_RBF_SEQUENCE
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
static void AvailableCoins(benchmark::Bench &bench, const std::vector< OutputType > &output_type)