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)
120 std::optional<int64_t> weight;
122 return weight.value();
127 if (desc)
return MaxInputWeight(*desc, {txin}, coin_control, tx_is_segwit, can_grind_r);
139 bool is_segwit = std::any_of(txouts.begin(), txouts.end(), [&](
const CTxOut& txo) {
145 if (is_segwit) weight += 2;
151 for (uint32_t i = 0; i < txouts.size(); i++) {
153 if (!txin_weight)
return TxSize{-1, -1};
154 assert(*txin_weight > -1);
155 weight += *txin_weight;
164 std::vector<CTxOut> txouts;
169 if (mi !=
wallet->mapWallet.end()) {
171 txouts.emplace_back(mi->second.tx->vout.at(input.
prevout.
n));
172 }
else if (coin_control) {
174 if (!txout)
return TxSize{-1, -1};
175 txouts.emplace_back(*txout);
186 for (
const auto& it :
coins) {
187 size += it.second.size();
194 std::vector<COutput> all;
195 all.reserve(
coins.size());
196 for (
const auto& it :
coins) {
197 all.insert(all.end(), it.second.begin(), it.second.end());
208 for (
auto& [type, vec] :
coins) {
209 auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](
const COutput& coin) {
211 if (coins_to_remove.count(coin.outpoint) == 0)
return false;
218 vec.erase(remove_it, vec.end());
224 for (
auto& it :
coins) {
225 ::Shuffle(it.second.begin(), it.second.end(), rng_fast);
233 if (
out.HasEffectiveValue()) {
262 const bool can_grind_r =
wallet.CanGrindR();
263 std::map<COutPoint, CAmount> map_of_bump_fees =
wallet.chain().calculateIndividualBumpFees(coin_control.ListSelected(), coin_selection_params.m_effective_feerate);
264 for (
const COutPoint& outpoint : coin_control.ListSelected()) {
265 int64_t input_bytes = coin_control.GetInputWeight(outpoint).value_or(-1);
266 if (input_bytes != -1) {
270 if (
auto ptr_wtx =
wallet.GetWalletTx(outpoint.hash)) {
272 if (ptr_wtx->tx->vout.size() <= outpoint.n) {
275 txout = ptr_wtx->tx->vout.at(outpoint.n);
276 if (input_bytes == -1) {
281 const auto out{coin_control.GetExternalOutput(outpoint)};
289 if (input_bytes == -1) {
293 if (input_bytes == -1) {
298 COutput output(outpoint, txout, 0, input_bytes,
true,
true,
true, 0,
false, coin_selection_params.m_effective_feerate);
300 result.
Insert(output, coin_selection_params.m_subtract_fee_outputs);
307 std::optional<CFeeRate> feerate,
319 const bool can_grind_r =
wallet.CanGrindR();
320 std::vector<COutPoint> outpoints;
322 std::set<uint256> trusted_parents;
323 for (
const auto& entry :
wallet.mapWallet)
325 const uint256& txid = entry.first;
331 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
357 if (nDepth == 0 && wtx.
mapValue.count(
"replaces_txid")) {
369 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
373 if (only_safe && !safeTx) {
377 if (nDepth < min_depth || nDepth > max_depth) {
383 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
384 const CTxOut& output = wtx.
tx->vout[i];
397 if (
wallet.IsSpent(outpoint))
410 std::unique_ptr<SigningProvider> provider =
wallet.GetSolvingProvider(output.
scriptPubKey);
415 bool solvable = input_bytes > -1;
422 std::vector<std::vector<uint8_t>> script_solutions;
429 bool is_from_p2sh{
false};
432 if (!provider->GetCScript(
CScriptID(
uint160(script_solutions[0])), script))
continue;
433 type =
Solver(script, script_solutions);
438 COutput(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.
GetTxTime(), tx_from_me, feerate));
440 outpoints.push_back(outpoint);
456 if (feerate.has_value()) {
457 std::map<COutPoint, CAmount> map_of_bump_fees =
wallet.chain().calculateIndividualBumpFees(outpoints, feerate.value());
459 for (
auto& [
_, outputs] : result.
coins) {
460 for (
auto& output : outputs) {
461 output.ApplyBumpFee(map_of_bump_fees.at(output.outpoint));
485 if (!it || it->
tx->vout.size() <= prevout.
n ||
486 !
wallet.IsMine(it->
tx->vout[prevout.
n])) {
499 std::map<CTxDestination, std::vector<COutput>> result;
512 if (
auto pk_dest = std::get_if<PubKeyDestination>(&address)) {
513 address =
PKHash(pk_dest->GetPubKey());
518 result[address].emplace_back(coin);
527 const std::vector<SelectionFilter>& filters,
528 std::vector<OutputGroup>& ret_discarded_groups)
534 for (
const auto& [type, outputs] : coins.
coins) {
535 for (
const COutput& output : outputs) {
537 size_t ancestors, descendants;
538 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
542 group.Insert(std::make_shared<COutput>(output), ancestors, descendants);
545 bool accepted =
false;
546 for (
const auto& sel_filter : filters) {
547 const auto& filter = sel_filter.filter;
548 if (!
group.EligibleForSpending(filter))
continue;
549 filtered_groups[filter].Push(
group, type,
true,
true);
552 if (!accepted) ret_discarded_groups.emplace_back(
group);
555 return filtered_groups;
564 typedef std::map<std::pair<CScript, OutputType>, std::vector<OutputGroup>> ScriptPubKeyToOutgroup;
565 const auto& insert_output = [&](
566 const std::shared_ptr<COutput>& output,
OutputType type,
size_t ancestors,
size_t descendants,
567 ScriptPubKeyToOutgroup& groups_map) {
568 std::vector<OutputGroup>& groups = groups_map[std::make_pair(output->txout.scriptPubKey,type)];
570 if (groups.size() == 0) {
572 groups.emplace_back(coin_sel_params);
583 groups.emplace_back(coin_sel_params);
584 group = &groups.back();
587 group->Insert(output, ancestors, descendants);
590 ScriptPubKeyToOutgroup spk_to_groups_map;
591 ScriptPubKeyToOutgroup spk_to_positive_groups_map;
592 for (
const auto& [type, outs] : coins.
coins) {
593 for (
const COutput& output : outs) {
594 size_t ancestors, descendants;
595 wallet.chain().getTransactionAncestry(output.outpoint.hash, ancestors, descendants);
597 const auto& shared_output = std::make_shared<COutput>(output);
599 if (output.GetEffectiveValue() > 0) {
600 insert_output(shared_output, type, ancestors, descendants, spk_to_positive_groups_map);
604 insert_output(shared_output, type, ancestors, descendants, spk_to_groups_map);
609 const auto& push_output_groups = [&](
const ScriptPubKeyToOutgroup& groups_map,
bool positive_only) {
610 for (
const auto& [script, groups] : groups_map) {
612 for (
auto group_it = groups.rbegin(); group_it != groups.rend(); group_it++) {
616 bool accepted =
false;
617 for (
const auto& sel_filter : filters) {
618 const auto& filter = sel_filter.filter;
619 if (!
group.EligibleForSpending(filter))
continue;
622 if (group_it == groups.rbegin() && groups.size() > 1 && !filter.m_include_partial_groups) {
628 filtered_groups[filter].Push(
group, type, positive_only, !positive_only);
631 if (!accepted) ret_discarded_groups.emplace_back(
group);
636 push_output_groups(spk_to_groups_map,
false);
637 push_output_groups(spk_to_positive_groups_map,
true);
639 return filtered_groups;
645 const std::vector<SelectionFilter>& filters)
647 std::vector<OutputGroup> unused;
658 std::vector<SelectionResult> results;
664 if (result) results.push_back(*result);
668 if (results.size() > 0)
return *std::min_element(results.begin(), results.end());
673 if (allow_mixed_output_types && groups.
TypesCount() > 1) {
684 std::vector<SelectionResult> results;
685 std::vector<util::Result<SelectionResult>> errors;
690 errors.emplace_back(result);
700 results.push_back(*bnb_result);
701 }
else append_error(bnb_result);
709 results.push_back(*knapsack_result);
710 }
else append_error(knapsack_result);
715 results.push_back(*cg_result);
717 append_error(cg_result);
722 results.push_back(*srd_result);
723 }
else append_error(srd_result);
725 if (results.empty()) {
728 return errors.empty() ?
util::Error() : errors.front();
732 for (
auto& result : results) {
733 std::vector<COutPoint> outpoints;
734 std::set<std::shared_ptr<COutput>> coins = result.GetInputSet();
736 for (
auto& coin : coins) {
737 if (coin->depth > 0)
continue;
738 outpoints.push_back(coin->outpoint);
739 summed_bump_fees += coin->ancestor_bump_fees;
742 if (!combined_bump_fee.has_value()) {
743 return util::Error{
_(
"Failed to calculate bump fees, because unconfirmed UTXOs depend on enormous cluster of unconfirmed transactions.")};
745 CAmount bump_fee_overestimate = summed_bump_fees - combined_bump_fee.value();
746 if (bump_fee_overestimate) {
747 result.SetBumpFeeDiscount(bump_fee_overestimate);
754 return *std::min_element(results.begin(), results.end());
766 return util::Error{
_(
"The preselected coins total amount does not cover the transaction target. " 767 "Please allow other inputs to be automatically selected or include more coins manually")};
771 if (selection_target <= 0) {
782 if (selection_target > available_coins_total_amount) {
788 if (!op_selection_result)
return op_selection_result;
791 if (!pre_set_inputs.
coins.empty()) {
794 op_selection_result->Merge(preselected);
799 return op_selection_result;
804 unsigned int limit_ancestor_count = 0;
805 unsigned int limit_descendant_count = 0;
806 wallet.chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
807 const size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
808 const size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
823 std::vector<SelectionFilter> ordered_filters{
831 if (
wallet.m_spend_zero_conf_change) {
833 ordered_filters.push_back({
CoinEligibilityFilter(0, 1, std::min(
size_t{4}, max_ancestors/3), std::min(
size_t{4}, max_descendants/3))});
847 if (!fRejectLongChains) {
849 std::numeric_limits<uint64_t>::max(),
855 std::vector<OutputGroup> discarded_groups;
860 CAmount total_unconf_long_chain = 0;
861 for (
const auto&
group : discarded_groups) {
862 total_discarded +=
group.GetSelectionAmount();
863 if (
group.m_ancestors >= max_ancestors ||
group.m_descendants >= max_descendants) total_unconf_long_chain +=
group.GetSelectionAmount();
868 if (total_amount + total_unconf_long_chain > value_to_select) {
869 return util::Result<SelectionResult>({
_(
"Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool")});
877 std::vector<util::Result<SelectionResult>> res_detailed_errors;
878 for (
const auto& select_filter : ordered_filters) {
879 auto it = filtered_groups.find(select_filter.filter);
880 if (it == filtered_groups.end())
continue;
882 coin_selection_params, select_filter.allow_mixed_output_types)}) {
888 if (
HasErrorMsg(res)) res_detailed_errors.emplace_back(res);
893 if (!res_detailed_errors.empty())
return res_detailed_errors.front();
908 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
911 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
965 for (
const auto& in : tx.
vin) {
979 const std::vector<CRecipient>& vecSend,
980 std::optional<unsigned int> change_pos,
989 if (coin_control.m_version) {
990 txNew.
nVersion = coin_control.m_version.value();
994 coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends;
995 coin_selection_params.m_include_unsafe_inputs = coin_control.m_include_unsafe_inputs;
998 coin_selection_params.m_long_term_feerate =
wallet.m_consolidate_feerate;
1001 const OutputType change_type =
wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type :
wallet.m_default_change_type, vecSend);
1003 unsigned int outputs_to_subtract_fee_from = 0;
1004 for (
const auto& recipient : vecSend) {
1005 recipients_sum += recipient.nAmount;
1007 if (recipient.fSubtractFeeFromAmount) {
1008 outputs_to_subtract_fee_from++;
1009 coin_selection_params.m_subtract_fee_outputs =
true;
1018 if (!std::get_if<CNoDestination>(&coin_control.destChange)) {
1043 CTxOut change_prototype_txout(0, scriptChange);
1044 coin_selection_params.change_output_size =
GetSerializeSize(change_prototype_txout);
1050 if (change_spend_size == -1) {
1053 coin_selection_params.change_spend_size = (size_t)change_spend_size;
1064 if (coin_control.m_feerate && coin_selection_params.m_effective_feerate > *coin_control.m_feerate) {
1069 return util::Error{
strprintf(
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s."),
"-fallbackfee")};
1077 coin_selection_params.m_change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
1078 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;
1080 coin_selection_params.m_min_change_target =
GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
1085 const auto dust =
GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
1086 const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
1087 coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
1093 for (
const auto& recipient : vecSend)
1103 txNew.
vout.push_back(txout);
1107 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);
1108 CAmount selection_target = recipients_sum + not_input_fees;
1112 if (selection_target == 0 && !coin_control.HasSelected()) {
1113 return util::Error{
_(
"Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input")};
1118 if (coin_control.HasSelected()) {
1121 preset_inputs = *res_fetch_inputs;
1127 if (coin_control.m_allow_other_inputs) {
1128 available_coins =
AvailableCoins(
wallet, &coin_control, coin_selection_params.m_effective_feerate);
1132 auto select_coins_res =
SelectCoins(
wallet, available_coins, preset_inputs, selection_target, coin_control, coin_selection_params);
1133 if (!select_coins_res) {
1139 TRACE5(coin_selection, selected_coins,
1140 wallet.GetName().c_str(),
1146 const CAmount change_amount = result.
GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
1147 if (change_amount > 0) {
1148 CTxOut newTxOut(change_amount, scriptChange);
1152 }
else if ((
unsigned int)*change_pos > txNew.
vout.size()) {
1153 return util::Error{
_(
"Transaction change output index out of range")};
1155 txNew.
vout.insert(txNew.
vout.begin() + *change_pos, newTxOut);
1157 change_pos = std::nullopt;
1163 if (coin_control.HasSelected() && coin_control.HasSelectedOrder()) {
1168 std::stable_sort(selected_coins.begin(), selected_coins.end(),
1169 [&coin_control](
const std::shared_ptr<COutput>& a,
const std::shared_ptr<COutput>& b) {
1170 auto a_pos = coin_control.GetSelectionPos(a->outpoint);
1171 auto b_pos = coin_control.GetSelectionPos(b->outpoint);
1172 if (a_pos.has_value() && b_pos.has_value()) {
1173 return a_pos.value() < b_pos.value();
1174 }
else if (a_pos.has_value() && !b_pos.has_value()) {
1190 bool use_anti_fee_sniping =
true;
1192 for (
const auto& coin : selected_coins) {
1193 std::optional<uint32_t>
sequence = coin_control.GetSequence(coin->outpoint);
1196 use_anti_fee_sniping =
false;
1198 txNew.
vin.emplace_back(coin->outpoint,
CScript{},
sequence.value_or(default_sequence));
1200 auto scripts = coin_control.GetScripts(coin->outpoint);
1201 if (scripts.first) {
1202 txNew.
vin.back().scriptSig = *scripts.first;
1204 if (scripts.second) {
1205 txNew.
vin.back().scriptWitness = *scripts.second;
1208 if (coin_control.m_locktime) {
1209 txNew.
nLockTime = coin_control.m_locktime.value();
1211 use_anti_fee_sniping =
false;
1213 if (use_anti_fee_sniping) {
1219 int nBytes = tx_sizes.
vsize;
1221 return util::Error{
_(
"Missing solving data for estimating transaction size")};
1225 Assume(recipients_sum + change_amount == output_value);
1229 if (current_fee < 0) {
1234 if (change_pos && fee_needed < current_fee) {
1235 auto& change = txNew.
vout.at(*change_pos);
1236 change.nValue += current_fee - fee_needed;
1238 if (fee_needed != current_fee) {
1244 if (coin_selection_params.m_subtract_fee_outputs) {
1245 CAmount to_reduce = fee_needed - current_fee;
1248 for (
const auto& recipient : vecSend)
1250 if (change_pos && i == *change_pos) {
1255 if (recipient.fSubtractFeeFromAmount)
1257 txout.
nValue -= to_reduce / outputs_to_subtract_fee_from;
1262 txout.
nValue -= to_reduce % outputs_to_subtract_fee_from;
1268 return util::Error{
_(
"The transaction amount is too small to pay the fee")};
1270 return util::Error{
_(
"The transaction amount is too small to send after the fee has been deducted")};
1277 if (fee_needed != current_fee) {
1284 if (fee_needed > current_fee) {
1289 if (scriptChange.
empty() && change_pos) {
1293 if (sign && !
wallet.SignTransaction(txNew)) {
1307 if (current_fee >
wallet.m_default_max_tx_fee) {
1313 auto result =
wallet.chain().checkChainLimits(tx);
1324 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",
1337 const std::vector<CRecipient>& vecSend,
1338 std::optional<unsigned int> change_pos,
1342 if (vecSend.empty()) {
1343 return util::Error{
_(
"Transaction must have at least one recipient")};
1346 if (std::any_of(vecSend.cbegin(), vecSend.cend(), [](
const auto& recipient){
return recipient.nAmount < 0; })) {
1347 return util::Error{
_(
"Transaction amounts must not be negative")};
1353 TRACE4(coin_selection, normal_create_tx_internal,
1354 wallet.GetName().c_str(),
1357 res && res->change_pos.has_value() ? int32_t(*res->change_pos) : -1);
1358 if (!res)
return res;
1359 const auto& txr_ungrouped = *res;
1362 TRACE1(coin_selection, attempting_aps_create_tx,
wallet.GetName().c_str());
1367 if (txr_ungrouped.change_pos) {
1368 ExtractDestination(txr_ungrouped.tx->vout[*txr_ungrouped.change_pos].scriptPubKey, tmp_cc.destChange);
1373 const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped.fee +
wallet.m_max_aps_fee) :
false};
1374 TRACE5(coin_selection, aps_create_tx_internal,
1375 wallet.GetName().c_str(),
1377 txr_grouped.has_value(),
1378 txr_grouped.has_value() ? txr_grouped->fee : 0,
1379 txr_grouped.has_value() && txr_grouped->change_pos.has_value() ? int32_t(*txr_grouped->change_pos) : -1);
1381 wallet.WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n",
1382 txr_ungrouped.fee, txr_grouped->fee, use_aps ?
"grouped" :
"non-grouped");
1383 if (use_aps)
return txr_grouped;
1407 std::map<COutPoint, Coin> coins;
1411 wallet.chain().findCoins(coins);
1414 const auto& outPoint = txin.
prevout;
1416 if (!
wallet.IsMine(outPoint)) {
1417 if (coins[outPoint].
out.IsNull()) {
1418 return util::Error{
_(
"Unable to find UTXO for external input")};
1435 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.
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.
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...
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.
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.
bilingual_str TransactionErrorString(const TransactionError err)
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...
const std::vector< CTxIn > vin
int64_t GetTxTime() const
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...
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.
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.
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.
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.
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 ...
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.
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
util::Result< SelectionResult > CoinGrinder(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, CAmount change_target, int max_weight)
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.
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
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...
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).
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