Branch data 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 <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 : 247959 : { # 13 : : // Basic checks that don't depend on any context # 14 [ + + ]: 247959 : if (tx.vin.empty()) # 15 : 2 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty"); # 16 [ + + ]: 247957 : if (tx.vout.empty()) # 17 : 5 : 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 [ + + ]: 247952 : if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) # 20 : 1 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize"); # 21 : : # 22 : : // Check for negative or overflow output values (see CVE-2010-5139) # 23 : 247951 : CAmount nValueOut = 0; # 24 [ + + ]: 247951 : for (const auto& txout : tx.vout) # 25 : 833965 : { # 26 [ + + ]: 833965 : if (txout.nValue < 0) # 27 : 5 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative"); # 28 [ + + ]: 833960 : if (txout.nValue > MAX_MONEY) # 29 : 5 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge"); # 30 : 833955 : nValueOut += txout.nValue; # 31 [ + + ]: 833955 : if (!MoneyRange(nValueOut)) # 32 : 5 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge"); # 33 : 833955 : } # 34 : : # 35 : : // Check for duplicate inputs (see CVE-2018-17144) # 36 : : // While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs # 37 : : // of a tx as spent, it does not check if the tx has duplicate inputs. # 38 : : // Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of # 39 : : // the underlying coins database. # 40 : 247936 : std::set<COutPoint> vInOutPoints; # 41 [ + + ]: 338149 : for (const auto& txin : tx.vin) { # 42 [ + + ]: 338149 : if (!vInOutPoints.insert(txin.prevout).second) # 43 : 320 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate"); # 44 : 338149 : } # 45 : : # 46 [ + + ]: 247616 : if (tx.IsCoinBase()) # 47 : 131611 : { # 48 [ + + ][ + + ]: 131611 : if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) # 49 : 6 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length"); # 50 : 131611 : } # 51 : 116005 : else # 52 : 116005 : { # 53 [ + + ]: 116005 : for (const auto& txin : tx.vin) # 54 [ + + ]: 205896 : if (txin.prevout.IsNull()) # 55 : 7 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null"); # 56 : 116005 : } # 57 : : # 58 : 247603 : return true; # 59 : 247616 : }