Line data Source code
1 : // Copyright (c) 2017-2017 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 "tx_verify.h"
6 :
7 : #include "consensus/consensus.h"
8 : #include "consensus/zerocoin_verify.h"
9 : #include "sapling/sapling_validation.h"
10 : #include "../validation.h"
11 :
12 9942925 : bool IsFinalTx(const CTransactionRef& tx, int nBlockHeight, int64_t nBlockTime)
13 : {
14 : // Time based nLockTime implemented in 0.1.6
15 9942925 : if (tx->nLockTime == 0)
16 : return true;
17 12 : if (nBlockTime == 0)
18 4 : nBlockTime = GetAdjustedTime();
19 12 : if ((int64_t)tx->nLockTime < ((int64_t)tx->nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
20 : return true;
21 8 : for (const CTxIn& txin : tx->vin)
22 8 : if (!txin.IsFinal())
23 8 : return false;
24 0 : return true;
25 : }
26 :
27 1384332 : unsigned int GetLegacySigOpCount(const CTransaction& tx)
28 : {
29 1384332 : unsigned int nSigOps = 0;
30 3855756 : for (const CTxIn& txin : tx.vin) {
31 2471424 : nSigOps += txin.scriptSig.GetSigOpCount(false);
32 : }
33 5022511 : for (const CTxOut& txout : tx.vout) {
34 3638189 : nSigOps += txout.scriptPubKey.GetSigOpCount(false);
35 : }
36 1384332 : return nSigOps;
37 : }
38 :
39 600054 : unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
40 : {
41 600054 : if (tx.IsCoinBase() || tx.HasZerocoinSpendInputs())
42 : // a tx containing a zc spend can have only zc inputs
43 0 : return 0;
44 :
45 : unsigned int nSigOps = 0;
46 1723716 : for (unsigned int i = 0; i < tx.vin.size(); i++) {
47 1123667 : const CTxOut& prevout = inputs.AccessCoin(tx.vin[i].prevout).out;
48 1123667 : if (prevout.scriptPubKey.IsPayToScriptHash())
49 62401 : nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
50 : }
51 : return nSigOps;
52 : }
53 :
54 891273 : bool CheckTransaction(const CTransaction& tx, CValidationState& state, bool fColdStakingActive)
55 : {
56 : // Basic checks that don't depend on any context
57 : // Transactions containing empty `vin` must have non-empty `vShieldedSpend`,
58 : // or they must be quorum commitments (only one per-type allowed in a block)
59 891273 : if (tx.vin.empty() && (tx.sapData && tx.sapData->vShieldedSpend.empty()) && !tx.IsQuorumCommitmentTx())
60 6 : return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty");
61 : // Transactions containing empty `vout` must have non-empty `vShieldedOutput`,
62 : // or they must be quorum commitments (only one per-type allowed in a block)
63 891271 : if (tx.vout.empty() && (tx.sapData && tx.sapData->vShieldedOutput.empty()) && !tx.IsQuorumCommitmentTx())
64 6 : return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
65 :
66 : // Version check
67 891269 : if (tx.nVersion < 1 || tx.nVersion >= CTransaction::TxVersion::TOOHIGH) {
68 0 : return state.DoS(10,
69 0 : error("%s: Transaction version (%d) too high. Max: %d", __func__, tx.nVersion, int(CTransaction::TxVersion::TOOHIGH) - 1),
70 : REJECT_INVALID, "bad-tx-version-too-high");
71 : }
72 :
73 : // Size limits
74 891269 : static_assert(MAX_BLOCK_SIZE_CURRENT >= MAX_TX_SIZE_AFTER_SAPLING, "Max block size must be bigger than max TX size"); // sanity
75 891269 : static_assert(MAX_TX_SIZE_AFTER_SAPLING > MAX_ZEROCOIN_TX_SIZE, "New max TX size must be bigger than old max TX size"); // sanity
76 891269 : const unsigned int nMaxSize = tx.IsShieldedTx() ? MAX_TX_SIZE_AFTER_SAPLING : MAX_ZEROCOIN_TX_SIZE;
77 891269 : if (tx.GetTotalSize() > nMaxSize) {
78 0 : return state.DoS(10, error("tx oversize: %d > %d", tx.GetTotalSize(), nMaxSize), REJECT_INVALID, "bad-txns-oversize");
79 : }
80 :
81 : // Dispatch to Sapling validator
82 891269 : CAmount nValueOut = 0;
83 891269 : if (!SaplingValidation::CheckTransaction(tx, state, nValueOut)) {
84 : return false;
85 : }
86 :
87 : // Check for negative or overflow output values
88 891267 : const Consensus::Params& consensus = Params().GetConsensus();
89 3272544 : for (const CTxOut& txout : tx.vout) {
90 2398441 : if (txout.IsEmpty() && !tx.IsCoinBase() && !tx.IsCoinStake())
91 54 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-empty");
92 2381278 : if (txout.nValue < 0)
93 3 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative");
94 2381277 : if (txout.nValue > consensus.nMaxMoneyOut)
95 3 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge");
96 2381276 : nValueOut += txout.nValue;
97 2381276 : if (!consensus.MoneyRange(nValueOut))
98 3 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge");
99 : // check cold staking enforcement (for delegations) and value out
100 2381275 : if (txout.scriptPubKey.IsPayToColdStaking()) {
101 209 : if (!fColdStakingActive)
102 3 : return state.DoS(10, false, REJECT_INVALID, "cold-stake-inactive");
103 208 : if (txout.nValue < MIN_COLDSTAKING_AMOUNT)
104 0 : return state.DoS(100, false, REJECT_INVALID, "cold-stake-vout-toosmall");
105 : }
106 : }
107 :
108 1782523 : std::set<COutPoint> vInOutPoints;
109 2510476 : for (const CTxIn& txin : tx.vin) {
110 : // Check for duplicate inputs
111 1619230 : if (vInOutPoints.count(txin.prevout))
112 12 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate");
113 1619228 : if (!txin.IsZerocoinSpend()) {
114 3238454 : vInOutPoints.insert(txin.prevout);
115 : }
116 : }
117 :
118 891241 : bool hasExchangeUTXOs = tx.HasExchangeAddr();
119 :
120 891241 : if (tx.IsCoinBase()) {
121 73445 : if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 150)
122 4 : return state.DoS(100, false, REJECT_INVALID, "bad-cb-length");
123 73122 : if (hasExchangeUTXOs)
124 0 : return state.DoS(100, false, REJECT_INVALID, "bad-exchange-address-in-cb");
125 : } else {
126 2364218 : for (const CTxIn& txin : tx.vin)
127 3099108 : if (txin.prevout.IsNull() && !txin.IsZerocoinSpend())
128 0 : return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null");
129 : }
130 :
131 : return true;
132 : }
133 :
134 663440 : bool ContextualCheckTransaction(const CTransactionRef& tx, CValidationState& state, const CChainParams& chainparams, int nHeight, bool isMined, bool fIBD)
135 : {
136 : // Dispatch to Sapling validator
137 663440 : if (!SaplingValidation::ContextualCheckTransaction(*tx, state, chainparams, nHeight, isMined, fIBD)) {
138 : return false; // Failure reason has been set in validation state object
139 : }
140 :
141 : // Dispatch to ZerocoinTx validator
142 663439 : if (!ContextualCheckZerocoinTx(tx, state, chainparams.GetConsensus(), nHeight, isMined)) {
143 6 : return false; // Failure reason has been set in validation state object
144 : }
145 :
146 : return true;
147 : }
|