Line data Source code
1 : // Copyright (c) 2017-2019 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 <primitives/transaction.h> 8 : #include <consensus/validation.h> 9 : 10 208910 : bool CheckTransaction(const CTransaction& tx, TxValidationState& state) 11 : { 12 : // Basic checks that don't depend on any context 13 208910 : if (tx.vin.empty()) 14 2 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty"); 15 208908 : if (tx.vout.empty()) 16 6 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-empty"); 17 : // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) 18 208902 : if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) 19 1 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize"); 20 : 21 : // Check for negative or overflow output values (see CVE-2010-5139) 22 208901 : CAmount nValueOut = 0; 23 820116 : for (const auto& txout : tx.vout) 24 : { 25 611215 : if (txout.nValue < 0) 26 4 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative"); 27 611211 : if (txout.nValue > MAX_MONEY) 28 4 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge"); 29 611207 : nValueOut += txout.nValue; 30 611207 : if (!MoneyRange(nValueOut)) 31 4 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge"); 32 611203 : } 33 : 34 : // Check for duplicate inputs (see CVE-2018-17144) 35 : // While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs 36 : // of a tx as spent, it does not check if the tx has duplicate inputs. 37 : // Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of 38 : // the underlying coins database. 39 208889 : std::set<COutPoint> vInOutPoints; 40 794215 : for (const auto& txin : tx.vin) { 41 585326 : if (!vInOutPoints.insert(txin.prevout).second) 42 136 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate"); 43 585190 : } 44 : 45 208753 : if (tx.IsCoinBase()) 46 : { 47 95817 : if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) 48 4 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length"); 49 : } 50 : else 51 : { 52 335026 : for (const auto& txin : tx.vin) 53 222090 : if (txin.prevout.IsNull()) 54 222090 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null"); 55 : } 56 : 57 208747 : return true; 58 208910 : }