MCPcopy Create free account
hub / github.com/ElementsProject/elements / CheckTransaction

Function CheckTransaction

src/consensus/tx_check.cpp:11–69  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

9#include <consensus/validation.h>
10
11bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
12{
13 // Basic checks that don't depend on any context
14 if (tx.vin.empty())
15 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty");
16 if (tx.vout.empty())
17 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 if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
20 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");
21
22 // Check for negative or overflow output values (see CVE-2010-5139)
23 CAmount nValueOutExplicit = 0;
24 for (const auto& txout : tx.vout)
25 {
26 if (!txout.nValue.IsValid())
27 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-amount-invalid");
28 if (!txout.nValue.IsExplicit())
29 continue;
30 if (txout.nValue.GetAmount() < 0)
31 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative");
32 if (txout.nValue.GetAmount() > MAX_MONEY)
33 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge");
34 nValueOutExplicit += txout.nValue.GetAmount();
35 if (!MoneyRange(nValueOutExplicit))
36 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge");
37 }
38
39 // Check for duplicate inputs (see CVE-2018-17144)
40 // While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs
41 // of a tx as spent, it does not check if the tx has duplicate inputs.
42 // Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of
43 // the underlying coins database.
44 std::set<COutPoint> vInOutPoints;
45 for (const auto& txin : tx.vin) {
46 if (!vInOutPoints.insert(txin.prevout).second)
47 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
48 }
49
50 if (tx.IsCoinBase())
51 {
52 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
53 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
54
55 for (unsigned int i = 0; i < tx.vout.size(); i++) {
56 if (tx.vout[i].IsFee()) {
57 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-fee");
58 }
59 }
60 }
61 else
62 {
63 for (const auto& txin : tx.vin)
64 if (txin.prevout.IsNull())
65 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");
66 }
67
68 return true;

Callers 6

PreChecksMethod · 0.85
CheckBlockFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
FUZZ_TARGET_INITFunction · 0.85
FUZZ_TARGET_INITFunction · 0.85

Calls 12

GetSerializeSizeFunction · 0.85
InvalidMethod · 0.80
IsExplicitMethod · 0.80
GetAmountMethod · 0.80
IsFeeMethod · 0.80
MoneyRangeFunction · 0.70
emptyMethod · 0.45
IsValidMethod · 0.45
insertMethod · 0.45
IsCoinBaseMethod · 0.45
sizeMethod · 0.45
IsNullMethod · 0.45

Tested by 4

BOOST_AUTO_TEST_CASEFunction · 0.68
BOOST_AUTO_TEST_CASEFunction · 0.68
FUZZ_TARGET_INITFunction · 0.68
FUZZ_TARGET_INITFunction · 0.68