Coverage Report

Created: 2026-07-14 18:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/consensus/tx_check.cpp
Line
Count
Source
1
// Copyright (c) 2017-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <consensus/tx_check.h>
6
7
#include <consensus/amount.h>
8
#include <primitives/transaction.h>
9
#include <consensus/validation.h>
10
11
bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
12
3.12M
{
13
    // Basic checks that don't depend on any context
14
3.12M
    if (tx.vin.empty())
  Branch (14:9): [True: 16, False: 3.12M]
15
16
        return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty");
16
3.12M
    if (tx.vout.empty())
  Branch (16:9): [True: 952, False: 3.12M]
17
952
        return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-empty");
18
    // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
19
3.12M
    if (::GetSerializeSize(TX_NO_WITNESS(tx)) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) {
  Branch (19:9): [True: 0, False: 3.12M]
20
0
        return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");
21
0
    }
22
23
    // Check for negative or overflow output values (see CVE-2010-5139)
24
3.12M
    CAmount nValueOut = 0;
25
3.12M
    for (const auto& txout : tx.vout)
  Branch (25:28): [True: 3.87M, False: 3.12M]
26
3.87M
    {
27
3.87M
        if (txout.nValue < 0)
  Branch (27:13): [True: 0, False: 3.87M]
28
0
            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative");
29
3.87M
        if (txout.nValue > MAX_MONEY)
  Branch (29:13): [True: 0, False: 3.87M]
30
0
            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge");
31
3.87M
        nValueOut += txout.nValue;
32
3.87M
        if (!MoneyRange(nValueOut))
  Branch (32:13): [True: 0, False: 3.87M]
33
0
            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge");
34
3.87M
    }
35
36
    // Check for duplicate inputs (see CVE-2018-17144)
37
    // While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs
38
    // of a tx as spent, it does not check if the tx has duplicate inputs.
39
    // Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of
40
    // the underlying coins database.
41
3.12M
    std::set<COutPoint> vInOutPoints;
42
3.49M
    for (const auto& txin : tx.vin) {
  Branch (42:27): [True: 3.49M, False: 3.12M]
43
3.49M
        if (!vInOutPoints.insert(txin.prevout).second)
  Branch (43:13): [True: 2.95k, False: 3.48M]
44
2.95k
            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
45
3.49M
    }
46
47
3.12M
    if (tx.IsCoinBase())
  Branch (47:9): [True: 156k, False: 2.96M]
48
156k
    {
49
156k
        if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
  Branch (49:13): [True: 0, False: 156k]
  Branch (49:47): [True: 0, False: 156k]
50
0
            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
51
156k
    }
52
2.96M
    else
53
2.96M
    {
54
2.96M
        for (const auto& txin : tx.vin)
  Branch (54:31): [True: 3.32M, False: 2.96M]
55
3.32M
            if (txin.prevout.IsNull())
  Branch (55:17): [True: 0, False: 3.32M]
56
0
                return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");
57
2.96M
    }
58
59
3.12M
    return true;
60
3.12M
}