vm: remove default syscall handler
It's not needed anymore. Close #1075.
This commit is contained in:
parent
33ae8d0ddc
commit
f45d8fc08d
3 changed files with 17 additions and 68 deletions
|
@ -1,66 +0,0 @@
|
||||||
package vm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
|
||||||
)
|
|
||||||
|
|
||||||
// interopIDFuncPrice adds an ID to the InteropFuncPrice.
|
|
||||||
type interopIDFuncPrice struct {
|
|
||||||
ID uint32
|
|
||||||
Func func(vm *VM) error
|
|
||||||
Price int64
|
|
||||||
RequiredFlags callflag.CallFlag
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultVMInterops = []interopIDFuncPrice{
|
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemRuntimeLog)),
|
|
||||||
Func: runtimeLog, Price: 1 << 15, RequiredFlags: callflag.AllowNotify},
|
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemRuntimeNotify)),
|
|
||||||
Func: runtimeNotify, Price: 1 << 15, RequiredFlags: callflag.AllowNotify},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
sort.Slice(defaultVMInterops, func(i, j int) bool { return defaultVMInterops[i].ID < defaultVMInterops[j].ID })
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultSyscallHandler(v *VM, id uint32) error {
|
|
||||||
n := sort.Search(len(defaultVMInterops), func(i int) bool {
|
|
||||||
return defaultVMInterops[i].ID >= id
|
|
||||||
})
|
|
||||||
if n >= len(defaultVMInterops) || defaultVMInterops[n].ID != id {
|
|
||||||
return errors.New("syscall not found")
|
|
||||||
}
|
|
||||||
d := defaultVMInterops[n]
|
|
||||||
ctxFlag := v.Context().sc.callFlag
|
|
||||||
if !ctxFlag.Has(d.RequiredFlags) {
|
|
||||||
return fmt.Errorf("missing call flags: %05b vs %05b", ctxFlag, d.RequiredFlags)
|
|
||||||
}
|
|
||||||
return d.Func(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// runtimeLog handles the syscall "System.Runtime.Log" for printing and logging stuff.
|
|
||||||
func runtimeLog(vm *VM) error {
|
|
||||||
msg := vm.Estack().Pop().String()
|
|
||||||
fmt.Printf("NEO-GO-VM (log) > %s\n", msg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// runtimeNotify handles the syscall "System.Runtime.Notify" for printing and logging stuff.
|
|
||||||
func runtimeNotify(vm *VM) error {
|
|
||||||
name := vm.Estack().Pop().String()
|
|
||||||
item := vm.Estack().Pop()
|
|
||||||
fmt.Printf("NEO-GO-VM (notify) > [%s] %s\n", name, item.Value())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// init sorts the global defaultVMInterops value.
|
|
||||||
func init() {
|
|
||||||
sort.Slice(defaultVMInterops, func(i, j int) bool {
|
|
||||||
return defaultVMInterops[i].ID < defaultVMInterops[j].ID
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -108,8 +108,6 @@ func NewWithTrigger(t trigger.Type) *VM {
|
||||||
vm := &VM{
|
vm := &VM{
|
||||||
state: vmstate.None,
|
state: vmstate.None,
|
||||||
trigger: t,
|
trigger: t,
|
||||||
|
|
||||||
SyscallHandler: defaultSyscallHandler,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initStack(&vm.istack, "invocation", nil)
|
initStack(&vm.istack, "invocation", nil)
|
||||||
|
@ -1458,6 +1456,9 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
|
|
||||||
case opcode.SYSCALL:
|
case opcode.SYSCALL:
|
||||||
interopID := GetInteropID(parameter)
|
interopID := GetInteropID(parameter)
|
||||||
|
if v.SyscallHandler == nil {
|
||||||
|
panic("vm's SyscallHandler is not initialized")
|
||||||
|
}
|
||||||
err := v.SyscallHandler(v, interopID)
|
err := v.SyscallHandler(v, interopID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to invoke syscall %d: %s", interopID, err))
|
panic(fmt.Sprintf("failed to invoke syscall %d: %s", interopID, err))
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
@ -2747,6 +2748,19 @@ func TestRemoveReferrer(t *testing.T) {
|
||||||
assert.Equal(t, 0, int(vm.refs))
|
assert.Equal(t, 0, int(vm.refs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUninitializedSyscallHandler(t *testing.T) {
|
||||||
|
v := newTestVM()
|
||||||
|
v.Reset(trigger.Application) // Reset SyscallHandler.
|
||||||
|
id := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(id, interopnames.ToID([]byte(interopnames.SystemRuntimeGasLeft)))
|
||||||
|
script := append([]byte{byte(opcode.SYSCALL)}, id...)
|
||||||
|
v.LoadScript(script)
|
||||||
|
err := v.Run()
|
||||||
|
require.Error(t, err)
|
||||||
|
require.True(t, strings.Contains(err.Error(), "SyscallHandler is not initialized"), err.Error())
|
||||||
|
assert.Equal(t, true, v.HasFailed())
|
||||||
|
}
|
||||||
|
|
||||||
func makeProgram(opcodes ...opcode.Opcode) []byte {
|
func makeProgram(opcodes ...opcode.Opcode) []byte {
|
||||||
prog := make([]byte, len(opcodes)+1) // RET
|
prog := make([]byte, len(opcodes)+1) // RET
|
||||||
for i := 0; i < len(opcodes); i++ {
|
for i := 0; i < len(opcodes); i++ {
|
||||||
|
|
Loading…
Reference in a new issue