/tmp/bitcoin/src/consensus/tx_verify.cpp
Line | Count | Source |
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 | | bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) |
24 | 277k | { |
25 | 277k | if (tx.nLockTime == 0) |
26 | 105k | return true; |
27 | 172k | if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) |
28 | 172k | 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 | 44 | for (const auto& txin : tx.vin) { |
39 | 44 | if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL)) |
40 | 39 | return false; |
41 | 44 | } |
42 | 5 | return true; |
43 | 44 | } |
44 | | |
45 | | std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) |
46 | 106k | { |
47 | 106k | 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 | 106k | int nMinHeight = -1; |
55 | 106k | int64_t nMinTime = -1; |
56 | | |
57 | 106k | 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 | 106k | if (!fEnforceBIP68) { |
62 | 2.95k | return std::make_pair(nMinHeight, nMinTime); |
63 | 2.95k | } |
64 | | |
65 | 266k | for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { |
66 | 162k | 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 | 162k | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) { |
72 | | // The height of this input is not relevant for sequence locks |
73 | 47.3k | prevHeights[txinIndex] = 0; |
74 | 47.3k | continue; |
75 | 47.3k | } |
76 | | |
77 | 115k | int nCoinHeight = prevHeights[txinIndex]; |
78 | | |
79 | 115k | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) { |
80 | 340 | 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 | 340 | nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1); |
95 | 115k | } else { |
96 | 115k | nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1); |
97 | 115k | } |
98 | 115k | } |
99 | | |
100 | 103k | return std::make_pair(nMinHeight, nMinTime); |
101 | 106k | } |
102 | | |
103 | | bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair) |
104 | 108k | { |
105 | 108k | assert(block.pprev); |
106 | 108k | int64_t nBlockTime = block.pprev->GetMedianTimePast(); |
107 | 108k | if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime) |
108 | 384 | return false; |
109 | | |
110 | 108k | return true; |
111 | 108k | } |
112 | | |
113 | | bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) |
114 | 62.0k | { |
115 | 62.0k | return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block)); |
116 | 62.0k | } |
117 | | |
118 | | unsigned int GetLegacySigOpCount(const CTransaction& tx) |
119 | 579k | { |
120 | 579k | unsigned int nSigOps = 0; |
121 | 579k | for (const auto& txin : tx.vin) |
122 | 688k | { |
123 | 688k | nSigOps += txin.scriptSig.GetSigOpCount(false); |
124 | 688k | } |
125 | 579k | for (const auto& txout : tx.vout) |
126 | 1.44M | { |
127 | 1.44M | nSigOps += txout.scriptPubKey.GetSigOpCount(false); |
128 | 1.44M | } |
129 | 579k | return nSigOps; |
130 | 579k | } |
131 | | |
132 | | unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs) |
133 | 105k | { |
134 | 105k | if (tx.IsCoinBase()) |
135 | 1 | return 0; |
136 | | |
137 | 105k | unsigned int nSigOps = 0; |
138 | 270k | for (unsigned int i = 0; i < tx.vin.size(); i++) |
139 | 164k | { |
140 | 164k | const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); |
141 | 164k | assert(!coin.IsSpent()); |
142 | 164k | const CTxOut &prevout = coin.out; |
143 | 164k | if (prevout.scriptPubKey.IsPayToScriptHash()) |
144 | 11.1k | nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig); |
145 | 164k | } |
146 | 105k | return nSigOps; |
147 | 105k | } |
148 | | |
149 | | int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, script_verify_flags flags) |
150 | 268k | { |
151 | 268k | int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR; |
152 | | |
153 | 268k | if (tx.IsCoinBase()) |
154 | 162k | return nSigOps; |
155 | | |
156 | 105k | if (flags & SCRIPT_VERIFY_P2SH) { |
157 | 105k | nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR; |
158 | 105k | } |
159 | | |
160 | 269k | for (unsigned int i = 0; i < tx.vin.size(); i++) |
161 | 164k | { |
162 | 164k | const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); |
163 | 164k | assert(!coin.IsSpent()); |
164 | 164k | const CTxOut &prevout = coin.out; |
165 | 164k | nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, tx.vin[i].scriptWitness, flags); |
166 | 164k | } |
167 | 105k | return nSigOps; |
168 | 105k | } |
169 | | |
170 | | bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee) |
171 | 11.0M | { |
172 | | // are the actual inputs available? |
173 | 11.0M | if (!inputs.HaveInputs(tx)) { |
174 | 324 | return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent", |
175 | 324 | strprintf("%s: inputs missing/spent", __func__)); |
176 | 324 | } |
177 | | |
178 | 11.0M | CAmount nValueIn = 0; |
179 | 25.1M | for (unsigned int i = 0; i < tx.vin.size(); ++i) { |
180 | 14.0M | const COutPoint &prevout = tx.vin[i].prevout; |
181 | 14.0M | const Coin& coin = inputs.AccessCoin(prevout); |
182 | 14.0M | assert(!coin.IsSpent()); |
183 | | |
184 | | // If prev is coinbase, check that it's matured |
185 | 14.0M | if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) { |
186 | 7 | return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase", |
187 | 7 | strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); |
188 | 7 | } |
189 | | |
190 | | // Check for negative or overflow input values |
191 | 14.0M | nValueIn += coin.out.nValue; |
192 | 14.0M | if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) { |
193 | 1 | return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange"); |
194 | 1 | } |
195 | 14.0M | } |
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 | 11.0M | const CAmount value_out = tx.GetValueOut(); |
202 | 11.0M | if (nValueIn < value_out) { |
203 | 11 | return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout", |
204 | 11 | strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out))); |
205 | 11 | } |
206 | | |
207 | | // Tally transaction fees |
208 | 11.0M | const CAmount txfee_aux = nValueIn - value_out; |
209 | 11.0M | 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 | 0 | } |
217 | | |
218 | 11.0M | txfee = txfee_aux; |
219 | 11.0M | return true; |
220 | 11.0M | } |