Branch data Line data Source code
1 : : // Copyright (c) 2017-present 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_verify.h>
6 : :
7 : : #include <chain.h>
8 : : #include <coins.h>
9 : : #include <consensus/amount.h>
10 : : #include <consensus/consensus.h>
11 : : #include <consensus/validation.h>
12 : : #include <primitives/transaction.h>
13 : : #include <script/interpreter.h>
14 : : #include <script/script.h>
15 : : #include <tinyformat.h>
16 : : #include <util/check.h>
17 : : #include <util/moneystr.h>
18 : :
19 : : #include <algorithm>
20 : : #include <cstddef>
21 : : #include <string>
22 : :
23 : 3800084 : bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
24 : : {
25 [ + + ]: 3800084 : if (tx.nLockTime == 0)
26 : : return true;
27 [ + + + + ]: 1625357 : if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
28 : : return true;
29 : :
30 : : // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a
31 : : // transaction is still considered final if all inputs' nSequence ==
32 : : // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored.
33 : : //
34 : : // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will
35 : : // also check that the spending input's nSequence != SEQUENCE_FINAL,
36 : : // ensuring that an unsatisfied nLockTime value will actually cause
37 : : // IsFinalTx() to return false here:
38 [ + + ]: 1390517 : for (const auto& txin : tx.vin) {
39 [ + + ]: 803989 : if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
40 : : return false;
41 : : }
42 : : return true;
43 : : }
44 : :
45 : 1790487 : std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
46 : : {
47 [ - + - + : 1790487 : assert(prevHeights.size() == tx.vin.size());
- + ]
48 : :
49 : : // Will be set to the equivalent height- and time-based nLockTime
50 : : // values that would be necessary to satisfy all relative lock-
51 : : // time constraints given our view of block chain history.
52 : : // The semantics of nLockTime are the last invalid height/time, so
53 : : // use -1 to have the effect of any height or time being valid.
54 : 1790487 : int nMinHeight = -1;
55 : 1790487 : int64_t nMinTime = -1;
56 : :
57 [ + + - + ]: 1790487 : bool fEnforceBIP68 = tx.version >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE;
58 : :
59 : : // Do not enforce sequence numbers as a relative lock time
60 : : // unless we have been instructed to
61 : 555 : if (!fEnforceBIP68) {
62 : 555 : return std::make_pair(nMinHeight, nMinTime);
63 : : }
64 : :
65 [ - + + + ]: 8218115 : for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
66 [ + + ]: 6428183 : const CTxIn& txin = tx.vin[txinIndex];
67 : :
68 : : // Sequence numbers with the most significant bit set are not
69 : : // treated as relative lock-times, nor are they given any
70 : : // consensus-enforced meaning at this point.
71 [ + + ]: 6428183 : if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
72 : : // The height of this input is not relevant for sequence locks
73 : 5444027 : prevHeights[txinIndex] = 0;
74 : 5444027 : continue;
75 : : }
76 : :
77 [ + + ]: 984156 : int nCoinHeight = prevHeights[txinIndex];
78 : :
79 [ + + ]: 984156 : if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
80 [ + - - + ]: 185208 : const int64_t nCoinTime{Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))->GetMedianTimePast()};
81 : : // NOTE: Subtract 1 to maintain nLockTime semantics
82 : : // BIP 68 relative lock times have the semantics of calculating
83 : : // the first block or time at which the transaction would be
84 : : // valid. When calculating the effective block time or height
85 : : // for the entire transaction, we switch to using the
86 : : // semantics of nLockTime which is the last invalid block
87 : : // time or height. Thus we subtract 1 from the calculated
88 : : // time or height.
89 : :
90 : : // Time-based relative lock-times are measured from the
91 : : // smallest allowed timestamp of the block containing the
92 : : // txout being spent, which is the median time past of the
93 : : // block prior.
94 [ + + ]: 141496 : nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
95 : : } else {
96 [ + + ]: 1528231 : nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
97 : : }
98 : : }
99 : :
100 : 1789932 : return std::make_pair(nMinHeight, nMinTime);
101 : : }
102 : :
103 : 1790487 : bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
104 : : {
105 [ - + ]: 1790487 : assert(block.pprev);
106 : 1790487 : int64_t nBlockTime = block.pprev->GetMedianTimePast();
107 [ + + + + ]: 1790487 : if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
108 : 71664 : return false;
109 : :
110 : : return true;
111 : : }
112 : :
113 : 63955 : bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
114 : : {
115 : 63955 : return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
116 : : }
117 : :
118 : 4123845 : unsigned int GetLegacySigOpCount(const CTransaction& tx)
119 : : {
120 : 4123845 : unsigned int nSigOps = 0;
121 [ + + ]: 11247860 : for (const auto& txin : tx.vin)
122 : : {
123 : 7124015 : nSigOps += txin.scriptSig.GetSigOpCount(false);
124 : : }
125 [ + + ]: 27409067 : for (const auto& txout : tx.vout)
126 : : {
127 : 23285222 : nSigOps += txout.scriptPubKey.GetSigOpCount(false);
128 : : }
129 : 4123845 : return nSigOps;
130 : : }
131 : :
132 : 1693170 : unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
133 : : {
134 [ + + ]: 1693170 : if (tx.IsCoinBase())
135 : : return 0;
136 : :
137 : : unsigned int nSigOps = 0;
138 [ - + + + ]: 5976514 : for (unsigned int i = 0; i < tx.vin.size(); i++)
139 : : {
140 : 4283349 : const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
141 [ - + ]: 4283349 : assert(!coin.IsSpent());
142 : 4283349 : const CTxOut &prevout = coin.out;
143 [ + + ]: 4283349 : if (prevout.scriptPubKey.IsPayToScriptHash())
144 : 819 : nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
145 : : }
146 : : return nSigOps;
147 : : }
148 : :
149 : 2562116 : int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, script_verify_flags flags)
150 : : {
151 : 2562116 : int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
152 : :
153 [ + + ]: 2562116 : if (tx.IsCoinBase())
154 : : return nSigOps;
155 : :
156 [ + + ]: 1691676 : if (flags & SCRIPT_VERIFY_P2SH) {
157 : 1691476 : nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
158 : : }
159 : :
160 [ - + + + ]: 5974984 : for (unsigned int i = 0; i < tx.vin.size(); i++)
161 : : {
162 : 4283308 : const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
163 [ - + ]: 4283308 : assert(!coin.IsSpent());
164 : 4283308 : const CTxOut &prevout = coin.out;
165 : 4283308 : nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, tx.vin[i].scriptWitness, flags);
166 : : }
167 : : return nSigOps;
168 : : }
169 : :
170 : 2168952 : bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
171 : : {
172 : : // are the actual inputs available?
173 [ + + ]: 2168952 : if (!inputs.HaveInputs(tx)) {
174 [ + - + - ]: 8081 : return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
175 : 16162 : strprintf("%s: inputs missing/spent", __func__));
176 : : }
177 : :
178 : : CAmount nValueIn = 0;
179 [ - + + + ]: 7247107 : for (unsigned int i = 0; i < tx.vin.size(); ++i) {
180 : 5092596 : const COutPoint &prevout = tx.vin[i].prevout;
181 : 5092596 : const Coin& coin = inputs.AccessCoin(prevout);
182 [ - + ]: 5092596 : assert(!coin.IsSpent());
183 : :
184 : : // If prev is coinbase, check that it's matured
185 [ + + + + ]: 5092596 : if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
186 [ + - + - ]: 6349 : return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
187 : 12698 : strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
188 : : }
189 : :
190 : : // Check for negative or overflow input values
191 : 5086247 : nValueIn += coin.out.nValue;
192 [ + + + - ]: 5086247 : if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
193 [ + - + - ]: 11 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
194 : : }
195 : : }
196 : :
197 : : // `tx.GetValueOut()` won't throw in validation paths because output-range checks run first
198 : : // (`bad-txns-vout-negative`, `bad-txns-vout-toolarge`, `bad-txns-txouttotal-toolarge`):
199 : : // * `MemPoolAccept::PreChecks`: `CheckTransaction()` is called before this method;
200 : : // * `Chainstate::ConnectBlock`: `CheckTransaction()` is called via `CheckBlock()` before this method.
201 : 2154511 : const CAmount value_out = tx.GetValueOut();
202 [ + + ]: 2154511 : if (nValueIn < value_out) {
203 [ + - + - ]: 16841 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
204 [ + - + - ]: 33682 : strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
205 : : }
206 : :
207 : : // Tally transaction fees
208 : 2137670 : const CAmount txfee_aux = nValueIn - value_out;
209 [ - + ]: 2137670 : if (!MoneyRange(txfee_aux)) {
210 : : // Unreachable, given the following preconditions:
211 : : // * `value_out` comes from `tx.GetValueOut()`, which throws unless `MoneyRange(value_out)` and asserts `MoneyRange(nValueOut)` on return.
212 : : // * `MoneyRange(nValueIn)` was enforced in the input loop.
213 : : // * `nValueIn < value_out` was handled above, so `nValueIn >= value_out` here (and `txfee_aux >= 0`).
214 : : // Therefore `0 <= txfee_aux = nValueIn - value_out <= nValueIn <= MAX_MONEY`.
215 [ # # # # ]: 0 : return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
216 : : }
217 : :
218 : 2137670 : txfee = txfee_aux;
219 : 2137670 : return true;
220 : : }
|