From 8df0af32d605fb56350ab8d989eeab08a4c992d7 Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Fri, 14 Mar 2014 14:48:19 +0000 Subject: [PATCH] Encountering OP_VERIF and OP_VERNOTIF in execution is always an error. I honestly thought we already handled this, but some tests dhill is working on shows that we didn't. --- opcode.go | 16 ++++++++++++++++ script.go | 9 ++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/opcode.go b/opcode.go index 710cd212..3b26b329 100644 --- a/opcode.go +++ b/opcode.go @@ -862,6 +862,22 @@ type parsedOpcode struct { opfunc func(op parsedOpcode, s Script) error } +// The following opcodes are always illegal when passed over by the program +// counter even if in a non-executed branch. (it isn't a coincidence that they +// are conditionals). +func (pop *parsedOpcode) alwaysIllegal() bool { + switch pop.opcode.value { + case OP_VERIF: + return true + case OP_VERNOTIF: + return true + default: + return false + } +} + +// The following opcode are conditional and thus change the conditional +// execution stack state when passed. func (pop *parsedOpcode) conditional() bool { switch pop.opcode.value { case OP_IF: diff --git a/script.go b/script.go index 2177df94..3fe74c3a 100644 --- a/script.go +++ b/script.go @@ -52,6 +52,11 @@ var ( // is encountered. StackErrReservedOpcode = errors.New("Reserved Opcode") + // StackErrAlwaysIllegal is returned when an opcode marked as always + // illegal is encountered. Currently this is just OP_VERIF and + // OP_VERNOTIF. + StackErrAlwaysIllegal = errors.New("Always Illlegal instruction encountered") + // StackErrEarlyReturn is returned when OP_RETURN is executed in the // script. StackErrEarlyReturn = errors.New("Script returned early") @@ -602,7 +607,9 @@ func (m *Script) Step() (done bool, err error) { if m.condStack[0] != OpCondTrue { // some opcodes still 'activate' if on the non-executing side // of conditional execution - if opcode.conditional() { + if opcode.alwaysIllegal() { + return true, StackErrAlwaysIllegal + } else if opcode.conditional() { executeInstr = true } else { executeInstr = false