tx_verify.cpp raw
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 <util/check.h>
15 #include <util/moneystr.h>
16
17 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
18 {
19 if (tx.nLockTime == 0)
20 return true;
21 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
22 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 for (const auto& txin : tx.vin) {
33 if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
34 return false;
35 }
36 return true;
37 }
38
39 std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
40 {
41 assert(prevHeights.size() == tx.vin.size());
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 int nMinHeight = -1;
49 int64_t nMinTime = -1;
50
51 bool fEnforceBIP68 = tx.version >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE;
52
53 // Do not enforce sequence numbers as a relative lock time
54 // unless we have been instructed to
55 if (!fEnforceBIP68) {
56 return std::make_pair(nMinHeight, nMinTime);
57 }
58
59 for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
60 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 if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
66 // The height of this input is not relevant for sequence locks
67 prevHeights[txinIndex] = 0;
68 continue;
69 }
70
71 int nCoinHeight = prevHeights[txinIndex];
72
73 if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
74 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 nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
89 } else {
90 nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
91 }
92 }
93
94 return std::make_pair(nMinHeight, nMinTime);
95 }
96
97 bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
98 {
99 assert(block.pprev);
100 int64_t nBlockTime = block.pprev->GetMedianTimePast();
101 if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
102 return false;
103
104 return true;
105 }
106
107 bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
108 {
109 return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
110 }
111
112 unsigned int GetLegacySigOpCount(const CTransaction& tx)
113 {
114 unsigned int nSigOps = 0;
115 for (const auto& txin : tx.vin)
116 {
117 nSigOps += txin.scriptSig.GetSigOpCount(false);
118 }
119 for (const auto& txout : tx.vout)
120 {
121 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
122 }
123 return nSigOps;
124 }
125
126 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
127 {
128 if (tx.IsCoinBase())
129 return 0;
130
131 unsigned int nSigOps = 0;
132 for (unsigned int i = 0; i < tx.vin.size(); i++)
133 {
134 const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
135 assert(!coin.IsSpent());
136 const CTxOut &prevout = coin.out;
137 if (prevout.scriptPubKey.IsPayToScriptHash())
138 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
139 }
140 return nSigOps;
141 }
142
143 int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, script_verify_flags flags)
144 {
145 int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
146
147 if (tx.IsCoinBase())
148 return nSigOps;
149
150 if (flags & SCRIPT_VERIFY_P2SH) {
151 nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
152 }
153
154 for (unsigned int i = 0; i < tx.vin.size(); i++)
155 {
156 const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
157 assert(!coin.IsSpent());
158 const CTxOut &prevout = coin.out;
159 nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, tx.vin[i].scriptWitness, flags);
160 }
161 return nSigOps;
162 }
163
164 bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
165 {
166 // are the actual inputs available?
167 if (!inputs.HaveInputs(tx)) {
168 return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
169 strprintf("%s: inputs missing/spent", __func__));
170 }
171
172 CAmount nValueIn = 0;
173 for (unsigned int i = 0; i < tx.vin.size(); ++i) {
174 const COutPoint &prevout = tx.vin[i].prevout;
175 const Coin& coin = inputs.AccessCoin(prevout);
176 assert(!coin.IsSpent());
177
178 // If prev is coinbase, check that it's matured
179 if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
180 return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
181 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
182 }
183
184 // Check for negative or overflow input values
185 nValueIn += coin.out.nValue;
186 if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
187 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
188 }
189 }
190
191 // `tx.GetValueOut()` won't throw in validation paths because output-range checks run first
192 // (`bad-txns-vout-negative`, `bad-txns-vout-toolarge`, `bad-txns-txouttotal-toolarge`):
193 // * `MemPoolAccept::PreChecks`: `CheckTransaction()` is called before this method;
194 // * `Chainstate::ConnectBlock`: `CheckTransaction()` is called via `CheckBlock()` before this method.
195 const CAmount value_out = tx.GetValueOut();
196 if (nValueIn < value_out) {
197 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
198 strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
199 }
200
201 // Tally transaction fees
202 const CAmount txfee_aux = nValueIn - value_out;
203 if (!MoneyRange(txfee_aux)) {
204 // Unreachable, given the following preconditions:
205 // * `value_out` comes from `tx.GetValueOut()`, which throws unless `MoneyRange(value_out)` and asserts `MoneyRange(nValueOut)` on return.
206 // * `MoneyRange(nValueIn)` was enforced in the input loop.
207 // * `nValueIn < value_out` was handled above, so `nValueIn >= value_out` here (and `txfee_aux >= 0`).
208 // Therefore `0 <= txfee_aux = nValueIn - value_out <= nValueIn <= MAX_MONEY`.
209 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
210 }
211
212 txfee = txfee_aux;
213 return true;
214 }
215