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#include <algorithm>6#include <common/args.h>7#include <common/messages.h>8#include <common/system.h>9#include <consensus/amount.h>10#include <consensus/validation.h>11#include <interfaces/chain.h>12#include <node/types.h>13#include <numeric>14#include <policy/policy.h>15#include <policy/truc_policy.h>16#include <primitives/transaction.h>17#include <primitives/transaction_identifier.h>18#include <script/script.h>19#include <script/signingprovider.h>20#include <script/solver.h>21#include <util/check.h>22#include <util/moneystr.h>23#include <util/rbf.h>24#include <util/trace.h>25#include <util/translation.h>26#include <wallet/coincontrol.h>27#include <wallet/fees.h>28#include <wallet/receive.h>29#include <wallet/spend.h>30#include <wallet/transaction.h>31#include <wallet/wallet.h>33#include <cmath>35using common::StringForFeeReason;36using common::TransactionErrorString;37using interfaces::FoundBlock;38using node::TransactionError;40TRACEPOINT_SEMAPHORE(coin_selection, selected_coins);41TRACEPOINT_SEMAPHORE(coin_selection, normal_create_tx_internal);42TRACEPOINT_SEMAPHORE(coin_selection, attempting_aps_create_tx);43TRACEPOINT_SEMAPHORE(coin_selection, aps_create_tx_internal);45namespace wallet {46static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES{100};48/** Whether the descriptor represents, directly or not, a witness program. */49static bool IsSegwit(const Descriptor& desc) {50if (const auto typ = desc.GetOutputType()) return *typ != OutputType::LEGACY;51return false;52}54/** Whether to assume ECDSA signatures' will be high-r. */55static bool UseMaxSig(const std::optional<CTxIn>& txin, const CCoinControl* coin_control) {56// Use max sig if watch only inputs were used or if this particular input is an external input57// to ensure a sufficient fee is attained for the requested feerate.58return coin_control && txin && coin_control->IsExternalSelected(txin->prevout);59}61/** Get the size of an input (in witness units) once it's signed.62*63* @param desc The output script descriptor of the coin spent by this input.64* @param txin Optionally the txin to estimate the size of. Used to determine the size of ECDSA signatures.65* @param coin_control Information about the context to determine the size of ECDSA signatures.66* @param tx_is_segwit Whether the transaction has at least a single input spending a segwit coin.67* @param can_grind_r Whether the signer will be able to grind the R of the signature.68*/69static std::optional<int64_t> MaxInputWeight(const Descriptor& desc, const std::optional<CTxIn>& txin,70const CCoinControl* coin_control, const bool tx_is_segwit,71const bool can_grind_r) {72if (const auto sat_weight = desc.MaxSatisfactionWeight(!can_grind_r || UseMaxSig(txin, coin_control))) {73if (const auto elems_count = desc.MaxSatisfactionElems()) {74const bool is_segwit = IsSegwit(desc);75// Account for the size of the scriptsig and the number of elements on the witness stack. Note76// that if any input in the transaction is spending a witness program, we need to specify the77// witness stack size for every input regardless of whether it is segwit itself.78// NOTE: this also works in case of mixed scriptsig-and-witness such as in p2sh-wrapped segwit v079// outputs. In this case the size of the scriptsig length will always be one (since the redeemScript80// is always a push of the witness program in this case, which is smaller than 253 bytes).81const int64_t scriptsig_len = is_segwit ? 1 : GetSizeOfCompactSize(*sat_weight / WITNESS_SCALE_FACTOR);82const int64_t witstack_len = is_segwit ? GetSizeOfCompactSize(*elems_count) : (tx_is_segwit ? 1 : 0);83// previous txid + previous vout + sequence + scriptsig len + witstack size + scriptsig or witness84// NOTE: sat_weight already accounts for the witness discount accordingly.85return (32 + 4 + 4 + scriptsig_len) * WITNESS_SCALE_FACTOR + witstack_len + *sat_weight;86}87}89return {};90}92int CalculateMaximumSignedInputSize(const CTxOut& txout, const COutPoint outpoint, const SigningProvider* provider, bool can_grind_r, const CCoinControl* coin_control)93{94if (!provider) return -1;96if (const auto desc = InferDescriptor(txout.scriptPubKey, *provider)) {97if (const auto weight = MaxInputWeight(*desc, CTxIn{outpoint}, coin_control, true, can_grind_r)) {98return static_cast<int>(GetVirtualTransactionSize(*weight, 0, 0));99}100}102return -1;103}105int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet, const CCoinControl* coin_control)106{107const std::unique_ptr<SigningProvider> provider = wallet->GetSolvingProvider(txout.scriptPubKey);108return CalculateMaximumSignedInputSize(txout, COutPoint(), provider.get(), wallet->CanGrindR(), coin_control);109}111/** Infer a descriptor for the given output script. */112static std::unique_ptr<Descriptor> GetDescriptor(const CWallet* wallet, const CCoinControl* coin_control,113const CScript script_pubkey)114{115MultiSigningProvider providers;116for (const auto spkman: wallet->GetScriptPubKeyMans(script_pubkey)) {117providers.AddProvider(spkman->GetSolvingProvider(script_pubkey));118}119if (coin_control) {120providers.AddProvider(std::make_unique<FlatSigningProvider>(coin_control->m_external_provider));121}122return InferDescriptor(script_pubkey, providers);123}125/** Infer the maximum size of this input after it will be signed. */126static std::optional<int64_t> GetSignedTxinWeight(const CWallet* wallet, const CCoinControl* coin_control,127const CTxIn& txin, const CTxOut& txo, const bool tx_is_segwit,128const bool can_grind_r)129{130// If weight was provided, use that.131std::optional<int64_t> weight;132if (coin_control && (weight = coin_control->GetInputWeight(txin.prevout))) {133return weight.value();134}136// Otherwise, use the maximum satisfaction size provided by the descriptor.137std::unique_ptr<Descriptor> desc{GetDescriptor(wallet, coin_control, txo.scriptPubKey)};138if (desc) return MaxInputWeight(*desc, {txin}, coin_control, tx_is_segwit, can_grind_r);140return {};141}143// txouts needs to be in the order of tx.vin144TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control)145{146// version + nLockTime + input count + output count147int64_t weight = (4 + 4 + GetSizeOfCompactSize(tx.vin.size()) + GetSizeOfCompactSize(tx.vout.size())) * WITNESS_SCALE_FACTOR;148// Whether any input spends a witness program. Necessary to run before the next loop over the149// inputs in order to accurately compute the compactSize length for the witness data per input.150bool is_segwit = std::any_of(txouts.begin(), txouts.end(), [&](const CTxOut& txo) {151std::unique_ptr<Descriptor> desc{GetDescriptor(wallet, coin_control, txo.scriptPubKey)};152if (desc) return IsSegwit(*desc);153return false;154});155// Segwit marker and flag156if (is_segwit) weight += 2;158// Add the size of the transaction outputs.159for (const auto& txo : tx.vout) weight += GetSerializeSize(txo) * WITNESS_SCALE_FACTOR;161// Add the size of the transaction inputs as if they were signed.162for (uint32_t i = 0; i < txouts.size(); i++) {163const auto txin_weight = GetSignedTxinWeight(wallet, coin_control, tx.vin[i], txouts[i], is_segwit, wallet->CanGrindR());164if (!txin_weight) return TxSize{-1, -1};165assert(*txin_weight > -1);166weight += *txin_weight;167}169// It's ok to use 0 as the number of sigops since we never create any pathological transaction.170return TxSize{GetVirtualTransactionSize(weight, 0, 0), weight};171}173TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const CCoinControl* coin_control)174{175std::vector<CTxOut> txouts;176// Look up the inputs. The inputs are either in the wallet, or in coin_control.177for (const CTxIn& input : tx.vin) {178const auto mi = wallet->mapWallet.find(input.prevout.hash);179// Can not estimate size without knowing the input details180if (mi != wallet->mapWallet.end()) {181assert(input.prevout.n < mi->second.GetTx()->vout.size());182txouts.emplace_back(mi->second.GetTx()->vout.at(input.prevout.n));183} else if (coin_control) {184const auto& txout{coin_control->GetExternalOutput(input.prevout)};185if (!txout) return TxSize{-1, -1};186txouts.emplace_back(*txout);187} else {188return TxSize{-1, -1};189}190}191return CalculateMaximumSignedTxSize(tx, wallet, txouts, coin_control);192}194size_t CoinsResult::Size() const195{196size_t size{0};197for (const auto& it : coins) {198size += it.second.size();199}200return size;201}203std::vector<COutput> CoinsResult::All() const204{205std::vector<COutput> all;206all.reserve(Size());207for (const auto& it : coins) {208all.insert(all.end(), it.second.begin(), it.second.end());209}210return all;211}213void CoinsResult::Erase(const std::unordered_set<COutPoint, SaltedOutpointHasher>& coins_to_remove)214{215for (auto& [type, vec] : coins) {216auto remove_it = std::remove_if(vec.begin(), vec.end(), [&](const COutput& coin) {217// remove it if it's on the set218if (!coins_to_remove.contains(coin.outpoint)) return false;220// update cached amounts221total_amount -= coin.txout.nValue;222if (coin.HasEffectiveValue() && total_effective_amount.has_value()) total_effective_amount = *total_effective_amount - coin.GetEffectiveValue();223return true;224});225vec.erase(remove_it, vec.end());226}227}229void CoinsResult::Shuffle(FastRandomContext& rng_fast)230{231for (auto& it : coins) {232std::shuffle(it.second.begin(), it.second.end(), rng_fast);233}234}236void CoinsResult::Add(OutputType type, const COutput& out)237{238coins[type].emplace_back(out);239total_amount += out.txout.nValue;240if (out.HasEffectiveValue()) {241total_effective_amount = total_effective_amount.has_value() ?242*total_effective_amount + out.GetEffectiveValue() : out.GetEffectiveValue();243}244}246static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)247{248switch (type) {249case TxoutType::WITNESS_V1_TAPROOT:250return OutputType::BECH32M;