From f9c1fb952c6a9260443f08ce351c180e1b44d7b3 Mon Sep 17 00:00:00 2001 From: Ekaterina Lebedeva Date: Fri, 4 Aug 2023 12:33:10 +0300 Subject: [PATCH] [#2] Add a custom vm.Run() function It executes loaded program and accumulates all seen opcodes together with the scripthash they belong to. Signed-off-by: Ekaterina Lebedeva --- covertest/run.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 covertest/run.go diff --git a/covertest/run.go b/covertest/run.go new file mode 100644 index 0000000..9ffaa5e --- /dev/null +++ b/covertest/run.go @@ -0,0 +1,58 @@ +package covertest + +import ( + "errors" + + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm" + "github.com/nspcc-dev/neo-go/pkg/vm/opcode" + "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" +) + +// InstrHash maps Instruction with its Script Hash. +type InstrHash struct { + Num int + Instruction opcode.Opcode + ScriptHash util.Uint160 +} + +// Run starts execution of the loaded program and accumulates all seen opcodes +// together with the scripthash they belong to. +func Run(v *vm.VM) ([]InstrHash, error) { + + if !v.Ready() { + return nil, errors.New("no program loaded") + } + + if v.HasFailed() { + // VM already ran something and failed, in general its state is + // undefined in this case so we can't run anything. + return nil, errors.New("VM has failed") + } + + // vmstate.Halt (the default) or vmstate.Break are safe to continue. + var ops []InstrHash + for { + switch { + case v.HasFailed(): + // Should be caught and reported already by the v.Step(), + // but we're checking here anyway just in case. + return ops, errors.New("VM has failed") + case v.HasHalted(), v.AtBreakpoint(): + // Normal exit from this loop. + return ops, nil + case v.State() == vmstate.None: + nStr, curInstr := v.Context().NextInstr() + ops = append(ops, InstrHash{ + Num: nStr, + Instruction: curInstr, + ScriptHash: v.Context().ScriptHash(), + }) + if err := v.Step(); err != nil { + return ops, err + } + default: + return ops, errors.New("unknown state") + } + } +}