tx_verify.cpp raw
1 // Copyright (c) 2017-2021 The Limenka 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/ct.h>
12 #include <consensus/validation.h>
13 #include <crypto/bulletproofs.h>
14 #include <hash.h>
15 #include <primitives/transaction.h>
16 #include <script/interpreter.h>
17 #include <uint256.h>
18 #include <util/check.h>
19 #include <util/moneystr.h>
20
21 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
22 {
23 if (tx.nLockTime == 0)
24 return true;
25 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
26 return true;
27
28 // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a
29 // transaction is still considered final if all inputs' nSequence ==
30 // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored.
31 //
32 // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will
33 // also check that the spending input's nSequence != SEQUENCE_FINAL,
34 // ensuring that an unsatisfied nLockTime value will actually cause
35 // IsFinalTx() to return false here:
36 for (const auto& txin : tx.vin) {
37 if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
38 return false;
39 }
40 return true;
41 }
42
43 std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
44 {
45 assert(prevHeights.size() == tx.vin.size());
46
47 // Will be set to the equivalent height- and time-based nLockTime
48 // values that would be necessary to satisfy all relative lock-
49 // time constraints given our view of block chain history.
50 // The semantics of nLockTime are the last invalid height/time, so
51 // use -1 to have the effect of any height or time being valid.
52 int nMinHeight = -1;
53 int64_t nMinTime = -1;
54
55 bool fEnforceBIP68 = tx.version >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE;
56
57 // Do not enforce sequence numbers as a relative lock time
58 // unless we have been instructed to
59 if (!fEnforceBIP68) {
60 return std::make_pair(nMinHeight, nMinTime);
61 }
62
63 for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
64 const CTxIn& txin = tx.vin[txinIndex];
65
66 // Sequence numbers with the most significant bit set are not
67 // treated as relative lock-times, nor are they given any
68 // consensus-enforced meaning at this point.
69 if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
70 // The height of this input is not relevant for sequence locks
71 prevHeights[txinIndex] = 0;
72 continue;
73 }
74
75 int nCoinHeight = prevHeights[txinIndex];
76
77 if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
78 const int64_t nCoinTime{Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))->GetMedianTimePast()};
79 // NOTE: Subtract 1 to maintain nLockTime semantics
80 // BIP 68 relative lock times have the semantics of calculating
81 // the first block or time at which the transaction would be
82 // valid. When calculating the effective block time or height
83 // for the entire transaction, we switch to using the
84 // semantics of nLockTime which is the last invalid block
85 // time or height. Thus we subtract 1 from the calculated
86 // time or height.
87
88 // Time-based relative lock-times are measured from the
89 // smallest allowed timestamp of the block containing the
90 // txout being spent, which is the median time past of the
91 // block prior.
92 nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
93 } else {
94 nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
95 }
96 }
97
98 return std::make_pair(nMinHeight, nMinTime);
99 }
100
101 bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
102 {
103 assert(block.pprev);
104 int64_t nBlockTime = block.pprev->GetMedianTimePast();
105 if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
106 return false;
107
108 return true;
109 }
110
111 bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
112 {
113 return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
114 }
115
116 unsigned int GetLegacySigOpCount(const CTransaction& tx)
117 {
118 unsigned int nSigOps = 0;
119 for (const auto& txin : tx.vin)
120 {
121 nSigOps += txin.scriptSig.GetSigOpCount(false);
122 }
123 for (const auto& txout : tx.vout)
124 {
125 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
126 }
127 return nSigOps;
128 }
129
130 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
131 {
132 if (tx.IsCoinBase())
133 return 0;
134
135 unsigned int nSigOps = 0;
136 for (unsigned int i = 0; i < tx.vin.size(); i++)
137 {
138 const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
139 assert(!coin.IsSpent());
140 const CTxOut &prevout = coin.out;
141 if (prevout.scriptPubKey.IsPayToScriptHash())
142 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
143 }
144 return nSigOps;
145 }
146
147 int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags)
148 {
149 int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
150
151 if (tx.IsCoinBase())
152 return nSigOps;
153
154 if (flags & SCRIPT_VERIFY_P2SH) {
155 nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
156 }
157
158 for (unsigned int i = 0; i < tx.vin.size(); i++)
159 {
160 const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
161 assert(!coin.IsSpent());
162 const CTxOut &prevout = coin.out;
163 nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
164 }
165 return nSigOps;
166 }
167
168 static bool IsP2BPCT(const CScript& spk)
169 {
170 int witver; std::vector<uint8_t> witprog;
171 return spk.IsWitnessProgram(witver, witprog) &&
172 witver == 4 && witprog.size() == WITNESS_V4_BPCT_SIZE;
173 }
174
175 bool Consensus::CheckOutputSizes(const CTransaction& tx, TxValidationState& state)
176 {
177 for (const auto& txout : tx.vout) {
178 if (txout.scriptPubKey.empty()) continue;
179 // CT outputs (witness v4 commitments, 35 bytes) and CT kernel
180 // outputs (OP_RETURN "BK" ...) exceed the RDTS reduced-data caps
181 // by construction; their own consensus rules bound their size.
182 if (IsP2BPCT(txout.scriptPubKey) || IsCTKernelScript(txout.scriptPubKey)) continue;
183 if (txout.scriptPubKey.size() > ((txout.scriptPubKey[0] == OP_RETURN) ? MAX_OUTPUT_DATA_SIZE : MAX_OUTPUT_SCRIPT_SIZE)) {
184 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-script-toolarge");
185 }
186 }
187 return true;
188 }
189
190 // Fork confidential-transaction rules. A CT transaction has CT outputs
191 // (and optionally CT inputs); transparent inputs are allowed as a mint
192 // path: their visible value enters the kernel balance with zero blinding
193 // and their script signatures authorize the spend separately.
194 // On success sets ct_fee to the explicit fee from the kernel output.
195 static bool CheckCTTransaction(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, CAmount& ct_fee, bool& is_ct_tx)
196 {
197 bool has_ct_input = false, has_ct_output = false;
198 for (const auto& txin : tx.vin) {
199 if (IsP2BPCT(inputs.AccessCoin(txin.prevout).out.scriptPubKey)) { has_ct_input = true; break; }
200 }
201 for (const auto& txout : tx.vout) {
202 if (IsP2BPCT(txout.scriptPubKey)) { has_ct_output = true; break; }
203 }
204 // CT-ness is defined by inputs/outputs, NOT by the presence of a
205 // kernel-shaped output: a transparent tx carrying a bare OP_RETURN
206 // "BK" output must not have its fee zeroed (and a real CT tx without
207 // a kernel is rejected below).
208 is_ct_tx = has_ct_input || has_ct_output;
209 if (!has_ct_input && !has_ct_output) return true; // not a confidential transaction
210
211 std::vector<std::vector<uint8_t>> in_commitments, out_commitments;
212 std::vector<CAmount> transparent_in_values;
213 for (const auto& txin : tx.vin) {
214 const Coin& coin = inputs.AccessCoin(txin.prevout);
215 int witver; std::vector<uint8_t> witprog;
216 if (coin.out.scriptPubKey.IsWitnessProgram(witver, witprog) &&
217 witver == 4 && witprog.size() == WITNESS_V4_BPCT_SIZE) {
218 in_commitments.push_back(std::move(witprog));
219 continue;
220 }
221 // Transparent mint input: its value is visible and enters the
222 // balance equation; script verification handles authorization.
223 const CAmount value_attosats = coin.out.nValue * ATTOSATS_PER_SATOSHI;
224 if (coin.out.nValue < 0) {
225 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-mint-value",
226 "confidential transaction has a negative transparent input");
227 }
228 transparent_in_values.push_back(value_attosats);
229 }
230
231 const int kernel_index = GetCTKernelOutputIndex(tx);
232 if (kernel_index == NO_CT_KERNEL_OUTPUT) {
233 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-no-kernel",
234 "confidential transaction missing kernel output");
235 }
236 for (size_t i = 0; i < tx.vout.size(); i++) {
237 if (static_cast<int>(i) == kernel_index) continue;
238 const CTxOut& txout = tx.vout[i];
239 int witver; std::vector<uint8_t> witprog;
240 if (!(txout.scriptPubKey.IsWitnessProgram(witver, witprog) &&
241 witver == 4 && witprog.size() == WITNESS_V4_BPCT_SIZE)) {
242 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-mixed-output",
243 "confidential transaction has a non-confidential output");
244 }
245 if (txout.nValue != 0) {
246 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-value",
247 "confidential output has non-zero nValue");
248 }
249 out_commitments.push_back(std::move(witprog));
250 }
251
252 const auto kernel = ParseCTKernelOutput(tx.vout[kernel_index]);
253 if (!kernel) {
254 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-kernel-format",
255 "malformed confidential transaction kernel output");
256 }
257 // The kernel output carries no spendable value; a non-zero nValue would
258 // be silently burned (OP_RETURN), so reject it outright.
259 if (tx.vout[kernel_index].nValue != 0) {
260 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-kernel-value",
261 "confidential transaction kernel output has non-zero nValue");
262 }
263
264 const uint256 msg = ComputeCTKernelMessage(tx, kernel_index, *kernel, transparent_in_values);
265 if (!VerifyCTBalance(in_commitments, out_commitments, kernel->fee,
266 {msg.begin(), msg.end()}, kernel->sig,
267 transparent_in_values)) {
268 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-balance",
269 "confidential transaction balance check failed");
270 }
271 ct_fee = kernel->fee;
272 return true;
273 }
274
275 bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, const CheckTxInputsRules rules, const Consensus::Params& consensusParams, bool fork_active)
276 {
277 // are the actual inputs available?
278 if (!inputs.HaveInputs(tx)) {
279 return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
280 strprintf("%s: inputs missing/spent", __func__));
281 }
282
283 // NOTE: CheckTransaction is arguably the more logical place to do this, but it's context-independent, so this is probably the next best place for now
284 if (rules.test(CheckTxInputsRules::OutputSizeLimit) && !CheckOutputSizes(tx, state)) {
285 return false;
286 }
287
288 // Post-activation opcode whitelist: reject outputs with disallowed opcodes
289 if (fork_active) {
290 for (unsigned int i = 0; i < tx.vout.size(); ++i) {
291 if (!CheckScriptOpcodeWhitelist(tx.vout[i].scriptPubKey)) {
292 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-output-opcode-whitelist",
293 strprintf("%s: output %d contains disallowed opcode", __func__, i));
294 }
295 }
296 }
297
298 CAmount nValueIn = 0;
299 for (unsigned int i = 0; i < tx.vin.size(); ++i) {
300 const COutPoint &prevout = tx.vin[i].prevout;
301 const Coin& coin = inputs.AccessCoin(prevout);
302 assert(!coin.IsSpent());
303
304 // If prev is coinbase, check that it's matured
305 if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
306 return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
307 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
308 }
309
310 // Check for negative or overflow input values
311 nValueIn += coin.out.nValue;
312 if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
313 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
314 }
315 }
316
317 const CAmount value_out = tx.GetValueOut();
318 if (nValueIn < value_out) {
319 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
320 strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
321 }
322
323 // Tally transaction fees
324 const CAmount txfee_aux = nValueIn - value_out;
325 if (!MoneyRange(txfee_aux)) {
326 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
327 }
328
329 txfee = txfee_aux;
330
331 // Fork confidential-transaction rules (no inflation via hidden amounts).
332 // The explicit kernel fee is added to the transaction fee so miners
333 // collect it in the coinbase.
334 CAmount ct_fee = 0;
335 bool is_ct_tx = false;
336 if (fork_active && !CheckCTTransaction(tx, state, inputs, ct_fee, is_ct_tx)) {
337 return false;
338 }
339 if (!fork_active) is_ct_tx = false;
340 // CT committed values and the kernel fee are in attosats; the
341 // transparent txfee domain is satoshis. For a CT transaction the
342 // kernel fee is the ONLY fee: transparent mint inputs' values move
343 // into the confidential domain (balance enforced by the kernel), so
344 // counting them as fee as well would double-pay the miner. Floor
345 // conversion keeps the sub-satoshi remainder burned.
346 // Policy note: a kernel fee below one satoshi floors to txfee == 0,
347 // so sub-satoshi CT fees cannot relay (minrelay rejects zero-fee
348 // transactions); they remain consensus-valid for direct block mining.
349 txfee = is_ct_tx ? ct_fee / ATTOSATS_PER_SATOSHI : txfee_aux;
350 if (!MoneyRange(txfee)) {
351 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
352 }
353
354 return true;
355 }
356
357 /** Post-activation opcode whitelist for output creation.
358 * Allows only: push ops, IF/ELSE/ENDIF, stack ops, HASH160, EQUAL, CLTV, CSV, CHECKSIG.
359 * This prevents creating complex scripts after fork activation. */
360 bool Consensus::CheckScriptOpcodeWhitelist(const CScript& script)
361 {
362 // Whitelist of allowed opcodes
363 static const std::set<opcodetype> allowed_opcodes = {
364 // Push values
365 OP_0, OP_1, OP_2, OP_3, OP_4, OP_5, OP_6, OP_7, OP_8, OP_9, OP_10, OP_11, OP_12, OP_13, OP_14, OP_15, OP_16,
366 OP_1NEGATE,
367 // Control
368 OP_IF, OP_NOTIF, OP_ELSE, OP_ENDIF, OP_RETURN,
369 // Stack ops (minimal set for basic scripts)
370 OP_TOALTSTACK, OP_FROMALTSTACK, OP_DROP, OP_DUP, OP_NIP, OP_OVER, OP_PICK, OP_ROLL, OP_ROT, OP_SWAP, OP_TUCK,
371 OP_IFDUP, OP_DEPTH, OP_2DROP, OP_2DUP, OP_3DUP, OP_2OVER, OP_2ROT, OP_2SWAP,
372 // Crypto (the core whitelist)
373 OP_HASH160, OP_HASH256, OP_SHA256, OP_RIPEMD160,
374 OP_EQUAL, OP_EQUALVERIFY,
375 OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKSIGADD,
376 OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY,
377 // Timelocks
378 OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY,
379 // Numeric (basic)
380 OP_ADD, OP_SUB, OP_ABS, OP_NOT, OP_0NOTEQUAL,
381 OP_BOOLAND, OP_BOOLOR, OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_NUMNOTEQUAL,
382 OP_LESSTHAN, OP_GREATERTHAN, OP_LESSTHANOREQUAL, OP_GREATERTHANOREQUAL,
383 OP_MIN, OP_MAX, OP_WITHIN,
384 OP_SIZE,
385 // Misc
386 OP_NOP, OP_VERIFY,
387 OP_CODESEPARATOR,
388 };
389
390 CScript::const_iterator pc = script.begin();
391 opcodetype opcode;
392 while (pc < script.end()) {
393 if (!script.GetOp(pc, opcode)) {
394 return false;
395 }
396 // Skip push data (data pushes are always allowed)
397 if (opcode <= OP_16) continue;
398 // Check against whitelist
399 if (allowed_opcodes.find(opcode) == allowed_opcodes.end()) {
400 return false;
401 }
402 }
403 return true;
404 }
405