From 31212676f24256568521150af94600224175b09d Mon Sep 17 00:00:00 2001 From: Vsevolod Brekelov Date: Tue, 15 Oct 2019 16:15:07 +0300 Subject: [PATCH 1/6] rpc: swap fmt to log for response handling --- pkg/rpc/request.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/rpc/request.go b/pkg/rpc/request.go index bc555a724..342baf3ba 100644 --- a/pkg/rpc/request.go +++ b/pkg/rpc/request.go @@ -2,7 +2,6 @@ package rpc import ( "encoding/json" - "fmt" "io" "net/http" @@ -114,7 +113,12 @@ func (r Request) writeServerResponse(w http.ResponseWriter, response Response) { encoder := json.NewEncoder(w) err := encoder.Encode(response) + logFields := log.Fields{ + "err": err, + "method": r.Method, + } + if err != nil { - fmt.Println(err) + log.WithFields(logFields).Error("Error encountered while encoding response") } } From ced2022273f3a9c233c80acd6c65e6c6806b7c8a Mon Sep 17 00:00:00 2001 From: Vsevolod Brekelov Date: Tue, 15 Oct 2019 16:25:49 +0300 Subject: [PATCH 2/6] storage: change println error for botldb to log --- pkg/core/storage/boltdb_store.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/core/storage/boltdb_store.go b/pkg/core/storage/boltdb_store.go index e8afd0ded..93a8ae6e9 100644 --- a/pkg/core/storage/boltdb_store.go +++ b/pkg/core/storage/boltdb_store.go @@ -7,6 +7,7 @@ import ( "path" "github.com/etcd-io/bbolt" + log "github.com/sirupsen/logrus" "github.com/syndtr/goleveldb/leveldb/util" ) @@ -110,7 +111,7 @@ func (s *BoltDBStore) Seek(key []byte, f func(k, v []byte)) { return nil }) if err != nil { - fmt.Println("error while executing seek in boltDB") + log.Error("error while executing seek in boltDB") } } From 5b81110d162c3a5487c9fbb5c61f467359ba5b94 Mon Sep 17 00:00:00 2001 From: Vsevolod Brekelov Date: Wed, 16 Oct 2019 13:47:42 +0300 Subject: [PATCH 3/6] cli: print logo via shell --- pkg/vm/cli/cli.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/vm/cli/cli.go b/pkg/vm/cli/cli.go index f871db287..b5c53d434 100644 --- a/pkg/vm/cli/cli.go +++ b/pkg/vm/cli/cli.go @@ -367,7 +367,7 @@ func changePrompt(c ishell.Actions, v *vm.VM) { // Run waits for user input from Stdin and executes the passed command. func (c *VMCLI) Run() error { - printLogo() + printLogo(c.shell) c.shell.Run() return nil } @@ -418,7 +418,7 @@ func parseArgs(args []string) ([]vm.StackItem, error) { return items, nil } -func printLogo() { +func printLogo(c *ishell.Shell) { logo := ` _ ____________ __________ _ ____ ___ / | / / ____/ __ \ / ____/ __ \ | | / / |/ / @@ -426,7 +426,7 @@ func printLogo() { / /| / /___/ /_/ /_____/ /_/ / /_/ /_____/ |/ / / / / /_/ |_/_____/\____/ \____/\____/ |___/_/ /_/ ` - fmt.Print(logo) - fmt.Println() - fmt.Println() + c.Print(logo) + c.Println() + c.Println() } From 0daef50b9d91a3e24ab6796478527145e2acf91d Mon Sep 17 00:00:00 2001 From: Vsevolod Brekelov Date: Wed, 16 Oct 2019 15:11:17 +0300 Subject: [PATCH 4/6] cli: fix for error wrapping --- pkg/vm/cli/cli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/vm/cli/cli.go b/pkg/vm/cli/cli.go index b5c53d434..e3363e7d4 100644 --- a/pkg/vm/cli/cli.go +++ b/pkg/vm/cli/cli.go @@ -213,7 +213,7 @@ func handleBreak(c *ishell.Context) { } v := getVMFromContext(c) if len(c.Args) != 1 { - c.Err(errors.New("Missing parameter ")) + c.Err(errors.New("missing parameter ")) } n, err := strconv.Atoi(c.Args[0]) if err != nil { From f2805541cbdc6b925932ee188e77e59df88ad2f3 Mon Sep 17 00:00:00 2001 From: Vsevolod Brekelov Date: Fri, 18 Oct 2019 18:28:08 +0300 Subject: [PATCH 5/6] vm: fix style and comments --- pkg/vm/vm.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index c914fd829..ca2315739 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -79,12 +79,12 @@ func New(mode Mode) *VM { return vm } -// RegisterInteropFunc will register the given InteropFunc to the VM. +// RegisterInteropFunc registers the given InteropFunc to the VM. func (v *VM) RegisterInteropFunc(name string, f InteropFunc, price int) { v.interop[name] = InteropFuncPrice{f, price} } -// RegisterInteropFuncs will register all interop functions passed in a map in +// RegisterInteropFuncs registers all interop functions passed in a map in // the VM. Effectively it's a batched version of RegisterInteropFunc. func (v *VM) RegisterInteropFuncs(interops map[string]InteropFuncPrice) { // We allow reregistration here. @@ -93,22 +93,22 @@ func (v *VM) RegisterInteropFuncs(interops map[string]InteropFuncPrice) { } } -// Estack will return the evaluation stack so interop hooks can utilize this. +// Estack returns the evaluation stack so interop hooks can utilize this. func (v *VM) Estack() *Stack { return v.estack } -// Astack will return the alt stack so interop hooks can utilize this. +// Astack returns the alt stack so interop hooks can utilize this. func (v *VM) Astack() *Stack { return v.astack } -// Istack will return the invocation stack so interop hooks can utilize this. +// Istack returns the invocation stack so interop hooks can utilize this. func (v *VM) Istack() *Stack { return v.istack } -// LoadArgs will load in the arguments used in the Mian entry point. +// LoadArgs loads in the arguments used in the Mian entry point. func (v *VM) LoadArgs(method []byte, args []StackItem) { if len(args) > 0 { v.estack.PushVal(args) @@ -118,7 +118,7 @@ func (v *VM) LoadArgs(method []byte, args []StackItem) { } } -// PrintOps will print the opcodes of the current loaded program to stdout. +// PrintOps prints the opcodes of the current loaded program to stdout. func (v *VM) PrintOps() { w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0) fmt.Fprintln(w, "INDEX\tOPCODE\tPARAMETER\t") @@ -176,7 +176,7 @@ func (v *VM) AddBreakPointRel(n int) { v.AddBreakPoint(ctx.ip + n) } -// LoadFile will load a program from the given path, ready to execute it. +// LoadFile loads a program from the given path, ready to execute it. func (v *VM) LoadFile(path string) error { b, err := ioutil.ReadFile(path) if err != nil { @@ -195,7 +195,7 @@ func (v *VM) Load(prog []byte) { v.istack.PushVal(NewContext(prog)) } -// LoadScript will load a script from the internal script table. It +// LoadScript loads a script from the internal script table. It // will immediately push a new context created from this script to // the invocation stack and starts executing it. func (v *VM) LoadScript(b []byte) { @@ -237,7 +237,7 @@ func (v *VM) Stack(n string) string { return buildStackOutput(s) } -// Ready return true if the VM ready to execute the loaded program. +// Ready returns true if the VM ready to execute the loaded program. // Will return false if no program is loaded. func (v *VM) Ready() bool { return v.istack.Len() > 0 @@ -289,7 +289,7 @@ func (v *VM) Step() { v.execute(ctx, op, param) } -// StepInto behaves the same as “step over” in case if the line does not contain a function it otherwise +// StepInto behaves the same as “step over” in case if the line does not contain a function. Otherwise // the debugger will enter the called function and continue line-by-line debugging there. func (v *VM) StepInto() { ctx := v.Context() @@ -436,11 +436,13 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { panic("can't TUCK with a one-element stack") } v.estack.InsertAt(a, 2) + case CAT: b := v.estack.Pop().Bytes() a := v.estack.Pop().Bytes() ab := append(a, b...) v.estack.PushVal(ab) + case SUBSTR: l := int(v.estack.Pop().BigInt().Int64()) if l < 0 { @@ -459,6 +461,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { last = len(s) } v.estack.PushVal(s[o:last]) + case LEFT: l := int(v.estack.Pop().BigInt().Int64()) if l < 0 { @@ -469,6 +472,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { l = t } v.estack.PushVal(s[:l]) + case RIGHT: l := int(v.estack.Pop().BigInt().Int64()) if l < 0 { @@ -476,6 +480,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { } s := v.estack.Pop().Bytes() v.estack.PushVal(s[len(s)-l:]) + case XDROP: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { From e2bfff86662f541fd40fcaa6e3221eeb4edfe61b Mon Sep 17 00:00:00 2001 From: Vsevolod Brekelov Date: Tue, 22 Oct 2019 13:44:14 +0300 Subject: [PATCH 6/6] vm: removed mute mode and pushed logging to upper lvl VM should be responsible for code execution and in case anyone interested in additional logging or errors they could handle them like we do it iin cli. --- cli/vm/vm.go | 2 +- pkg/core/blockchain.go | 11 +- pkg/vm/cli/cli.go | 43 ++- pkg/vm/compiler/compiler.go | 2 +- pkg/vm/tests/vm_test.go | 9 +- pkg/vm/vm.go | 124 ++++---- pkg/vm/vm_test.go | 591 +++++++++++++----------------------- 7 files changed, 326 insertions(+), 456 deletions(-) diff --git a/cli/vm/vm.go b/cli/vm/vm.go index 35a8f92c2..27e9638a3 100644 --- a/cli/vm/vm.go +++ b/cli/vm/vm.go @@ -48,7 +48,7 @@ func inspect(ctx *cli.Context) error { if err != nil { return cli.NewExitError(err, 1) } - v := vm.New(0) + v := vm.New() v.LoadScript(b) v.PrintOps() return nil diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index a20a6a5f1..1476863cf 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -407,7 +407,7 @@ func (bc *Blockchain) storeBlock(block *Block) error { contracts[contract.ScriptHash()] = contract case *transaction.InvocationTX: - vm := vm.New(vm.ModeMute) + vm := vm.New() vm.SetCheckedHash(tx.VerificationHash().Bytes()) vm.SetScriptGetter(func(hash util.Uint160) []byte { cs := bc.GetContractState(hash) @@ -421,7 +421,7 @@ func (bc *Blockchain) storeBlock(block *Block) error { vm.RegisterInteropFuncs(systemInterop.getSystemInteropMap()) vm.RegisterInteropFuncs(systemInterop.getNeoInteropMap()) vm.LoadScript(t.Script) - vm.Run() + err := vm.Run() if !vm.HasFailed() { _, err := systemInterop.mem.Persist() if err != nil { @@ -431,6 +431,7 @@ func (bc *Blockchain) storeBlock(block *Block) error { log.WithFields(log.Fields{ "tx": tx.Hash().ReverseString(), "block": block.Index, + "err": err, }).Warn("contract invocation failed") } } @@ -1091,7 +1092,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa } } - vm := vm.New(vm.ModeMute) + vm := vm.New() vm.SetCheckedHash(checkedHash.Bytes()) vm.SetScriptGetter(func(hash util.Uint160) []byte { cs := bc.GetContractState(hash) @@ -1104,9 +1105,9 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa vm.RegisterInteropFuncs(interopCtx.getNeoInteropMap()) vm.LoadScript(verification) vm.LoadScript(witness.InvocationScript) - vm.Run() + err := vm.Run() if vm.HasFailed() { - return errors.Errorf("vm failed to execute the script") + return errors.Errorf("vm failed to execute the script with error: %s", err) } resEl := vm.Estack().Pop() if resEl != nil { diff --git a/pkg/vm/cli/cli.go b/pkg/vm/cli/cli.go index e3363e7d4..3083e0b6e 100644 --- a/pkg/vm/cli/cli.go +++ b/pkg/vm/cli/cli.go @@ -169,7 +169,7 @@ type VMCLI struct { // New returns a new VMCLI object. func New() *VMCLI { vmcli := VMCLI{ - vm: vm.New(0), + vm: vm.New(), shell: ishell.New(), } vmcli.shell.Set(vmKey, vmcli.vm) @@ -286,16 +286,40 @@ func handleRun(c *ishell.Context) { } v.LoadArgs(method, params) } - v.Run() + runVMWithHandling(c, v) changePrompt(c, v) } +// runVMWithHandling runs VM with handling errors and additional state messages. +func runVMWithHandling(c *ishell.Context, v *vm.VM) { + err := v.Run() + if err != nil { + c.Err(err) + return + } + + var message string + switch { + case v.HasFailed(): + message = "FAILED" + case v.HasHalted(): + message = v.Stack("estack") + case v.AtBreakpoint(): + ctx := v.Context() + i, op := ctx.CurrInstr() + message = fmt.Sprintf("at breakpoint %d (%s)\n", i, op.String()) + } + if message != "" { + c.Printf(message) + } +} + func handleCont(c *ishell.Context) { if !checkVMIsReady(c) { return } v := getVMFromContext(c) - v.Run() + runVMWithHandling(c, v) changePrompt(c, v) } @@ -317,7 +341,7 @@ func handleStep(c *ishell.Context) { } } v.AddBreakPointRel(n) - v.Run() + runVMWithHandling(c, v) changePrompt(c, v) } @@ -338,14 +362,19 @@ func handleStepType(c *ishell.Context, stepType string) { return } v := getVMFromContext(c) + var err error switch stepType { case "into": - v.StepInto() + err = v.StepInto() case "out": - v.StepOut() + err = v.StepOut() case "over": - v.StepOver() + err = v.StepOver() } + if err != nil { + c.Err(err) + } + handleIP(c) changePrompt(c, v) } diff --git a/pkg/vm/compiler/compiler.go b/pkg/vm/compiler/compiler.go index 94bf31ee8..6477b90ae 100644 --- a/pkg/vm/compiler/compiler.go +++ b/pkg/vm/compiler/compiler.go @@ -107,7 +107,7 @@ func CompileAndInspect(src string) error { return err } - v := vm.New(0) + v := vm.New() v.LoadScript(b) v.PrintOps() return nil diff --git a/pkg/vm/tests/vm_test.go b/pkg/vm/tests/vm_test.go index 885e3ebc6..47078363f 100644 --- a/pkg/vm/tests/vm_test.go +++ b/pkg/vm/tests/vm_test.go @@ -8,6 +8,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/vm" "github.com/CityOfZion/neo-go/pkg/vm/compiler" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type testCase struct { @@ -24,14 +25,16 @@ func run_testcases(t *testing.T, tcases []testCase) { func eval(t *testing.T, src string, result interface{}) { vm := vmAndCompile(t, src) - vm.Run() + err := vm.Run() + require.NoError(t, err) assertResult(t, vm, result) } func evalWithArgs(t *testing.T, src string, op []byte, args []vm.StackItem, result interface{}) { vm := vmAndCompile(t, src) vm.LoadArgs(op, args) - vm.Run() + err := vm.Run() + require.NoError(t, err) assertResult(t, vm, result) } @@ -42,7 +45,7 @@ func assertResult(t *testing.T, vm *vm.VM, result interface{}) { } func vmAndCompile(t *testing.T, src string) *vm.VM { - vm := vm.New(vm.ModeMute) + vm := vm.New() storePlugin := newStoragePlugin() vm.RegisterInteropFunc("Neo.Storage.Get", storePlugin.Get, 1) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index ca2315739..c8f47828a 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -5,7 +5,6 @@ import ( "encoding/binary" "fmt" "io/ioutil" - "log" "math/big" "os" "reflect" @@ -15,15 +14,25 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/util" + "github.com/pkg/errors" ) -// Mode configures behaviour of the VM. -type Mode uint +type errorAtInstruct struct { + ip int + op Instruction + err interface{} +} -// Available VM Modes. -var ( - ModeMute Mode = 1 << 0 -) +func (e *errorAtInstruct) Error() string { + return fmt.Sprintf("error encountered at instruction %d (%s): %s", e.ip, e.op, e.err) +} + +func newError(ip int, op Instruction, err interface{}) *errorAtInstruct { + return &errorAtInstruct{ip: ip, op: op, err: err} +} + +// StateMessage is a vm state message which could be used as additional info for example by cli. +type StateMessage string const ( // MaxArraySize is the maximum array size allowed in the VM. @@ -46,8 +55,6 @@ type VM struct { estack *Stack // execution stack. astack *Stack // alt stack. - // Mute all output after execution. - mute bool // Hash to verify in CHECKSIG/CHECKMULTISIG. checkhash []byte } @@ -59,7 +66,7 @@ type InteropFuncPrice struct { } // New returns a new VM object ready to load .avm bytecode scripts. -func New(mode Mode) *VM { +func New() *VM { vm := &VM{ interop: make(map[string]InteropFuncPrice), getScript: nil, @@ -68,9 +75,6 @@ func New(mode Mode) *VM { estack: NewStack("evaluation"), astack: NewStack("alt"), } - if mode == ModeMute { - vm.mute = true - } // Register native interop hooks. vm.RegisterInteropFunc("Neo.Runtime.Log", runtimeLog, 1) @@ -244,10 +248,10 @@ func (v *VM) Ready() bool { } // Run starts the execution of the loaded program. -func (v *VM) Run() { +func (v *VM) Run() error { if !v.Ready() { - fmt.Println("no program loaded") - return + v.state = faultState + return errors.New("no program loaded") } v.state = noneState @@ -258,40 +262,33 @@ func (v *VM) Run() { v.state |= breakState } switch { - case v.state.HasFlag(faultState): - fmt.Println("FAULT") - return - case v.state.HasFlag(haltState): - if !v.mute { - fmt.Println(v.Stack("estack")) - } - return - case v.state.HasFlag(breakState): - ctx := v.Context() - i, op := ctx.CurrInstr() - fmt.Printf("at breakpoint %d (%s)\n", i, op.String()) - return + case v.state.HasFlag(faultState), v.state.HasFlag(haltState), v.state.HasFlag(breakState): + return errors.New("VM stopped") case v.state == noneState: - v.Step() + if err := v.Step(); err != nil { + return err + } + default: + v.state = faultState + return errors.New("unknown state") } } } // Step 1 instruction in the program. -func (v *VM) Step() { +func (v *VM) Step() error { ctx := v.Context() op, param, err := ctx.Next() if err != nil { - log.Printf("error encountered at instruction %d (%s)", ctx.ip, op) - log.Println(err) v.state = faultState + return newError(ctx.ip, op, err) } - v.execute(ctx, op, param) + return v.execute(ctx, op, param) } // StepInto behaves the same as “step over” in case if the line does not contain a function. Otherwise // the debugger will enter the called function and continue line-by-line debugging there. -func (v *VM) StepInto() { +func (v *VM) StepInto() error { ctx := v.Context() if ctx == nil { @@ -299,29 +296,31 @@ func (v *VM) StepInto() { } if v.HasStopped() { - return + return nil } if ctx != nil && ctx.prog != nil { op, param, err := ctx.Next() if err != nil { - log.Printf("error encountered at instruction %d (%s)", ctx.ip, op) - log.Println(err) v.state = faultState + return newError(ctx.ip, op, err) + } + vErr := v.execute(ctx, op, param) + if vErr != nil { + return vErr } - v.execute(ctx, op, param) - i, op := ctx.CurrInstr() - fmt.Printf("at breakpoint %d (%s)\n", i, op.String()) } cctx := v.Context() if cctx != nil && cctx.atBreakPoint() { v.state = breakState } + return nil } // StepOut takes the debugger to the line where the current function was called. -func (v *VM) StepOut() { +func (v *VM) StepOut() error { + var err error if v.state == breakState { v.state = noneState } else { @@ -330,15 +329,17 @@ func (v *VM) StepOut() { expSize := v.istack.len for v.state.HasFlag(noneState) && v.istack.len >= expSize { - v.StepInto() + err = v.StepInto() } + return err } // StepOver takes the debugger to the line that will step over a given line. // If the line contains a function the function will be executed and the result returned without debugging each line. -func (v *VM) StepOver() { +func (v *VM) StepOver() error { + var err error if v.HasStopped() { - return + return err } if v.state == breakState { @@ -349,11 +350,12 @@ func (v *VM) StepOver() { expSize := v.istack.len for { - v.StepInto() + err = v.StepInto() if !(v.state.HasFlag(noneState) && v.istack.len > expSize) { break } } + return err } // HasFailed returns whether VM is in the failed state now. Usually used to @@ -367,6 +369,16 @@ func (v *VM) HasStopped() bool { return v.state.HasFlag(haltState) || v.state.HasFlag(faultState) } +// HasHalted returns whether VM is in Halt state. +func (v *VM) HasHalted() bool { + return v.state.HasFlag(haltState) +} + +// AtBreakpoint returns whether VM is at breakpoint. +func (v *VM) AtBreakpoint() bool { + return v.state.HasFlag(breakState) +} + // SetCheckedHash sets checked hash for CHECKSIG and CHECKMULTISIG instructions. func (v *VM) SetCheckedHash(h []byte) { v.checkhash = make([]byte, len(h)) @@ -379,14 +391,13 @@ func (v *VM) SetScriptGetter(gs func(util.Uint160) []byte) { } // execute performs an instruction cycle in the VM. Acting on the instruction (opcode). -func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { +func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) { // Instead of polluting the whole VM logic with error handling, we will recover - // each panic at a central point, putting the VM in a fault state. + // each panic at a central point, putting the VM in a fault state and setting error. defer func() { - if err := recover(); err != nil { - log.Printf("error encountered at instruction %d (%s)", ctx.ip, op) - log.Println(err) + if errRecover := recover(); errRecover != nil { v.state = faultState + err = newError(ctx.ip, op, errRecover) } }() @@ -961,7 +972,10 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { case CALL: v.istack.PushVal(ctx.Copy()) - v.execute(v.Context(), JMP, parameter) + err = v.execute(v.Context(), JMP, parameter) + if err != nil { + return + } case SYSCALL: ifunc, ok := v.interop[string(parameter)] @@ -1161,6 +1175,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) { default: panic(fmt.Sprintf("unknown opcode %s", op.String())) } + return } func cloneIfStruct(item StackItem) StackItem { @@ -1189,8 +1204,3 @@ func validateMapKey(key *Element) { panic("key can't be a collection") } } - -func init() { - log.SetPrefix("NEO-GO-VM > ") - log.SetFlags(0) -} diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index d2f09923e..edda68b55 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -11,10 +11,11 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/util" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestInteropHook(t *testing.T) { - v := New(ModeMute) + v := New() v.RegisterInteropFunc("foo", func(evm *VM) error { evm.Estack().PushVal(1) return nil @@ -24,14 +25,13 @@ func TestInteropHook(t *testing.T) { EmitSyscall(buf, "foo") EmitOpcode(buf, RET) v.Load(buf.Bytes()) - v.Run() - assert.Equal(t, false, v.HasFailed()) + runVM(t, v) assert.Equal(t, 1, v.estack.Len()) assert.Equal(t, big.NewInt(1), v.estack.Pop().value.Value()) } func TestRegisterInterop(t *testing.T) { - v := New(ModeMute) + v := New() currRegistered := len(v.interop) v.RegisterInteropFunc("foo", func(evm *VM) error { return nil }, 1) assert.Equal(t, currRegistered+1, len(v.interop)) @@ -45,7 +45,8 @@ func TestPushBytes1to75(t *testing.T) { b := randomBytes(i) EmitBytes(buf, b) vm := load(buf.Bytes()) - vm.Step() + err := vm.Step() + require.NoError(t, err) assert.Equal(t, 1, vm.estack.Len()) @@ -54,7 +55,8 @@ func TestPushBytes1to75(t *testing.T) { assert.IsType(t, elem.Bytes(), b) assert.Equal(t, 0, vm.estack.Len()) - vm.execute(nil, RET, nil) + errExec := vm.execute(nil, RET, nil) + require.NoError(t, errExec) assert.Equal(t, 0, vm.astack.Len()) assert.Equal(t, 0, vm.istack.Len()) @@ -66,7 +68,18 @@ func TestPushBytesNoParam(t *testing.T) { prog := make([]byte, 1) prog[0] = byte(PUSHBYTES1) vm := load(prog) - vm.Run() + checkVMFailed(t, vm) +} + +func runVM(t *testing.T, vm *VM) { + err := vm.Run() + require.NoError(t, err) + assert.Equal(t, false, vm.HasFailed()) +} + +func checkVMFailed(t *testing.T, vm *VM) { + err := vm.Run() + require.Error(t, err) assert.Equal(t, true, vm.HasFailed()) } @@ -74,8 +87,7 @@ func TestPushBytesShort(t *testing.T) { prog := make([]byte, 10) prog[0] = byte(PUSHBYTES10) // but only 9 left in the `prog` vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushm1to16(t *testing.T) { @@ -92,7 +104,8 @@ func TestPushm1to16(t *testing.T) { if i == 80 { continue // nice opcode layout we got here. } - vm.Step() + err := vm.Step() + require.NoError(t, err) elem := vm.estack.Pop() assert.IsType(t, &BigIntegerItem{}, elem.value) @@ -104,22 +117,19 @@ func TestPushm1to16(t *testing.T) { func TestPushData1BadNoN(t *testing.T) { prog := []byte{byte(PUSHDATA1)} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData1BadN(t *testing.T) { prog := []byte{byte(PUSHDATA1), 1} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData1Good(t *testing.T) { prog := makeProgram(PUSHDATA1, 3, 1, 2, 3) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte{1, 2, 3}, vm.estack.Pop().Bytes()) } @@ -127,29 +137,25 @@ func TestPushData1Good(t *testing.T) { func TestPushData2BadNoN(t *testing.T) { prog := []byte{byte(PUSHDATA2)} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData2ShortN(t *testing.T) { prog := []byte{byte(PUSHDATA2), 0} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData2BadN(t *testing.T) { prog := []byte{byte(PUSHDATA2), 1, 0} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData2Good(t *testing.T) { prog := makeProgram(PUSHDATA2, 3, 0, 1, 2, 3) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte{1, 2, 3}, vm.estack.Pop().Bytes()) } @@ -157,29 +163,25 @@ func TestPushData2Good(t *testing.T) { func TestPushData4BadNoN(t *testing.T) { prog := []byte{byte(PUSHDATA4)} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData4BadN(t *testing.T) { prog := []byte{byte(PUSHDATA4), 1, 0, 0, 0} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData4ShortN(t *testing.T) { prog := []byte{byte(PUSHDATA4), 0, 0, 0} vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPushData4Good(t *testing.T) { prog := makeProgram(PUSHDATA4, 3, 0, 0, 0, 1, 2, 3) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte{1, 2, 3}, vm.estack.Pop().Bytes()) } @@ -187,16 +189,14 @@ func TestPushData4Good(t *testing.T) { func TestNOTNoArgument(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestNOTBool(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) vm.estack.PushVal(false) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) } @@ -204,8 +204,7 @@ func TestNOTNonZeroInt(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } @@ -213,8 +212,7 @@ func TestNOTArray(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) vm.estack.PushVal([]StackItem{}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } @@ -222,8 +220,7 @@ func TestNOTStruct(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) vm.estack.Push(NewElement(&StructItem{[]StackItem{}})) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } @@ -231,8 +228,7 @@ func TestNOTByteArray0(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) vm.estack.PushVal([]byte{0, 0}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) } @@ -240,8 +236,7 @@ func TestNOTByteArray1(t *testing.T) { prog := makeProgram(NOT) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } @@ -250,8 +245,7 @@ func TestAdd(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(6), vm.estack.Pop().BigInt().Int64()) } @@ -260,8 +254,7 @@ func TestMul(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(8), vm.estack.Pop().BigInt().Int64()) } @@ -270,8 +263,7 @@ func TestDiv(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(2), vm.estack.Pop().BigInt().Int64()) } @@ -280,8 +272,7 @@ func TestSub(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(2), vm.estack.Pop().BigInt().Int64()) } @@ -290,8 +281,7 @@ func TestSHRGood(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) } @@ -301,8 +291,7 @@ func TestSHRZero(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte{0, 1}) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) } @@ -312,8 +301,7 @@ func TestSHRSmallValue(t *testing.T) { vm := load(prog) vm.estack.PushVal(5) vm.estack.PushVal(-257) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSHLGood(t *testing.T) { @@ -321,8 +309,7 @@ func TestSHLGood(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(16), vm.estack.Pop().value) } @@ -332,8 +319,7 @@ func TestSHLZero(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte{0, 1}) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) } @@ -343,8 +329,7 @@ func TestSHLBigValue(t *testing.T) { vm := load(prog) vm.estack.PushVal(5) vm.estack.PushVal(257) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestLT(t *testing.T) { @@ -352,8 +337,7 @@ func TestLT(t *testing.T) { vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -362,8 +346,7 @@ func TestLTE(t *testing.T) { vm := load(prog) vm.estack.PushVal(2) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -372,8 +355,7 @@ func TestGT(t *testing.T) { vm := load(prog) vm.estack.PushVal(9) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -383,8 +365,7 @@ func TestGTE(t *testing.T) { vm := load(prog) vm.estack.PushVal(3) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -394,24 +375,21 @@ func TestDepth(t *testing.T) { vm.estack.PushVal(1) vm.estack.PushVal(2) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(3), vm.estack.Pop().BigInt().Int64()) } func TestEQUALNoArguments(t *testing.T) { prog := makeProgram(EQUAL) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestEQUALBad1Argument(t *testing.T) { prog := makeProgram(EQUAL) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestEQUALGoodInteger(t *testing.T) { @@ -419,8 +397,7 @@ func TestEQUALGoodInteger(t *testing.T) { vm := load(prog) vm.estack.PushVal(5) vm.estack.PushVal(5) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) } @@ -429,8 +406,7 @@ func TestEQUALArrayTrue(t *testing.T) { prog := makeProgram(DUP, EQUAL) vm := load(prog) vm.estack.PushVal([]StackItem{}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) } @@ -440,8 +416,7 @@ func TestEQUALArrayFalse(t *testing.T) { vm := load(prog) vm.estack.PushVal([]StackItem{}) vm.estack.PushVal([]StackItem{}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } @@ -450,8 +425,7 @@ func TestEQUALMapTrue(t *testing.T) { prog := makeProgram(DUP, EQUAL) vm := load(prog) vm.estack.Push(&Element{value: NewMapItem()}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) } @@ -461,8 +435,7 @@ func TestEQUALMapFalse(t *testing.T) { vm := load(prog) vm.estack.Push(&Element{value: NewMapItem()}) vm.estack.Push(&Element{value: NewMapItem()}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } @@ -472,8 +445,7 @@ func TestNumEqual(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -482,8 +454,7 @@ func TestNumNotEqual(t *testing.T) { vm := load(prog) vm.estack.PushVal(2) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -491,8 +462,7 @@ func TestINC(t *testing.T) { prog := makeProgram(INC) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, big.NewInt(2), vm.estack.Pop().BigInt()) } @@ -500,8 +470,7 @@ func TestNEWARRAYInteger(t *testing.T) { prog := makeProgram(NEWARRAY) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{[]StackItem{makeStackItem(false)}}, vm.estack.Pop().value) } @@ -511,8 +480,7 @@ func TestNEWARRAYStruct(t *testing.T) { vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &StructItem{arr}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) } @@ -522,8 +490,7 @@ func TestNEWARRAYArray(t *testing.T) { vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &ArrayItem{arr}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) } @@ -532,8 +499,7 @@ func TestNEWARRAYByteArray(t *testing.T) { prog := makeProgram(NEWARRAY) vm := load(prog) vm.estack.PushVal([]byte{}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{[]StackItem{}}, vm.estack.Pop().value) } @@ -542,16 +508,14 @@ func TestNEWARRAYBadSize(t *testing.T) { prog := makeProgram(NEWARRAY) vm := load(prog) vm.estack.PushVal(MaxArraySize + 1) - vm.Run() - assert.Equal(t, true, vm.state.HasFlag(faultState)) + checkVMFailed(t, vm) } func TestNEWSTRUCTInteger(t *testing.T) { prog := makeProgram(NEWSTRUCT) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &StructItem{[]StackItem{makeStackItem(false)}}, vm.estack.Pop().value) } @@ -561,8 +525,7 @@ func TestNEWSTRUCTArray(t *testing.T) { vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &ArrayItem{arr}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &StructItem{arr}, vm.estack.Pop().value) } @@ -572,8 +535,7 @@ func TestNEWSTRUCTStruct(t *testing.T) { vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &StructItem{arr}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &StructItem{arr}, vm.estack.Pop().value) } @@ -582,8 +544,7 @@ func TestNEWSTRUCTByteArray(t *testing.T) { prog := makeProgram(NEWSTRUCT) vm := load(prog) vm.estack.PushVal([]byte{}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &StructItem{[]StackItem{}}, vm.estack.Pop().value) } @@ -592,16 +553,14 @@ func TestNEWSTRUCTBadSize(t *testing.T) { prog := makeProgram(NEWSTRUCT) vm := load(prog) vm.estack.PushVal(MaxArraySize + 1) - vm.Run() - assert.Equal(t, true, vm.state.HasFlag(faultState)) + checkVMFailed(t, vm) } func TestAPPENDArray(t *testing.T) { prog := makeProgram(DUP, PUSH5, APPEND) vm := load(prog) vm.estack.Push(&Element{value: &ArrayItem{}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{[]StackItem{makeStackItem(5)}}, vm.estack.Pop().value) } @@ -610,8 +569,7 @@ func TestAPPENDStruct(t *testing.T) { prog := makeProgram(DUP, PUSH5, APPEND) vm := load(prog) vm.estack.Push(&Element{value: &StructItem{}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &StructItem{[]StackItem{makeStackItem(5)}}, vm.estack.Pop().value) } @@ -620,8 +578,7 @@ func TestAPPENDCloneStruct(t *testing.T) { prog := makeProgram(DUP, PUSH0, NEWSTRUCT, TOALTSTACK, DUPFROMALTSTACK, APPEND, FROMALTSTACK, PUSH1, APPEND) vm := load(prog) vm.estack.Push(&Element{value: &ArrayItem{}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{[]StackItem{ &StructItem{[]StackItem{}}, @@ -631,16 +588,14 @@ func TestAPPENDCloneStruct(t *testing.T) { func TestAPPENDBadNoArguments(t *testing.T) { prog := makeProgram(APPEND) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestAPPENDBad1Argument(t *testing.T) { prog := makeProgram(APPEND) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestAPPENDWrongType(t *testing.T) { @@ -648,16 +603,14 @@ func TestAPPENDWrongType(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte{}) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestAPPENDGoodSizeLimit(t *testing.T) { prog := makeProgram(NEWARRAY, DUP, PUSH0, APPEND) vm := load(prog) vm.estack.PushVal(MaxArraySize - 1) - vm.Run() - assert.Equal(t, false, vm.state.HasFlag(faultState)) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, MaxArraySize, len(vm.estack.Pop().Array())) } @@ -666,8 +619,7 @@ func TestAPPENDBadSizeLimit(t *testing.T) { prog := makeProgram(NEWARRAY, DUP, PUSH0, APPEND) vm := load(prog) vm.estack.PushVal(MaxArraySize) - vm.Run() - assert.Equal(t, true, vm.state.HasFlag(faultState)) + checkVMFailed(t, vm) } func TestPICKITEMBadIndex(t *testing.T) { @@ -675,8 +627,7 @@ func TestPICKITEMBadIndex(t *testing.T) { vm := load(prog) vm.estack.PushVal([]StackItem{}) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPICKITEMArray(t *testing.T) { @@ -684,8 +635,7 @@ func TestPICKITEMArray(t *testing.T) { vm := load(prog) vm.estack.PushVal([]StackItem{makeStackItem(1), makeStackItem(2)}) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } @@ -695,8 +645,7 @@ func TestPICKITEMByteArray(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte{1, 2}) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } @@ -710,8 +659,7 @@ func TestPICKITEMMap(t *testing.T) { vm.estack.Push(&Element{value: m}) vm.estack.PushVal(makeStackItem(5)) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(3), vm.estack.Pop().value) } @@ -728,8 +676,7 @@ func TestSETITEMMap(t *testing.T) { vm.estack.PushVal(5) vm.estack.PushVal([]byte{0, 1}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) } @@ -746,8 +693,7 @@ func TestSETITEMBigMapBad(t *testing.T) { vm.estack.PushVal(MaxArraySize) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSETITEMBigMapGood(t *testing.T) { @@ -762,23 +708,20 @@ func TestSETITEMBigMapGood(t *testing.T) { vm.estack.PushVal(0) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) } func TestSIZENoArgument(t *testing.T) { prog := makeProgram(SIZE) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSIZEByteArray(t *testing.T) { prog := makeProgram(SIZE) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } @@ -787,8 +730,7 @@ func TestSIZEBool(t *testing.T) { prog := makeProgram(SIZE) vm := load(prog) vm.estack.PushVal(false) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) } @@ -800,8 +742,7 @@ func TestARRAYSIZEArray(t *testing.T) { makeStackItem(1), makeStackItem([]byte{}), }) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } @@ -815,8 +756,7 @@ func TestARRAYSIZEMap(t *testing.T) { m.Add(makeStackItem([]byte{0, 1}), makeStackItem(6)) vm.estack.Push(&Element{value: m}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } @@ -830,8 +770,7 @@ func TestKEYSMap(t *testing.T) { m.Add(makeStackItem([]byte{0, 1}), makeStackItem(6)) vm.estack.Push(&Element{value: m}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) top := vm.estack.Pop().value.(*ArrayItem) @@ -843,16 +782,14 @@ func TestKEYSMap(t *testing.T) { func TestKEYSNoArgument(t *testing.T) { prog := makeProgram(KEYS) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestKEYSWrongType(t *testing.T) { prog := makeProgram(KEYS) vm := load(prog) vm.estack.PushVal([]StackItem{}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestVALUESMap(t *testing.T) { @@ -864,8 +801,7 @@ func TestVALUESMap(t *testing.T) { m.Add(makeStackItem([]byte{0, 1}), makeStackItem([]StackItem{})) vm.estack.Push(&Element{value: m}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) top := vm.estack.Pop().value.(*ArrayItem) @@ -878,8 +814,7 @@ func TestVALUESArray(t *testing.T) { prog := makeProgram(VALUES) vm := load(prog) vm.estack.PushVal([]StackItem{makeStackItem(4)}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ArrayItem{[]StackItem{makeStackItem(4)}}, vm.estack.Pop().value) } @@ -887,23 +822,20 @@ func TestVALUESArray(t *testing.T) { func TestVALUESNoArgument(t *testing.T) { prog := makeProgram(VALUES) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestVALUESWrongType(t *testing.T) { prog := makeProgram(VALUES) vm := load(prog) vm.estack.PushVal(5) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestHASKEYArrayTrue(t *testing.T) { prog := makeProgram(PUSH5, NEWARRAY, PUSH4, HASKEY) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(true), vm.estack.Pop().value) } @@ -911,8 +843,7 @@ func TestHASKEYArrayTrue(t *testing.T) { func TestHASKEYArrayFalse(t *testing.T) { prog := makeProgram(PUSH5, NEWARRAY, PUSH5, HASKEY) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) } @@ -920,8 +851,7 @@ func TestHASKEYArrayFalse(t *testing.T) { func TestHASKEYStructTrue(t *testing.T) { prog := makeProgram(PUSH5, NEWSTRUCT, PUSH4, HASKEY) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(true), vm.estack.Pop().value) } @@ -929,8 +859,7 @@ func TestHASKEYStructTrue(t *testing.T) { func TestHASKEYStructFalse(t *testing.T) { prog := makeProgram(PUSH5, NEWSTRUCT, PUSH5, HASKEY) vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) } @@ -942,8 +871,7 @@ func TestHASKEYMapTrue(t *testing.T) { m.Add(makeStackItem(5), makeStackItem(6)) vm.estack.Push(&Element{value: m}) vm.estack.PushVal(5) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(true), vm.estack.Pop().value) } @@ -955,8 +883,7 @@ func TestHASKEYMapFalse(t *testing.T) { m.Add(makeStackItem(5), makeStackItem(6)) vm.estack.Push(&Element{value: m}) vm.estack.PushVal(6) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) } @@ -964,16 +891,14 @@ func TestHASKEYMapFalse(t *testing.T) { func TestHASKEYNoArguments(t *testing.T) { prog := makeProgram(HASKEY) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestHASKEY1Argument(t *testing.T) { prog := makeProgram(HASKEY) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestHASKEYWrongKeyType(t *testing.T) { @@ -981,8 +906,7 @@ func TestHASKEYWrongKeyType(t *testing.T) { vm := load(prog) vm.estack.PushVal([]StackItem{}) vm.estack.PushVal([]StackItem{}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestHASKEYWrongCollectionType(t *testing.T) { @@ -990,31 +914,27 @@ func TestHASKEYWrongCollectionType(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSIGNNoArgument(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSIGNWrongType(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) vm.estack.PushVal([]StackItem{}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSIGNBool(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) vm.estack.PushVal(false) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BigIntegerItem{big.NewInt(0)}, vm.estack.Pop().value) } @@ -1023,8 +943,7 @@ func TestSIGNPositiveInt(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BigIntegerItem{big.NewInt(1)}, vm.estack.Pop().value) } @@ -1033,8 +952,7 @@ func TestSIGNNegativeInt(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BigIntegerItem{big.NewInt(-1)}, vm.estack.Pop().value) } @@ -1043,8 +961,7 @@ func TestSIGNZero(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BigIntegerItem{big.NewInt(0)}, vm.estack.Pop().value) } @@ -1053,8 +970,7 @@ func TestSIGNByteArray(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &BigIntegerItem{big.NewInt(1)}, vm.estack.Pop().value) } @@ -1074,8 +990,7 @@ func TestAppCall(t *testing.T) { }) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) elem := vm.estack.Pop() // depth should be 1 assert.Equal(t, int64(1), elem.BigInt().Int64()) } @@ -1089,8 +1004,7 @@ func TestSimpleCall(t *testing.T) { t.Fatal(err) } vm := load(prog) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, result, int(vm.estack.Pop().BigInt().Int64())) } @@ -1098,8 +1012,7 @@ func TestNZtrue(t *testing.T) { prog := makeProgram(NZ) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -1107,8 +1020,7 @@ func TestNZfalse(t *testing.T) { prog := makeProgram(NZ) vm := load(prog) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -1116,16 +1028,14 @@ func TestPICKbadNoitem(t *testing.T) { prog := makeProgram(PICK) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPICKbadNegative(t *testing.T) { prog := makeProgram(PICK) vm := load(prog) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPICKgood(t *testing.T) { @@ -1139,8 +1049,7 @@ func TestPICKgood(t *testing.T) { vm.estack.PushVal(4) vm.estack.PushVal(5) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(result), vm.estack.Pop().BigInt().Int64()) } @@ -1149,8 +1058,7 @@ func TestROTBad(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestROTGood(t *testing.T) { @@ -1159,8 +1067,7 @@ func TestROTGood(t *testing.T) { vm.estack.PushVal(1) vm.estack.PushVal(2) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 3, vm.estack.Len()) assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) assert.Equal(t, makeStackItem(3), vm.estack.Pop().value) @@ -1171,8 +1078,7 @@ func TestXTUCKbadNoitem(t *testing.T) { prog := makeProgram(XTUCK) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXTUCKbadNoN(t *testing.T) { @@ -1180,16 +1086,14 @@ func TestXTUCKbadNoN(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXTUCKbadNegative(t *testing.T) { prog := makeProgram(XTUCK) vm := load(prog) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXTUCKbadZero(t *testing.T) { @@ -1197,8 +1101,7 @@ func TestXTUCKbadZero(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXTUCKgood(t *testing.T) { @@ -1213,8 +1116,7 @@ func TestXTUCKgood(t *testing.T) { vm.estack.PushVal(4) vm.estack.PushVal(topelement) vm.estack.PushVal(xtuckdepth) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(topelement), vm.estack.Peek(0).BigInt().Int64()) assert.Equal(t, int64(topelement), vm.estack.Peek(xtuckdepth).BigInt().Int64()) } @@ -1222,16 +1124,14 @@ func TestXTUCKgood(t *testing.T) { func TestTUCKbadNoitems(t *testing.T) { prog := makeProgram(TUCK) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestTUCKbadNoitem(t *testing.T) { prog := makeProgram(TUCK) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestTUCKgood(t *testing.T) { @@ -1239,8 +1139,7 @@ func TestTUCKgood(t *testing.T) { vm := load(prog) vm.estack.PushVal(42) vm.estack.PushVal(34) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(34), vm.estack.Peek(0).BigInt().Int64()) assert.Equal(t, int64(42), vm.estack.Peek(1).BigInt().Int64()) assert.Equal(t, int64(34), vm.estack.Peek(2).BigInt().Int64()) @@ -1252,8 +1151,7 @@ func TestTUCKgood2(t *testing.T) { vm.estack.PushVal(11) vm.estack.PushVal(42) vm.estack.PushVal(34) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(34), vm.estack.Peek(0).BigInt().Int64()) assert.Equal(t, int64(42), vm.estack.Peek(1).BigInt().Int64()) assert.Equal(t, int64(34), vm.estack.Peek(2).BigInt().Int64()) @@ -1264,8 +1162,7 @@ func TestOVERbadNoitem(t *testing.T) { prog := makeProgram(OVER) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) } @@ -1273,8 +1170,7 @@ func TestOVERbadNoitem(t *testing.T) { func TestOVERbadNoitems(t *testing.T) { prog := makeProgram(OVER) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestOVERgood(t *testing.T) { @@ -1282,8 +1178,7 @@ func TestOVERgood(t *testing.T) { vm := load(prog) vm.estack.PushVal(42) vm.estack.PushVal(34) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(42), vm.estack.Peek(0).BigInt().Int64()) assert.Equal(t, int64(34), vm.estack.Peek(1).BigInt().Int64()) assert.Equal(t, int64(42), vm.estack.Peek(2).BigInt().Int64()) @@ -1294,8 +1189,7 @@ func TestNIPBadNoItem(t *testing.T) { prog := makeProgram(NIP) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestNIPGood(t *testing.T) { @@ -1303,8 +1197,7 @@ func TestNIPGood(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } @@ -1312,24 +1205,21 @@ func TestNIPGood(t *testing.T) { func TestDROPBadNoItem(t *testing.T) { prog := makeProgram(DROP) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestDROPGood(t *testing.T) { prog := makeProgram(DROP) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 0, vm.estack.Len()) } func TestXDROPbadNoitem(t *testing.T) { prog := makeProgram(XDROP) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXDROPbadNoN(t *testing.T) { @@ -1337,8 +1227,7 @@ func TestXDROPbadNoN(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXDROPbadNegative(t *testing.T) { @@ -1346,8 +1235,7 @@ func TestXDROPbadNegative(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestXDROPgood(t *testing.T) { @@ -1357,8 +1245,7 @@ func TestXDROPgood(t *testing.T) { vm.estack.PushVal(1) vm.estack.PushVal(2) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 2, vm.estack.Len()) assert.Equal(t, int64(2), vm.estack.Peek(0).BigInt().Int64()) assert.Equal(t, int64(1), vm.estack.Peek(1).BigInt().Int64()) @@ -1367,16 +1254,14 @@ func TestXDROPgood(t *testing.T) { func TestINVERTbadNoitem(t *testing.T) { prog := makeProgram(INVERT) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestINVERTgood1(t *testing.T) { prog := makeProgram(INVERT) vm := load(prog) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(-1), vm.estack.Peek(0).BigInt().Int64()) } @@ -1384,8 +1269,7 @@ func TestINVERTgood2(t *testing.T) { prog := makeProgram(INVERT) vm := load(prog) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(0), vm.estack.Peek(0).BigInt().Int64()) } @@ -1393,24 +1277,21 @@ func TestINVERTgood3(t *testing.T) { prog := makeProgram(INVERT) vm := load(prog) vm.estack.PushVal(0x69) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, int64(-0x6A), vm.estack.Peek(0).BigInt().Int64()) } func TestCATBadNoArgs(t *testing.T) { prog := makeProgram(CAT) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCATBadOneArg(t *testing.T) { prog := makeProgram(CAT) vm := load(prog) vm.estack.PushVal([]byte("abc")) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCATGood(t *testing.T) { @@ -1418,8 +1299,7 @@ func TestCATGood(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abc")) vm.estack.PushVal([]byte("def")) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("abcdef"), vm.estack.Peek(0).Bytes()) } @@ -1429,8 +1309,7 @@ func TestCATInt0ByteArray(t *testing.T) { vm := load(prog) vm.estack.PushVal(0) vm.estack.PushVal([]byte{}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ByteArrayItem{[]byte{}}, vm.estack.Pop().value) } @@ -1440,8 +1319,7 @@ func TestCATByteArrayInt1(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte{}) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, &ByteArrayItem{[]byte{1}}, vm.estack.Pop().value) } @@ -1449,16 +1327,14 @@ func TestCATByteArrayInt1(t *testing.T) { func TestSUBSTRBadNoArgs(t *testing.T) { prog := makeProgram(SUBSTR) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSUBSTRBadOneArg(t *testing.T) { prog := makeProgram(SUBSTR) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSUBSTRBadTwoArgs(t *testing.T) { @@ -1466,8 +1342,7 @@ func TestSUBSTRBadTwoArgs(t *testing.T) { vm := load(prog) vm.estack.PushVal(0) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSUBSTRGood(t *testing.T) { @@ -1476,8 +1351,7 @@ func TestSUBSTRGood(t *testing.T) { vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(1) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("bc"), vm.estack.Peek(0).Bytes()) } @@ -1488,8 +1362,7 @@ func TestSUBSTRBadOffset(t *testing.T) { vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(7) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSUBSTRBigLen(t *testing.T) { @@ -1498,8 +1371,7 @@ func TestSUBSTRBigLen(t *testing.T) { vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(1) vm.estack.PushVal(6) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("bcdef"), vm.estack.Pop().Bytes()) } @@ -1512,8 +1384,7 @@ func TestSUBSTRBad387(t *testing.T) { vm.estack.PushVal(b) vm.estack.PushVal(1) vm.estack.PushVal(6) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("bcdef"), vm.estack.Pop().Bytes()) } @@ -1524,8 +1395,7 @@ func TestSUBSTRBadNegativeOffset(t *testing.T) { vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(-1) vm.estack.PushVal(3) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestSUBSTRBadNegativeLen(t *testing.T) { @@ -1534,23 +1404,20 @@ func TestSUBSTRBadNegativeLen(t *testing.T) { vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(3) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestLEFTBadNoArgs(t *testing.T) { prog := makeProgram(LEFT) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestLEFTBadNoString(t *testing.T) { prog := makeProgram(LEFT) vm := load(prog) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestLEFTBadNegativeLen(t *testing.T) { @@ -1558,8 +1425,7 @@ func TestLEFTBadNegativeLen(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestLEFTGood(t *testing.T) { @@ -1567,8 +1433,7 @@ func TestLEFTGood(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("ab"), vm.estack.Peek(0).Bytes()) } @@ -1578,8 +1443,7 @@ func TestLEFTGoodLen(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(8) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("abcdef"), vm.estack.Peek(0).Bytes()) } @@ -1587,16 +1451,14 @@ func TestLEFTGoodLen(t *testing.T) { func TestRIGHTBadNoArgs(t *testing.T) { prog := makeProgram(RIGHT) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestRIGHTBadNoString(t *testing.T) { prog := makeProgram(RIGHT) vm := load(prog) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestRIGHTBadNegativeLen(t *testing.T) { @@ -1604,8 +1466,7 @@ func TestRIGHTBadNegativeLen(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(-1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestRIGHTGood(t *testing.T) { @@ -1613,8 +1474,7 @@ func TestRIGHTGood(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(2) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []byte("ef"), vm.estack.Peek(0).Bytes()) } @@ -1624,16 +1484,14 @@ func TestRIGHTBadLen(t *testing.T) { vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(8) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPACKBadLen(t *testing.T) { prog := makeProgram(PACK) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPACKBigLen(t *testing.T) { @@ -1643,16 +1501,14 @@ func TestPACKBigLen(t *testing.T) { vm.estack.PushVal(0) } vm.estack.PushVal(MaxArraySize + 1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestPACKGoodZeroLen(t *testing.T) { prog := makeProgram(PACK) vm := load(prog) vm.estack.PushVal(0) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, []StackItem{}, vm.estack.Peek(0).Array()) } @@ -1667,8 +1523,7 @@ func TestPACKGood(t *testing.T) { vm.estack.PushVal(elements[i]) } vm.estack.PushVal(len(elements)) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 2, vm.estack.Len()) a := vm.estack.Peek(0).Array() assert.Equal(t, len(elements), len(a)) @@ -1683,8 +1538,7 @@ func TestUNPACKBadNotArray(t *testing.T) { prog := makeProgram(UNPACK) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestUNPACKGood(t *testing.T) { @@ -1694,8 +1548,7 @@ func TestUNPACKGood(t *testing.T) { // canary vm.estack.PushVal(1) vm.estack.PushVal(elements) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 5, vm.estack.Len()) assert.Equal(t, int64(len(elements)), vm.estack.Peek(0).BigInt().Int64()) for k, v := range elements { @@ -1708,8 +1561,7 @@ func TestREVERSEBadNotArray(t *testing.T) { prog := makeProgram(REVERSE) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestREVERSEGoodOneElem(t *testing.T) { @@ -1718,8 +1570,7 @@ func TestREVERSEGoodOneElem(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(elements) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 2, vm.estack.Len()) a := vm.estack.Peek(0).Array() assert.Equal(t, len(elements), len(a)) @@ -1743,8 +1594,7 @@ func TestREVERSEGoodStruct(t *testing.T) { } vm.estack.Push(&Element{value: &StructItem{arr}}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 2, vm.estack.Len()) a := vm.estack.Peek(0).Array() assert.Equal(t, len(elements), len(a)) @@ -1766,8 +1616,7 @@ func TestREVERSEGood(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(elements) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 2, vm.estack.Len()) a := vm.estack.Peek(0).Array() assert.Equal(t, len(elements), len(a)) @@ -1782,16 +1631,14 @@ func TestREVERSEGood(t *testing.T) { func TestREMOVEBadNoArgs(t *testing.T) { prog := makeProgram(REMOVE) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestREMOVEBadOneArg(t *testing.T) { prog := makeProgram(REMOVE) vm := load(prog) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestREMOVEBadNotArray(t *testing.T) { @@ -1799,8 +1646,7 @@ func TestREMOVEBadNotArray(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(1) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestREMOVEBadIndex(t *testing.T) { @@ -1809,8 +1655,7 @@ func TestREMOVEBadIndex(t *testing.T) { vm := load(prog) vm.estack.PushVal(elements) vm.estack.PushVal(10) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestREMOVEGood(t *testing.T) { @@ -1820,8 +1665,7 @@ func TestREMOVEGood(t *testing.T) { vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(elements) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 2, vm.estack.Len()) assert.Equal(t, makeStackItem(reselements), vm.estack.Pop().value) assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) @@ -1838,8 +1682,7 @@ func TestREMOVEMap(t *testing.T) { vm.estack.Push(&Element{value: m}) vm.estack.PushVal(makeStackItem(5)) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) } @@ -1847,8 +1690,7 @@ func TestREMOVEMap(t *testing.T) { func TestCHECKSIGNoArgs(t *testing.T) { prog := makeProgram(CHECKSIG) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKSIGOneArg(t *testing.T) { @@ -1858,8 +1700,7 @@ func TestCHECKSIGOneArg(t *testing.T) { pbytes := pk.PublicKey().Bytes() vm := load(prog) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKSIGNoSigLoaded(t *testing.T) { @@ -1873,8 +1714,7 @@ func TestCHECKSIGNoSigLoaded(t *testing.T) { vm := load(prog) vm.estack.PushVal(sig) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKSIGBadKey(t *testing.T) { @@ -1889,8 +1729,7 @@ func TestCHECKSIGBadKey(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal(sig) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKSIGWrongSig(t *testing.T) { @@ -1905,8 +1744,7 @@ func TestCHECKSIGWrongSig(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal(util.ArrayReverse(sig)) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -1923,8 +1761,7 @@ func TestCHECKSIGGood(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal(sig) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -1941,8 +1778,7 @@ func TestVERIFYGood(t *testing.T) { vm.estack.PushVal(msg) vm.estack.PushVal(sig) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -1959,8 +1795,7 @@ func TestVERIFYBad(t *testing.T) { vm.estack.PushVal(util.ArrayReverse(msg)) vm.estack.PushVal(sig) vm.estack.PushVal(pbytes) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -1968,8 +1803,7 @@ func TestVERIFYBad(t *testing.T) { func TestCHECKMULTISIGNoArgs(t *testing.T) { prog := makeProgram(CHECKMULTISIG) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKMULTISIGOneArg(t *testing.T) { @@ -1979,8 +1813,7 @@ func TestCHECKMULTISIGOneArg(t *testing.T) { vm := load(prog) pbytes := pk.PublicKey().Bytes() vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes)}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKMULTISIGNotEnoughKeys(t *testing.T) { @@ -1999,8 +1832,7 @@ func TestCHECKMULTISIGNotEnoughKeys(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)}) vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1)}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKMULTISIGNoHash(t *testing.T) { @@ -2019,8 +1851,7 @@ func TestCHECKMULTISIGNoHash(t *testing.T) { vm := load(prog) vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)}) vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKMULTISIGBadKey(t *testing.T) { @@ -2040,8 +1871,7 @@ func TestCHECKMULTISIGBadKey(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)}) vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)}) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) + checkVMFailed(t, vm) } func TestCHECKMULTISIGBadSig(t *testing.T) { @@ -2061,8 +1891,7 @@ func TestCHECKMULTISIGBadSig(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal([]StackItem{NewByteArrayItem(util.ArrayReverse(sig1)), NewByteArrayItem(sig2)}) vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, false, vm.estack.Pop().Bool()) } @@ -2084,8 +1913,7 @@ func TestCHECKMULTISIGGood(t *testing.T) { vm.SetCheckedHash(hash.Sha256(msg).Bytes()) vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)}) vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)}) - vm.Run() - assert.Equal(t, false, vm.HasFailed()) + runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) assert.Equal(t, true, vm.estack.Pop().Bool()) } @@ -2100,8 +1928,7 @@ func makeProgram(opcodes ...Instruction) []byte { } func load(prog []byte) *VM { - vm := New(ModeMute) - vm.mute = true + vm := New() vm.istack.PushVal(NewContext(prog)) return vm }