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 1003366 : bool CheckTransaction(const CTransaction& tx, TxValidationState& state) 15 : { 16 1003366 : bool allowEmptyTxIn = false; 17 1003366 : bool allowEmptyTxOut = false; 18 1003366 : if (tx.nType == TRANSACTION_QUORUM_COMMITMENT || tx.nType == TRANSACTION_MNHF_SIGNAL) { 19 308795 : allowEmptyTxIn = true; 20 308795 : allowEmptyTxOut = true; 21 308795 : } 22 1003366 : if (tx.nType == TRANSACTION_ASSET_UNLOCK) { 23 554 : allowEmptyTxIn = true; 24 554 : } 25 : 26 : // Basic checks that don't depend on any context 27 1003366 : if (!allowEmptyTxIn && tx.vin.empty()) 28 8 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty"); 29 1003358 : if (!allowEmptyTxOut && tx.vout.empty()) 30 10 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-empty"); 31 : // Size limits 32 1003348 : if (::GetSerializeSize(tx, PROTOCOL_VERSION) > MAX_LEGACY_BLOCK_SIZE) 33 2 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize"); 34 1003346 : 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 1003346 : CAmount nValueOut = 0; 39 2915711 : for (const auto& txout : tx.vout) { 40 1912395 : if (txout.nValue < 0) 41 10 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative"); 42 1912385 : if (txout.nValue > MAX_MONEY) 43 10 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge"); 44 1912375 : nValueOut += txout.nValue; 45 1912375 : if (!MoneyRange(nValueOut)) 46 10 : 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 1003316 : std::set<COutPoint> vInOutPoints; 55 1871852 : for (const auto& txin : tx.vin) { 56 870753 : if (!vInOutPoints.insert(txin.prevout).second) 57 2217 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate"); 58 : } 59 : 60 1001099 : if (tx.IsCoinBase()) { 61 471462 : size_t minCbSize = 2; 62 471462 : if (tx.nType == TRANSACTION_COINBASE) { 63 : // With the introduction of CbTx, coinbase scripts are not required anymore to hold a valid block height 64 219019 : minCbSize = 1; 65 219019 : } 66 471462 : if (tx.vin[0].scriptSig.size() < minCbSize || tx.vin[0].scriptSig.size() > 100) 67 8 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length"); 68 471454 : } else { 69 924482 : for (const auto& txin : tx.vin) 70 394856 : if (txin.prevout.IsNull()) 71 11 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null"); 72 : } 73 : 74 1001080 : return true; 75 1003366 : }