[#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 <ekaterina.lebedeva@yadro.com>
master
Ekaterina Lebedeva 2023-08-04 12:33:10 +03:00
parent 6519282570
commit f9c1fb952c
1 changed files with 58 additions and 0 deletions

58
covertest/run.go 100644
View File

@ -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")
}
}
}