Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
iguana_interpreter.cpp
Go to the documentation of this file.
1// Copyright (c) 2024 The Bitcoin developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
8#include <streams.h>
9
10#include <tinyformat.h>
11
13 const CTxIn &txin = tx.vin[inputIndex];
14
16
17 std::vector<std::vector<uint8_t>> stack;
18
19 IguanaResult result;
20 {
22 result.metrics);
25 return result;
26 }
27 }
28
29 std::vector<std::vector<uint8_t>> stackCopy = stack;
30
31 {
33 result.metrics);
36 return result;
37 }
38 }
39
40 if (stack.empty() || CastToBool(stack.back()) == false) {
42 return result;
43 }
44
46
48 result.traceRedeemScript.emplace();
49 if (!txin.scriptSig.IsPushOnly()) {
50 result.traceRedeemScript->scriptError = ScriptError::SIG_PUSHONLY;
51 return result;
52 }
53
54 swap(stack, stackCopy);
55 const std::vector<uint8_t> &redeemScriptRaw = stack.back();
57 stack.pop_back();
58
59 if ((flags & SCRIPT_DISALLOW_SEGWIT_RECOVERY) == 0 && stack.empty() &&
60 redeemScript.IsWitnessProgram()) {
61 // Allow SegWit recovery; doesn't run redeemScript
62 result.traceRedeemScript = std::nullopt;
63 return result;
64 }
65
67 result.metrics);
69
70 if (result.traceRedeemScript->scriptError != ScriptError::OK) {
71 return result;
72 }
73
74 if (stack.empty() || CastToBool(stack.back()) == false) {
75 result.traceRedeemScript->scriptError = ScriptError::EVAL_FALSE;
76 return result;
77 }
79 }
80
81 if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) {
82 if (stack.size() != 1) {
84 return result;
85 }
86 }
87
89 if (int(txin.scriptSig.size()) < result.metrics.nSigChecks * 43 - 60) {
91 return result;
92 }
93 }
94
95 return result;
96}
97
99 bool isPushOnly) const {
102 trace.initialStacks.stack = interpreter.GetStack();
103 trace.initialStacks.altstack = interpreter.GetAltStack();
104 try {
105 while (!interpreter.IsAtEnd()) {
107 if (!interpreter.GetNextOp(nextEntry.opcode, nextEntry.pushdata)) {
108 // Override message for invalid encoding, since an unknown
109 // opcode also results in BAD_OPCODE
110 trace.errorMsg = "Invalidly encoded opcode";
111 trace.scriptError = ScriptError::BAD_OPCODE;
112 return trace;
113 }
114
115 IguanaTraceEntry &entry = trace.entries.emplace_back(nextEntry);
116
117 if (isPushOnly && entry.opcode > OP_16) {
118 trace.scriptError = ScriptError::SIG_PUSHONLY;
119 return trace;
120 }
121 if (!interpreter.RunNextOp()) {
122 trace.scriptError = interpreter.GetScriptError();
123 return trace;
124 }
125
126 entry.stacks.stack = interpreter.GetStack();
127 entry.stacks.altstack = interpreter.GetAltStack();
128 }
129 } catch (std::exception &ex) {
130 trace.errorMsg = strprintf("Exception: %s", ex.what());
131 return trace;
132 }
133 trace.scriptError = ScriptError::OK;
134 return trace;
135}
std::vector< CTxIn > vin
Serialized script, used inside transaction inputs and outputs.
Definition script.h:424
bool IsPayToScriptHash() const
Definition script.cpp:373
An input of a transaction.
Definition transaction.h:59
IguanaTrace RunScript(ScriptInterpreter &interpreter, bool isPushOnly) const
IguanaResult Run() const
Run the interpreter, stepping through the scripts and return the trace.
CMutableTransaction tx
MutableTransactionSignatureChecker sigChecker
bool CastToBool(const valtype &vch)
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
@ OP_16
Definition script.h:72
@ SCRIPT_VERIFY_P2SH
@ SCRIPT_VERIFY_SIGPUSHONLY
@ SCRIPT_VERIFY_CLEANSTACK
@ SCRIPT_DISALLOW_SEGWIT_RECOVERY
@ SCRIPT_VERIFY_INPUT_SIGCHECKS
IguanaTrace traceScriptSig
IguanaTrace traceScriptPubKey
ScriptExecutionMetrics metrics
std::optional< IguanaTrace > traceRedeemScript
std::vector< std::vector< uint8_t > > stack
std::vector< std::vector< uint8_t > > altstack
IguanaStacks stacks
opcodetype opcode
ScriptError scriptError
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...