/bitcoin/src/consensus/tx_verify.cpp
Line | Count | Source |
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_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 <util/check.h> |
15 | | #include <util/moneystr.h> |
16 | | |
17 | | bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) |
18 | 2.72M | { |
19 | 2.72M | if (tx.nLockTime == 0) Branch (19:9): [True: 2.71M, False: 14.6k]
|
20 | 2.71M | return true; |
21 | 14.6k | if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) Branch (21:9): [True: 5.74k, False: 8.88k]
Branch (21:34): [True: 7.12k, False: 7.49k]
|
22 | 5.74k | return true; |
23 | | |
24 | | // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a |
25 | | // transaction is still considered final if all inputs' nSequence == |
26 | | // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored. |
27 | | // |
28 | | // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will |
29 | | // also check that the spending input's nSequence != SEQUENCE_FINAL, |
30 | | // ensuring that an unsatisfied nLockTime value will actually cause |
31 | | // IsFinalTx() to return false here: |
32 | 10.5k | for (const auto& txin : tx.vin) { Branch (32:27): [True: 10.5k, False: 8.50k]
|
33 | 10.5k | if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL)) Branch (33:13): [True: 381, False: 10.1k]
|
34 | 381 | return false; |
35 | 10.5k | } |
36 | 8.50k | return true; |
37 | 8.88k | } |
38 | | |
39 | | std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) |
40 | 84.4k | { |
41 | 84.4k | assert(prevHeights.size() == tx.vin.size()); Branch (41:5): [True: 84.4k, False: 0]
|
42 | | |
43 | | // Will be set to the equivalent height- and time-based nLockTime |
44 | | // values that would be necessary to satisfy all relative lock- |
45 | | // time constraints given our view of block chain history. |
46 | | // The semantics of nLockTime are the last invalid height/time, so |
47 | | // use -1 to have the effect of any height or time being valid. |
48 | 84.4k | int nMinHeight = -1; |
49 | 84.4k | int64_t nMinTime = -1; |
50 | | |
51 | 84.4k | bool fEnforceBIP68 = tx.version >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE; Branch (51:26): [True: 80.7k, False: 3.70k]
Branch (51:45): [True: 80.7k, False: 0]
|
52 | | |
53 | | // Do not enforce sequence numbers as a relative lock time |
54 | | // unless we have been instructed to |
55 | 84.4k | if (!fEnforceBIP68) { Branch (55:9): [True: 3.70k, False: 80.7k]
|
56 | 3.70k | return std::make_pair(nMinHeight, nMinTime); |
57 | 3.70k | } |
58 | | |
59 | 171k | for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { Branch (59:32): [True: 90.8k, False: 80.7k]
|
60 | 90.8k | const CTxIn& txin = tx.vin[txinIndex]; |
61 | | |
62 | | // Sequence numbers with the most significant bit set are not |
63 | | // treated as relative lock-times, nor are they given any |
64 | | // consensus-enforced meaning at this point. |
65 | 90.8k | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) { Branch (65:13): [True: 90.0k, False: 791]
|
66 | | // The height of this input is not relevant for sequence locks |
67 | 90.0k | prevHeights[txinIndex] = 0; |
68 | 90.0k | continue; |
69 | 90.0k | } |
70 | | |
71 | 791 | int nCoinHeight = prevHeights[txinIndex]; |
72 | | |
73 | 791 | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) { Branch (73:13): [True: 357, False: 434]
|
74 | 357 | const int64_t nCoinTime{Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))->GetMedianTimePast()}; |
75 | | // NOTE: Subtract 1 to maintain nLockTime semantics |
76 | | // BIP 68 relative lock times have the semantics of calculating |
77 | | // the first block or time at which the transaction would be |
78 | | // valid. When calculating the effective block time or height |
79 | | // for the entire transaction, we switch to using the |
80 | | // semantics of nLockTime which is the last invalid block |
81 | | // time or height. Thus we subtract 1 from the calculated |
82 | | // time or height. |
83 | | |
84 | | // Time-based relative lock-times are measured from the |
85 | | // smallest allowed timestamp of the block containing the |
86 | | // txout being spent, which is the median time past of the |
87 | | // block prior. |
88 | 357 | nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1); |
89 | 434 | } else { |
90 | 434 | nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1); |
91 | 434 | } |
92 | 791 | } |
93 | | |
94 | 80.7k | return std::make_pair(nMinHeight, nMinTime); |
95 | 84.4k | } |
96 | | |
97 | | bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair) |
98 | 96.0k | { |
99 | 96.0k | assert(block.pprev); Branch (99:5): [True: 96.0k, False: 0]
|
100 | 96.0k | int64_t nBlockTime = block.pprev->GetMedianTimePast(); |
101 | 96.0k | if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime) Branch (101:9): [True: 432, False: 95.6k]
Branch (101:44): [True: 357, False: 95.2k]
|
102 | 789 | return false; |
103 | | |
104 | 95.2k | return true; |
105 | 96.0k | } |
106 | | |
107 | | bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) |
108 | 20.4k | { |
109 | 20.4k | return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block)); |
110 | 20.4k | } |
111 | | |
112 | | unsigned int GetLegacySigOpCount(const CTransaction& tx) |
113 | 4.79M | { |
114 | 4.79M | unsigned int nSigOps = 0; |
115 | 4.79M | for (const auto& txin : tx.vin) Branch (115:27): [True: 4.83M, False: 4.79M]
|
116 | 4.83M | { |
117 | 4.83M | nSigOps += txin.scriptSig.GetSigOpCount(false); |
118 | 4.83M | } |
119 | 4.79M | for (const auto& txout : tx.vout) Branch (119:28): [True: 9.33M, False: 4.79M]
|
120 | 9.33M | { |
121 | 9.33M | nSigOps += txout.scriptPubKey.GetSigOpCount(false); |
122 | 9.33M | } |
123 | 4.79M | return nSigOps; |
124 | 4.79M | } |
125 | | |
126 | | unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs) |
127 | 83.5k | { |
128 | 83.5k | if (tx.IsCoinBase()) Branch (128:9): [True: 0, False: 83.5k]
|
129 | 0 | return 0; |
130 | | |
131 | 83.5k | unsigned int nSigOps = 0; |
132 | 180k | for (unsigned int i = 0; i < tx.vin.size(); i++) Branch (132:30): [True: 97.0k, False: 83.5k]
|
133 | 97.0k | { |
134 | 97.0k | const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); |
135 | 97.0k | assert(!coin.IsSpent()); Branch (135:9): [True: 97.0k, False: 0]
|
136 | 97.0k | const CTxOut &prevout = coin.out; |
137 | 97.0k | if (prevout.scriptPubKey.IsPayToScriptHash()) Branch (137:13): [True: 4.35k, False: 92.6k]
|
138 | 4.35k | nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig); |
139 | 97.0k | } |
140 | 83.5k | return nSigOps; |
141 | 83.5k | } |
142 | | |
143 | | int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags) |
144 | 2.31M | { |
145 | 2.31M | int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR; |
146 | | |
147 | 2.31M | if (tx.IsCoinBase()) Branch (147:9): [True: 2.22M, False: 83.5k]
|
148 | 2.22M | return nSigOps; |
149 | | |
150 | 83.5k | if (flags & SCRIPT_VERIFY_P2SH) { Branch (150:9): [True: 83.5k, False: 0]
|
151 | 83.5k | nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR; |
152 | 83.5k | } |
153 | | |
154 | 180k | for (unsigned int i = 0; i < tx.vin.size(); i++) Branch (154:30): [True: 97.0k, False: 83.5k]
|
155 | 97.0k | { |
156 | 97.0k | const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); |
157 | 97.0k | assert(!coin.IsSpent()); Branch (157:9): [True: 97.0k, False: 0]
|
158 | 97.0k | const CTxOut &prevout = coin.out; |
159 | 97.0k | nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags); |
160 | 97.0k | } |
161 | 83.5k | return nSigOps; |
162 | 83.5k | } |
163 | | |
164 | | bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee) |
165 | 1.56M | { |
166 | | // are the actual inputs available? |
167 | 1.56M | if (!inputs.HaveInputs(tx)) { Branch (167:9): [True: 1.51k, False: 1.56M]
|
168 | 1.51k | return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent", |
169 | 1.51k | strprintf("%s: inputs missing/spent", __func__)); |
170 | 1.51k | } |
171 | | |
172 | 1.56M | CAmount nValueIn = 0; |
173 | 3.22M | for (unsigned int i = 0; i < tx.vin.size(); ++i) { Branch (173:30): [True: 1.66M, False: 1.56M]
|
174 | 1.66M | const COutPoint &prevout = tx.vin[i].prevout; |
175 | 1.66M | const Coin& coin = inputs.AccessCoin(prevout); |
176 | 1.66M | assert(!coin.IsSpent()); Branch (176:9): [True: 1.66M, False: 0]
|
177 | | |
178 | | // If prev is coinbase, check that it's matured |
179 | 1.66M | if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) { Branch (179:13): [True: 456k, False: 1.20M]
Branch (179:34): [True: 1, False: 456k]
|
180 | 1 | return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase", |
181 | 1 | strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); |
182 | 1 | } |
183 | | |
184 | | // Check for negative or overflow input values |
185 | 1.66M | nValueIn += coin.out.nValue; |
186 | 1.66M | if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) { Branch (186:13): [True: 0, False: 1.66M]
Branch (186:45): [True: 0, False: 1.66M]
|
187 | 0 | return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange"); |
188 | 0 | } |
189 | 1.66M | } |
190 | | |
191 | 1.56M | const CAmount value_out = tx.GetValueOut(); |
192 | 1.56M | if (nValueIn < value_out) { Branch (192:9): [True: 0, False: 1.56M]
|
193 | 0 | return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout", |
194 | 0 | strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out))); |
195 | 0 | } |
196 | | |
197 | | // Tally transaction fees |
198 | 1.56M | const CAmount txfee_aux = nValueIn - value_out; |
199 | 1.56M | if (!MoneyRange(txfee_aux)) { Branch (199:9): [True: 0, False: 1.56M]
|
200 | 0 | return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange"); |
201 | 0 | } |
202 | | |
203 | 1.56M | txfee = txfee_aux; |
204 | 1.56M | return true; |
205 | 1.56M | } |