Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2021-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_WALLET_SPEND_H6#define BITCOIN_WALLET_SPEND_H8#include <consensus/amount.h>9#include <util/result.h>10#include <wallet/coinselection.h>11#include <wallet/transaction.h>12#include <wallet/types.h>13#include <wallet/wallet.h>15#include <map>16#include <memory>17#include <optional>18#include <set>19#include <unordered_set>20#include <vector>22namespace wallet {23/** Get the marginal bytes if spending the specified output from this transaction.24* Use CoinControl to determine whether to expect signature grinding when calculating the size of the input spend. */25int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet, const CCoinControl* coin_control);26int CalculateMaximumSignedInputSize(const CTxOut& txout, COutPoint outpoint, const SigningProvider* pwallet, bool can_grind_r, const CCoinControl* coin_control);27struct TxSize {28int64_t vsize{-1};29int64_t weight{-1};30};32/** Calculate the size of the transaction using CoinControl to determine33* whether to expect signature grinding when calculating the size of the input spend. */34TxSize CalculateMaximumSignedTxSize(const CTransaction& tx, const CWallet* wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control = nullptr);35TxSize CalculateMaximumSignedTxSize(const CTransaction& tx, const CWallet* wallet, const CCoinControl* coin_control = nullptr) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet);37/**38* COutputs available for spending, stored by OutputType.39* This struct is really just a wrapper around OutputType vectors with a convenient40* method for concatenating and returning all COutputs as one vector.41*42* Size(), Erase(), Shuffle(), and Add() methods are implemented to43* allow easy interaction with the struct.44*/45struct CoinsResult {46std::map<OutputType, std::vector<COutput>> coins;48/** Concatenate and return all COutputs as one vector */49std::vector<COutput> All() const;51/** The following methods are provided so that CoinsResult can mimic a vector,52* i.e., methods can work with individual OutputType vectors or on the entire object */53size_t Size() const;54/** Return how many different output types this struct stores */55size_t TypesCount() const { return coins.size(); }56void Erase(const std::unordered_set<COutPoint, SaltedOutpointHasher>& coins_to_remove);57void Shuffle(FastRandomContext& rng_fast);58void Add(OutputType type, const COutput& out);60CAmount GetTotalAmount() const { return total_amount; }61std::optional<CAmount> GetEffectiveTotalAmount() const { return total_effective_amount; }62// Returns the appropriate total based on whether fees are being subtracted from outputs63std::optional<CAmount> GetAppropriateTotal(bool subtract_fee_outputs) const {64return subtract_fee_outputs ? total_amount : total_effective_amount;65}67private:68/** Sum of all available coins raw value */69CAmount total_amount{0};70/** Sum of all available coins effective value (each output value minus fees required to spend it) */71std::optional<CAmount> total_effective_amount;72};74struct CoinFilterParams {75// Outputs below the minimum amount will not get selected76CAmount min_amount{1};77// Outputs above the maximum amount will not get selected78CAmount max_amount{MAX_MONEY};79// Return outputs until the minimum sum amount is covered80CAmount min_sum_amount{MAX_MONEY};81// Maximum number of outputs that can be returned82uint64_t max_count{0};83// By default, do not include immature coinbase outputs84bool include_immature_coinbase{false};85// By default, skip locked UTXOs86bool skip_locked{true};87// When true, filter unconfirmed coins by whether their88// version's TRUCness matches what is set by CCoinControl.89bool check_version_trucness{true};90};92/**93* Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.94*/95CoinsResult AvailableCoins(const CWallet& wallet,96const CCoinControl* coinControl = nullptr,97std::optional<CFeeRate> feerate = std::nullopt,98const CoinFilterParams& params = {}) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);100/**101* Find non-change parent output.102*/103const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);105/**106* Return list of available coins and locked coins grouped by non-change output address.107*/108std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);110struct SelectionFilter {111CoinEligibilityFilter filter;112bool allow_mixed_output_types{true};113};115/**116* Group coins by the provided filters.117*/118FilteredOutputGroups GroupOutputs(const CWallet& wallet,119const CoinsResult& coins,120const CoinSelectionParams& coin_sel_params,121const std::vector<SelectionFilter>& filters);123/**124* Attempt to find a valid input set that preserves privacy by not mixing OutputTypes.125* `ChooseSelectionResult()` will be called on each OutputType individually and the best126* the solution (according to the waste metric) will be chosen. If a valid input cannot be found from any127* single OutputType, fallback to running `ChooseSelectionResult()` over all available coins.128*129* @param[in] chain The chain interface to get information on bump fees for unconfirmed UTXOs130* @param[in] nTargetValue The target value131* @param[in] groups The grouped outputs mapped by coin eligibility filters132* @param[in] coin_selection_params Parameters for the coin selection133* @param[in] allow_mixed_output_types Relax restriction that SelectionResults must be of the same OutputType134* returns If successful, a SelectionResult containing the input set135* If failed, returns (1) an empty error message if the target was not reached (general "Insufficient funds")136* or (2) a specific error message if there was something particularly wrong (e.g. a selection137* result that surpassed the tx max weight size).138*/139util::Result<SelectionResult> AttemptSelection(interfaces::Chain& chain, const CAmount& nTargetValue, OutputGroupTypeMap& groups,140const CoinSelectionParams& coin_selection_params, bool allow_mixed_output_types);142/**143* Attempt to find a valid input set that meets the provided eligibility filter and target.144* Multiple coin selection algorithms will be run and the input set that produces the least waste145* (according to the waste metric) will be chosen.146*147* @param[in] chain The chain interface to get information on bump fees for unconfirmed UTXOs148* @param[in] nTargetValue The target value149* @param[in] groups The struct containing the outputs grouped by script and divided by (1) positive only outputs and (2) all outputs (positive + negative).150* @param[in] coin_selection_params Parameters for the coin selection151* returns If successful, a SelectionResult containing the input set152* If failed, returns (1) an empty error message if the target was not reached (general "Insufficient funds")153* or (2) a specific error message if there was something particularly wrong (e.g. a selection154* result that surpassed the tx max weight size).155*/156util::Result<SelectionResult> ChooseSelectionResult(interfaces::Chain& chain, const CAmount& nTargetValue, Groups& groups, const CoinSelectionParams& coin_selection_params);158/**159* Fetch and validate coin control selected inputs.160* Coins could be internal (from the wallet) or external.161*/162util::Result<CoinsResult> FetchSelectedInputs(const CWallet& wallet, const CCoinControl& coin_control,163const CoinSelectionParams& coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);165/**166* Select a set of coins such that nTargetValue is met; never select unconfirmed coins if they are not ours167* @param[in] wallet The wallet which provides data necessary to spend the selected coins168* @param[in] available_coins The struct of coins, organized by OutputType, available for selection prior to filtering169* @param[in] nTargetValue The target value170* @param[in] coin_selection_params Parameters for this coin selection such as feerates, whether to avoid partial spends,171* and whether to subtract the fee from the outputs.172* returns If successful, a SelectionResult containing the selected coins173* If failed, returns (1) an empty error message if the target was not reached (general "Insufficient funds")174* or (2) an specific error message if there was something particularly wrong (e.g. a selection175* result that surpassed the tx max weight size).176*/177util::Result<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, CoinsResult& available_coins, const CAmount& nTargetValue,178const CoinSelectionParams& coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);180/**181* Select all coins from coin_control, and if coin_control 'm_allow_other_inputs=true', call 'AutomaticCoinSelection' to182* select a set of coins such that nTargetValue - pre_set_inputs.total_amount is met.183*/184util::Result<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& available_coins, const CoinsResult& pre_set_inputs,185const CAmount& nTargetValue, const CCoinControl& coin_control,186const CoinSelectionParams& coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);188/**189* Set a height-based locktime for new transactions (uses the height of the190* current chain tip unless we are not synced with the current chain191*/192void DiscourageFeeSniping(CMutableTransaction& tx, FastRandomContext& rng_fast, interfaces::Chain& chain, const uint256& block_hash, int block_height);194/**195* Create a new transaction paying the recipients with a set of coins196* selected by SelectCoins(); Also create the change output, when needed197* @note passing change_pos as std::nullopt will result in setting a random position198*/199util::Result<CreatedTransactionResult> CreateTransaction(CWallet& wallet, const std::vector<CRecipient>& vecSend, std::optional<unsigned int> change_pos, const CCoinControl& coin_control, bool sign = true);201/**202* Insert additional inputs into the transaction by203* calling CreateTransaction();204*/205util::Result<CreatedTransactionResult> FundTransaction(CWallet& wallet, const CMutableTransaction& tx, const std::vector<CRecipient>& recipients, std::optional<unsigned int> change_pos, bool lockUnspents, CCoinControl);206} // namespace wallet208#endif // BITCOIN_WALLET_SPEND_H
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.