bitcoin_script_analyzer/
script_error.rs

1// From the Bitcoin Core source code, files src/script/script_error.{h,cpp} at commit b1a2021f78099c17360dc2179cbcb948059b5969
2// Edited for use in this software
3
4// Orignal Bitcoin Core copyright header:
5// Copyright (c) 2009-2010 Satoshi Nakamoto
6// Copyright (c) 2009-2020 The Bitcoin Core developers
7// Distributed under the MIT software license, see the accompanying
8// file COPYING or http://www.opensource.org/licenses/mit-license.php.
9
10use core::fmt;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13#[allow(non_camel_case_types)]
14#[allow(dead_code)]
15pub enum ScriptError {
16    SCRIPT_ERR_OK,
17    SCRIPT_ERR_UNKNOWN_ERROR,
18    SCRIPT_ERR_EVAL_FALSE,
19    SCRIPT_ERR_OP_RETURN,
20
21    /* Max sizes */
22    SCRIPT_ERR_SCRIPT_SIZE,
23    SCRIPT_ERR_PUSH_SIZE,
24    SCRIPT_ERR_OP_COUNT,
25    SCRIPT_ERR_STACK_SIZE,
26    SCRIPT_ERR_SIG_COUNT,
27    SCRIPT_ERR_PUBKEY_COUNT,
28
29    /* Failed verify operations */
30    SCRIPT_ERR_VERIFY,
31    SCRIPT_ERR_EQUALVERIFY,
32    SCRIPT_ERR_CHECKMULTISIGVERIFY,
33    SCRIPT_ERR_CHECKSIGVERIFY,
34    SCRIPT_ERR_NUMEQUALVERIFY,
35
36    /* Logical/Format/Canonical errors */
37    SCRIPT_ERR_BAD_OPCODE,
38    SCRIPT_ERR_DISABLED_OPCODE,
39    SCRIPT_ERR_INVALID_STACK_OPERATION,
40    SCRIPT_ERR_INVALID_ALTSTACK_OPERATION,
41    SCRIPT_ERR_UNBALANCED_CONDITIONAL,
42
43    /* CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY */
44    SCRIPT_ERR_NEGATIVE_LOCKTIME,
45    SCRIPT_ERR_UNSATISFIED_LOCKTIME,
46
47    /* Malleability */
48    SCRIPT_ERR_SIG_HASHTYPE,
49    SCRIPT_ERR_SIG_DER,
50    SCRIPT_ERR_MINIMALDATA,
51    SCRIPT_ERR_SIG_PUSHONLY,
52    SCRIPT_ERR_SIG_HIGH_S,
53    SCRIPT_ERR_SIG_NULLDUMMY,
54    SCRIPT_ERR_PUBKEYTYPE,
55    SCRIPT_ERR_CLEANSTACK,
56    SCRIPT_ERR_MINIMALIF,
57    SCRIPT_ERR_SIG_NULLFAIL,
58
59    /* softfork safeness */
60    SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,
61    SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,
62    SCRIPT_ERR_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION,
63    SCRIPT_ERR_DISCOURAGE_OP_SUCCESS,
64    SCRIPT_ERR_DISCOURAGE_UPGRADABLE_PUBKEYTYPE,
65
66    /* segregated witness */
67    SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH,
68    SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY,
69    SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH,
70    SCRIPT_ERR_WITNESS_MALLEATED,
71    SCRIPT_ERR_WITNESS_MALLEATED_P2SH,
72    SCRIPT_ERR_WITNESS_UNEXPECTED,
73    SCRIPT_ERR_WITNESS_PUBKEYTYPE,
74
75    /* Taproot */
76    SCRIPT_ERR_SCHNORR_SIG_SIZE,
77    SCRIPT_ERR_SCHNORR_SIG_HASHTYPE,
78    SCRIPT_ERR_SCHNORR_SIG,
79    SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE,
80    SCRIPT_ERR_TAPSCRIPT_VALIDATION_WEIGHT,
81    SCRIPT_ERR_TAPSCRIPT_CHECKMULTISIG,
82    SCRIPT_ERR_TAPSCRIPT_MINIMALIF,
83
84    /* Constant scriptCode */
85    SCRIPT_ERR_OP_CODESEPARATOR,
86    SCRIPT_ERR_SIG_FINDANDDELETE,
87
88    //SCRIPT_ERR_ERROR_COUNT,
89    //SCRIPT_ERR_LAST = Self::SCRIPT_ERR_ERROR_COUNT,
90    /// This error does not exists in Bitcoin Core, it uses SCRIPT_ERR_UNKNOWN_ERROR
91    SCRIPT_ERR_NUM_OVERFLOW,
92    /// This error does not exists in Bitcoin Core, this is a limitation of this program
93    SCRIPT_ERR_UNKNOWN_DEPTH,
94}
95
96impl ScriptError {
97    pub fn description(&self) -> &'static str {
98        match self {
99            ScriptError::SCRIPT_ERR_OK => "No error",
100            ScriptError::SCRIPT_ERR_EVAL_FALSE => {
101                "Script evaluated without error but finished with a false/empty top stack element"
102            }
103            ScriptError::SCRIPT_ERR_VERIFY => "Script failed an OP_VERIFY operation",
104            ScriptError::SCRIPT_ERR_EQUALVERIFY => "Script failed an OP_EQUALVERIFY operation",
105            ScriptError::SCRIPT_ERR_CHECKMULTISIGVERIFY => {
106                "Script failed an OP_CHECKMULTISIGVERIFY operation"
107            }
108            ScriptError::SCRIPT_ERR_CHECKSIGVERIFY => {
109                "Script failed an OP_CHECKSIGVERIFY operation"
110            }
111            ScriptError::SCRIPT_ERR_NUMEQUALVERIFY => {
112                "Script failed an OP_NUMEQUALVERIFY operation"
113            }
114            ScriptError::SCRIPT_ERR_SCRIPT_SIZE => "Script is too big",
115            ScriptError::SCRIPT_ERR_PUSH_SIZE => "Push value size limit exceeded",
116            ScriptError::SCRIPT_ERR_OP_COUNT => "Operation limit exceeded",
117            ScriptError::SCRIPT_ERR_STACK_SIZE => "Stack size limit exceeded",
118            ScriptError::SCRIPT_ERR_SIG_COUNT => {
119                "Signature count negative or greater than pubkey count"
120            }
121            ScriptError::SCRIPT_ERR_PUBKEY_COUNT => "Pubkey count negative or limit exceeded",
122            ScriptError::SCRIPT_ERR_BAD_OPCODE => "Opcode missing or not understood",
123            ScriptError::SCRIPT_ERR_DISABLED_OPCODE => "Attempted to use a disabled opcode",
124            ScriptError::SCRIPT_ERR_INVALID_STACK_OPERATION => {
125                "Operation not valid with the current stack size"
126            }
127            ScriptError::SCRIPT_ERR_INVALID_ALTSTACK_OPERATION => {
128                "Operation not valid with the current altstack size"
129            }
130            ScriptError::SCRIPT_ERR_OP_RETURN => "OP_RETURN was encountered",
131            ScriptError::SCRIPT_ERR_UNBALANCED_CONDITIONAL => "Invalid OP_IF construction",
132            ScriptError::SCRIPT_ERR_NEGATIVE_LOCKTIME => "Negative locktime",
133            ScriptError::SCRIPT_ERR_UNSATISFIED_LOCKTIME => "Locktime requirement not satisfied",
134            ScriptError::SCRIPT_ERR_SIG_HASHTYPE => "Signature hash type missing or not understood",
135            ScriptError::SCRIPT_ERR_SIG_DER => "Non-canonical DER signature",
136            ScriptError::SCRIPT_ERR_MINIMALDATA => "Data push larger than necessary",
137            ScriptError::SCRIPT_ERR_SIG_PUSHONLY => "Only push operators allowed in signatures",
138            ScriptError::SCRIPT_ERR_SIG_HIGH_S => {
139                "Non-canonical signature: S value is unnecessarily high"
140            }
141            ScriptError::SCRIPT_ERR_SIG_NULLDUMMY => "Dummy CHECKMULTISIG argument must be zero",
142            ScriptError::SCRIPT_ERR_MINIMALIF => "OP_IF/NOTIF argument must be minimal",
143            ScriptError::SCRIPT_ERR_SIG_NULLFAIL => {
144                "Signature must be zero for failed CHECK(MULTI)SIG operation"
145            }
146            ScriptError::SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS => {
147                "NOPx reserved for soft-fork upgrades"
148            }
149            ScriptError::SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM => {
150                "Witness version reserved for soft-fork upgrades"
151            }
152            ScriptError::SCRIPT_ERR_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION => {
153                "Taproot version reserved for soft-fork upgrades"
154            }
155            ScriptError::SCRIPT_ERR_DISCOURAGE_OP_SUCCESS => {
156                "OP_SUCCESSx reserved for soft-fork upgrades"
157            }
158            ScriptError::SCRIPT_ERR_DISCOURAGE_UPGRADABLE_PUBKEYTYPE => {
159                "Public key version reserved for soft-fork upgrades"
160            }
161            ScriptError::SCRIPT_ERR_PUBKEYTYPE => {
162                "Public key is neither compressed or uncompressed"
163            }
164            ScriptError::SCRIPT_ERR_CLEANSTACK => "Stack size must be exactly one after execution",
165            ScriptError::SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH => {
166                "Witness program has incorrect length"
167            }
168            ScriptError::SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY => {
169                "Witness program was passed an empty witness"
170            }
171            ScriptError::SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH => "Witness program hash mismatch",
172            ScriptError::SCRIPT_ERR_WITNESS_MALLEATED => "Witness requires empty scriptSig",
173            ScriptError::SCRIPT_ERR_WITNESS_MALLEATED_P2SH => {
174                "Witness requires only-redeemscript scriptSig"
175            }
176            ScriptError::SCRIPT_ERR_WITNESS_UNEXPECTED => "Witness provided for non-witness script",
177            ScriptError::SCRIPT_ERR_WITNESS_PUBKEYTYPE => "Using non-compressed keys in segwit",
178            ScriptError::SCRIPT_ERR_SCHNORR_SIG_SIZE => "Invalid Schnorr signature size",
179            ScriptError::SCRIPT_ERR_SCHNORR_SIG_HASHTYPE => "Invalid Schnorr signature hash type",
180            ScriptError::SCRIPT_ERR_SCHNORR_SIG => "Invalid Schnorr signature",
181            ScriptError::SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE => {
182                "Invalid Taproot control block size"
183            }
184            ScriptError::SCRIPT_ERR_TAPSCRIPT_VALIDATION_WEIGHT => {
185                "Too much signature validation relative to witness weight"
186            }
187            ScriptError::SCRIPT_ERR_TAPSCRIPT_CHECKMULTISIG => {
188                "OP_CHECKMULTISIG(VERIFY) is not available in tapscript"
189            }
190            ScriptError::SCRIPT_ERR_TAPSCRIPT_MINIMALIF => {
191                "OP_IF/NOTIF argument must be minimal in tapscript"
192            }
193            ScriptError::SCRIPT_ERR_OP_CODESEPARATOR => {
194                "Using OP_CODESEPARATOR in non-witness script"
195            }
196            ScriptError::SCRIPT_ERR_SIG_FINDANDDELETE => "Signature is found in scriptCode",
197            // bitcoin core returns unknown error for this one so added it myself
198            ScriptError::SCRIPT_ERR_NUM_OVERFLOW => "Script number overflow",
199            ScriptError::SCRIPT_ERR_UNKNOWN_DEPTH => "Depth argument could not be evaluated",
200            ScriptError::SCRIPT_ERR_UNKNOWN_ERROR /* _ */ => "unknown error",
201        }
202    }
203}
204
205impl fmt::Display for ScriptError {
206    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207        write!(f, "{}", self.description())
208    }
209}