LCOV - code coverage report
Current view: top level - src/consensus - tx_check.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 42 44 95.5 %
Date: 2026-06-25 07:23:51 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2017-2021 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 <version.h>
       6             : 
       7             : #include <consensus/consensus.h>
       8             : #include <consensus/tx_check.h>
       9             : 
      10             : #include <consensus/amount.h>
      11             : #include <primitives/transaction.h>
      12             : #include <consensus/validation.h>
      13             : 
      14      121714 : bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
      15             : {
      16      121714 :     bool allowEmptyTxIn = false;
      17      121714 :     bool allowEmptyTxOut = false;
      18      121714 :     if (tx.nType == TRANSACTION_QUORUM_COMMITMENT || tx.nType == TRANSACTION_MNHF_SIGNAL) {
      19       43635 :         allowEmptyTxIn = true;
      20       43635 :         allowEmptyTxOut = true;
      21       43635 :     }
      22      121714 :     if (tx.nType == TRANSACTION_ASSET_UNLOCK) {
      23           1 :         allowEmptyTxIn = true;
      24           1 :     }
      25             : 
      26             :     // Basic checks that don't depend on any context
      27      121714 :     if (!allowEmptyTxIn && tx.vin.empty())
      28           1 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty");
      29      121713 :     if (!allowEmptyTxOut && tx.vout.empty())
      30           1 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-empty");
      31             :     // Size limits
      32      121712 :     if (::GetSerializeSize(tx, PROTOCOL_VERSION) > MAX_LEGACY_BLOCK_SIZE)
      33           0 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");
      34      121712 :     if (tx.vExtraPayload.size() > MAX_TX_EXTRA_PAYLOAD)
      35           0 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-payload-oversize");
      36             : 
      37             :     // Check for negative or overflow output values (see CVE-2010-5139)
      38      121712 :     CAmount nValueOut = 0;
      39      228932 :     for (const auto& txout : tx.vout) {
      40      107223 :         if (txout.nValue < 0)
      41           1 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative");
      42      107222 :         if (txout.nValue > MAX_MONEY)
      43           1 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge");
      44      107221 :         nValueOut += txout.nValue;
      45      107221 :         if (!MoneyRange(nValueOut))
      46           1 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge");
      47             :     }
      48             : 
      49             :     // Check for duplicate inputs (see CVE-2018-17144)
      50             :     // While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs
      51             :     // of a tx as spent, it does not check if the tx has duplicate inputs.
      52             :     // Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of
      53             :     // the underlying coins database.
      54      121709 :     std::set<COutPoint> vInOutPoints;
      55      201604 :     for (const auto& txin : tx.vin) {
      56       79897 :         if (!vInOutPoints.insert(txin.prevout).second)
      57           2 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
      58             :     }
      59             : 
      60      121707 :     if (tx.IsCoinBase()) {
      61       74163 :         size_t minCbSize = 2;
      62       74163 :         if (tx.nType == TRANSACTION_COINBASE) {
      63             :             // With the introduction of CbTx, coinbase scripts are not required anymore to hold a valid block height
      64       27391 :             minCbSize = 1;
      65       27391 :         }
      66       74163 :         if (tx.vin[0].scriptSig.size() < minCbSize || tx.vin[0].scriptSig.size() > 100)
      67           2 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
      68       74161 :     } else {
      69       53271 :         for (const auto& txin : tx.vin)
      70        5729 :             if (txin.prevout.IsNull())
      71           2 :                 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");
      72             :     }
      73             : 
      74      121703 :     return true;
      75      121714 : }

Generated by: LCOV version 1.16