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 : 1327116 : bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
12 : : {
13 : : // Basic checks that don't depend on any context
14 [ + + ]: 1327116 : if (tx.vin.empty())
15 [ + - + - ]: 56262 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty");
16 [ + + ]: 1270854 : if (tx.vout.empty())
17 [ + - + - ]: 24190 : 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 [ + + ]: 1246664 : if (::GetSerializeSize(TX_NO_WITNESS(tx)) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) {
20 [ + - + - ]: 82 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");
21 : : }
22 : :
23 : : // Check for negative or overflow output values (see CVE-2010-5139)
24 : 1246582 : CAmount nValueOut = 0;
25 [ + + ]: 17569735 : for (const auto& txout : tx.vout)
26 : : {
27 [ + + ]: 16428207 : if (txout.nValue < 0)
28 [ + - + - ]: 2422 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative");
29 [ + + ]: 16425785 : if (txout.nValue > MAX_MONEY)
30 [ + - + - ]: 102389 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge");
31 : 16323396 : nValueOut += txout.nValue;
32 [ + + ]: 16323396 : if (!MoneyRange(nValueOut))
33 [ + - + - ]: 243 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge");
34 : : }
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 : 1141528 : std::set<COutPoint> vInOutPoints;
42 [ + + ]: 11225654 : for (const auto& txin : tx.vin) {
43 [ + - + + ]: 10133119 : if (!vInOutPoints.insert(txin.prevout).second)
44 [ + - + - : 48993 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
+ - ]
45 : : }
46 : :
47 [ + + ]: 1092535 : if (tx.IsCoinBase())
48 : : {
49 [ + + + + : 1143982 : if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
+ + + + ]
50 [ + - + - : 600 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
+ - ]
51 : : }
52 : : else
53 : : {
54 [ + + ]: 7881282 : for (const auto& txin : tx.vin)
55 [ + + ]: 7146266 : if (txin.prevout.IsNull())
56 [ + - + - : 13195 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");
+ - ]
57 : : }
58 : :
59 : : return true;
60 : 1141528 : }
|