error.go
  1  // Copyright (c) 2013-2017 The btcsuite developers
  2  // Use of this source code is governed by an ISC
  3  // license that can be found in the LICENSE file.
  4  
  5  package txscript
  6  
  7  import (
  8  	"fmt"
  9  )
 10  
 11  // ErrorCode identifies a kind of script error.
 12  type ErrorCode int
 13  
 14  // These constants are used to identify a specific Error.
 15  const (
 16  	// ErrInternal is returned if internal consistency checks fail.  In
 17  	// practice this error should never be seen as it would mean there is an
 18  	// error in the engine logic.
 19  	ErrInternal ErrorCode = iota
 20  
 21  	// ---------------------------------------
 22  	// Failures related to improper API usage.
 23  	// ---------------------------------------
 24  
 25  	// ErrInvalidFlags is returned when the passed flags to NewEngine
 26  	// contain an invalid combination.
 27  	ErrInvalidFlags
 28  
 29  	// ErrInvalidIndex is returned when an out-of-bounds index is passed to
 30  	// a function.
 31  	ErrInvalidIndex
 32  
 33  	// ErrUnsupportedAddress is returned when a concrete type that
 34  	// implements a btcutil.Address is not a supported type.
 35  	ErrUnsupportedAddress
 36  
 37  	// ErrNotMultisigScript is returned from CalcMultiSigStats when the
 38  	// provided script is not a multisig script.
 39  	ErrNotMultisigScript
 40  
 41  	// ErrTooManyRequiredSigs is returned from MultiSigScript when the
 42  	// specified number of required signatures is larger than the number of
 43  	// provided public keys.
 44  	ErrTooManyRequiredSigs
 45  
 46  	// ErrTooMuchNullData is returned from NullDataScript when the length of
 47  	// the provided data exceeds MaxDataCarrierSize.
 48  	ErrTooMuchNullData
 49  
 50  	// ------------------------------------------
 51  	// Failures related to final execution state.
 52  	// ------------------------------------------
 53  
 54  	// ErrEarlyReturn is returned when OP_RETURN is executed in the script.
 55  	ErrEarlyReturn
 56  
 57  	// ErrEmptyStack is returned when the script evaluated without error,
 58  	// but terminated with an empty top stack element.
 59  	ErrEmptyStack
 60  
 61  	// ErrEvalFalse is returned when the script evaluated without error but
 62  	// terminated with a false top stack element.
 63  	ErrEvalFalse
 64  
 65  	// ErrScriptUnfinished is returned when CheckErrorCondition is called on
 66  	// a script that has not finished executing.
 67  	ErrScriptUnfinished
 68  
 69  	// ErrScriptDone is returned when an attempt to execute an opcode is
 70  	// made once all of them have already been executed.  This can happen
 71  	// due to things such as a second call to Execute or calling Step after
 72  	// all opcodes have already been executed.
 73  	ErrInvalidProgramCounter
 74  
 75  	// -----------------------------------------------------
 76  	// Failures related to exceeding maximum allowed limits.
 77  	// -----------------------------------------------------
 78  
 79  	// ErrScriptTooBig is returned if a script is larger than MaxScriptSize.
 80  	ErrScriptTooBig
 81  
 82  	// ErrElementTooBig is returned if the size of an element to be pushed
 83  	// to the stack is over MaxScriptElementSize.
 84  	ErrElementTooBig
 85  
 86  	// ErrTooManyOperations is returned if a script has more than
 87  	// MaxOpsPerScript opcodes that do not push data.
 88  	ErrTooManyOperations
 89  
 90  	// ErrStackOverflow is returned when stack and altstack combined depth
 91  	// is over the limit.
 92  	ErrStackOverflow
 93  
 94  	// ErrInvalidPubKeyCount is returned when the number of public keys
 95  	// specified for a multsig is either negative or greater than
 96  	// MaxPubKeysPerMultiSig.
 97  	ErrInvalidPubKeyCount
 98  
 99  	// ErrInvalidSignatureCount is returned when the number of signatures
100  	// specified for a multisig is either negative or greater than the
101  	// number of public keys.
102  	ErrInvalidSignatureCount
103  
104  	// ErrNumberTooBig is returned when the argument for an opcode that
105  	// expects numeric input is larger than the expected maximum number of
106  	// bytes.  For the most part, opcodes that deal with stack manipulation
107  	// via offsets, arithmetic, numeric comparison, and boolean logic are
108  	// those that this applies to.  However, any opcode that expects numeric
109  	// input may fail with this code.
110  	ErrNumberTooBig
111  
112  	// --------------------------------------------
113  	// Failures related to verification operations.
114  	// --------------------------------------------
115  
116  	// ErrVerify is returned when OP_VERIFY is encountered in a script and
117  	// the top item on the data stack does not evaluate to true.
118  	ErrVerify
119  
120  	// ErrEqualVerify is returned when OP_EQUALVERIFY is encountered in a
121  	// script and the top item on the data stack does not evaluate to true.
122  	ErrEqualVerify
123  
124  	// ErrNumEqualVerify is returned when OP_NUMEQUALVERIFY is encountered
125  	// in a script and the top item on the data stack does not evaluate to
126  	// true.
127  	ErrNumEqualVerify
128  
129  	// ErrCheckSigVerify is returned when OP_CHECKSIGVERIFY is encountered
130  	// in a script and the top item on the data stack does not evaluate to
131  	// true.
132  	ErrCheckSigVerify
133  
134  	// ErrCheckSigVerify is returned when OP_CHECKMULTISIGVERIFY is
135  	// encountered in a script and the top item on the data stack does not
136  	// evaluate to true.
137  	ErrCheckMultiSigVerify
138  
139  	// --------------------------------------------
140  	// Failures related to improper use of opcodes.
141  	// --------------------------------------------
142  
143  	// ErrDisabledOpcode is returned when a disabled opcode is encountered
144  	// in a script.
145  	ErrDisabledOpcode
146  
147  	// ErrReservedOpcode is returned when an opcode marked as reserved
148  	// is encountered in a script.
149  	ErrReservedOpcode
150  
151  	// ErrMalformedPush is returned when a data push opcode tries to push
152  	// more bytes than are left in the script.
153  	ErrMalformedPush
154  
155  	// ErrInvalidStackOperation is returned when a stack operation is
156  	// attempted with a number that is invalid for the current stack size.
157  	ErrInvalidStackOperation
158  
159  	// ErrUnbalancedConditional is returned when an OP_ELSE or OP_ENDIF is
160  	// encountered in a script without first having an OP_IF or OP_NOTIF or
161  	// the end of script is reached without encountering an OP_ENDIF when
162  	// an OP_IF or OP_NOTIF was previously encountered.
163  	ErrUnbalancedConditional
164  
165  	// ---------------------------------
166  	// Failures related to malleability.
167  	// ---------------------------------
168  
169  	// ErrMinimalData is returned when the ScriptVerifyMinimalData flag
170  	// is set and the script contains push operations that do not use
171  	// the minimal opcode required.
172  	ErrMinimalData
173  
174  	// ErrInvalidSigHashType is returned when a signature hash type is not
175  	// one of the supported types.
176  	ErrInvalidSigHashType
177  
178  	// ErrSigDER is returned when a signature is not a canonically-encoded
179  	// DER signature.
180  	ErrSigDER
181  
182  	// ErrSigHighS is returned when the ScriptVerifyLowS flag is set and the
183  	// script contains any signatures whose S values are higher than the
184  	// half order.
185  	ErrSigHighS
186  
187  	// ErrNotPushOnly is returned when a script that is required to only
188  	// push data to the stack performs other operations.  A couple of cases
189  	// where this applies is for a pay-to-script-hash signature script when
190  	// bip16 is active and when the ScriptVerifySigPushOnly flag is set.
191  	ErrNotPushOnly
192  
193  	// ErrSigNullDummy is returned when the ScriptStrictMultiSig flag is set
194  	// and a multisig script has anything other than 0 for the extra dummy
195  	// argument.
196  	ErrSigNullDummy
197  
198  	// ErrPubKeyType is returned when the ScriptVerifyStrictEncoding
199  	// flag is set and the script contains invalid public keys.
200  	ErrPubKeyType
201  
202  	// ErrCleanStack is returned when the ScriptVerifyCleanStack flag
203  	// is set, and after evalution, the stack does not contain only a
204  	// single element.
205  	ErrCleanStack
206  
207  	// ErrNullFail is returned when the ScriptVerifyNullFail flag is
208  	// set and signatures are not empty on failed checksig or checkmultisig
209  	// operations.
210  	ErrNullFail
211  
212  	// ErrWitnessMalleated is returned if ScriptVerifyWitness is set and a
213  	// native p2wsh program is encountered which has a non-empty sigScript.
214  	ErrWitnessMalleated
215  
216  	// ErrWitnessMalleatedP2SH is returned if ScriptVerifyWitness if set
217  	// and the validation logic for nested p2sh encounters a sigScript
218  	// which isn't *exactyl* a datapush of the witness program.
219  	ErrWitnessMalleatedP2SH
220  
221  	// -------------------------------
222  	// Failures related to soft forks.
223  	// -------------------------------
224  
225  	// ErrDiscourageUpgradableNOPs is returned when the
226  	// ScriptDiscourageUpgradableNops flag is set and a NOP opcode is
227  	// encountered in a script.
228  	ErrDiscourageUpgradableNOPs
229  
230  	// ErrNegativeLockTime is returned when a script contains an opcode that
231  	// interprets a negative lock time.
232  	ErrNegativeLockTime
233  
234  	// ErrUnsatisfiedLockTime is returned when a script contains an opcode
235  	// that involves a lock time and the required lock time has not been
236  	// reached.
237  	ErrUnsatisfiedLockTime
238  
239  	// ErrMinimalIf is returned if ScriptVerifyWitness is set and the
240  	// operand of an OP_IF/OP_NOF_IF are not either an empty vector or
241  	// [0x01].
242  	ErrMinimalIf
243  
244  	// ErrDiscourageUpgradableWitnessProgram is returned if
245  	// ScriptVerifyWitness is set and the versino of an executing witness
246  	// program is outside the set of currently defined witness program
247  	// vesions.
248  	ErrDiscourageUpgradableWitnessProgram
249  
250  	// ----------------------------------------
251  	// Failures related to segregated witness.
252  	// ----------------------------------------
253  
254  	// ErrWitnessProgramEmpty is returned if ScriptVerifyWitness is set and
255  	// the witness stack itself is empty.
256  	ErrWitnessProgramEmpty
257  
258  	// ErrWitnessProgramMismatch is returned if ScriptVerifyWitness is set
259  	// and the witness itself for a p2wkh witness program isn't *exactly* 2
260  	// items or if the witness for a p2wsh isn't the sha255 of the witness
261  	// script.
262  	ErrWitnessProgramMismatch
263  
264  	// ErrWitnessProgramWrongLength is returned if ScriptVerifyWitness is
265  	// set and the length of the witness program violates the length as
266  	// dictated by the current witness version.
267  	ErrWitnessProgramWrongLength
268  
269  	// ErrWitnessUnexpected is returned if ScriptVerifyWitness is set and a
270  	// transaction includes witness data but doesn't spend an which is a
271  	// witness program (nested or native).
272  	ErrWitnessUnexpected
273  
274  	// ErrWitnessPubKeyType is returned if ScriptVerifyWitness is set and
275  	// the public key used in either a check-sig or check-multi-sig isn't
276  	// serialized in a compressed format.
277  	ErrWitnessPubKeyType
278  
279  	// numErrorCodes is the maximum error code number used in tests.  This
280  	// entry MUST be the last entry in the enum.
281  	numErrorCodes
282  )
283  
284  // Map of ErrorCode values back to their constant names for pretty printing.
285  var errorCodeStrings = map[ErrorCode]string{
286  	ErrInternal:                           "ErrInternal",
287  	ErrInvalidFlags:                       "ErrInvalidFlags",
288  	ErrInvalidIndex:                       "ErrInvalidIndex",
289  	ErrUnsupportedAddress:                 "ErrUnsupportedAddress",
290  	ErrNotMultisigScript:                  "ErrNotMultisigScript",
291  	ErrTooManyRequiredSigs:                "ErrTooManyRequiredSigs",
292  	ErrTooMuchNullData:                    "ErrTooMuchNullData",
293  	ErrEarlyReturn:                        "ErrEarlyReturn",
294  	ErrEmptyStack:                         "ErrEmptyStack",
295  	ErrEvalFalse:                          "ErrEvalFalse",
296  	ErrScriptUnfinished:                   "ErrScriptUnfinished",
297  	ErrInvalidProgramCounter:              "ErrInvalidProgramCounter",
298  	ErrScriptTooBig:                       "ErrScriptTooBig",
299  	ErrElementTooBig:                      "ErrElementTooBig",
300  	ErrTooManyOperations:                  "ErrTooManyOperations",
301  	ErrStackOverflow:                      "ErrStackOverflow",
302  	ErrInvalidPubKeyCount:                 "ErrInvalidPubKeyCount",
303  	ErrInvalidSignatureCount:              "ErrInvalidSignatureCount",
304  	ErrNumberTooBig:                       "ErrNumberTooBig",
305  	ErrVerify:                             "ErrVerify",
306  	ErrEqualVerify:                        "ErrEqualVerify",
307  	ErrNumEqualVerify:                     "ErrNumEqualVerify",
308  	ErrCheckSigVerify:                     "ErrCheckSigVerify",
309  	ErrCheckMultiSigVerify:                "ErrCheckMultiSigVerify",
310  	ErrDisabledOpcode:                     "ErrDisabledOpcode",
311  	ErrReservedOpcode:                     "ErrReservedOpcode",
312  	ErrMalformedPush:                      "ErrMalformedPush",
313  	ErrInvalidStackOperation:              "ErrInvalidStackOperation",
314  	ErrUnbalancedConditional:              "ErrUnbalancedConditional",
315  	ErrMinimalData:                        "ErrMinimalData",
316  	ErrInvalidSigHashType:                 "ErrInvalidSigHashType",
317  	ErrSigDER:                             "ErrSigDER",
318  	ErrSigHighS:                           "ErrSigHighS",
319  	ErrNotPushOnly:                        "ErrNotPushOnly",
320  	ErrSigNullDummy:                       "ErrSigNullDummy",
321  	ErrPubKeyType:                         "ErrPubKeyType",
322  	ErrCleanStack:                         "ErrCleanStack",
323  	ErrNullFail:                           "ErrNullFail",
324  	ErrDiscourageUpgradableNOPs:           "ErrDiscourageUpgradableNOPs",
325  	ErrNegativeLockTime:                   "ErrNegativeLockTime",
326  	ErrUnsatisfiedLockTime:                "ErrUnsatisfiedLockTime",
327  	ErrWitnessProgramEmpty:                "ErrWitnessProgramEmpty",
328  	ErrWitnessProgramMismatch:             "ErrWitnessProgramMismatch",
329  	ErrWitnessProgramWrongLength:          "ErrWitnessProgramWrongLength",
330  	ErrWitnessMalleated:                   "ErrWitnessMalleated",
331  	ErrWitnessMalleatedP2SH:               "ErrWitnessMalleatedP2SH",
332  	ErrWitnessUnexpected:                  "ErrWitnessUnexpected",
333  	ErrMinimalIf:                          "ErrMinimalIf",
334  	ErrWitnessPubKeyType:                  "ErrWitnessPubKeyType",
335  	ErrDiscourageUpgradableWitnessProgram: "ErrDiscourageUpgradableWitnessProgram",
336  }
337  
338  // String returns the ErrorCode as a human-readable name.
339  func (e ErrorCode) String() string {
340  	if s := errorCodeStrings[e]; s != "" {
341  		return s
342  	}
343  	return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
344  }
345  
346  // Error identifies a script-related error.  It is used to indicate three
347  // classes of errors:
348  // 1) Script execution failures due to violating one of the many requirements
349  //    imposed by the script engine or evaluating to false
350  // 2) Improper API usage by callers
351  // 3) Internal consistency check failures
352  //
353  // The caller can use type assertions on the returned errors to access the
354  // ErrorCode field to ascertain the specific reason for the error.  As an
355  // additional convenience, the caller may make use of the IsErrorCode function
356  // to check for a specific error code.
357  type Error struct {
358  	ErrorCode   ErrorCode
359  	Description string
360  }
361  
362  // Error satisfies the error interface and prints human-readable errors.
363  func (e Error) Error() string {
364  	return e.Description
365  }
366  
367  // scriptError creates an Error given a set of arguments.
368  func scriptError(c ErrorCode, desc string) Error {
369  	return Error{ErrorCode: c, Description: desc}
370  }
371  
372  // IsErrorCode returns whether or not the provided error is a script error with
373  // the provided error code.
374  func IsErrorCode(err error, c ErrorCode) bool {
375  	serr, ok := err.(Error)
376  	return ok && serr.ErrorCode == c
377  }