vm: move InteropNameToID to emit package

This commit is contained in:
Evgenii Stratonikov 2020-04-15 17:13:50 +03:00
parent 93d2a3e031
commit bfbbef952a
9 changed files with 40 additions and 34 deletions

View file

@ -6,6 +6,7 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -54,7 +55,7 @@ func getPanicSource(need bool, message string) string {
} }
func logGetter(logs *[]string) vm.InteropGetterFunc { func logGetter(logs *[]string) vm.InteropGetterFunc {
logID := vm.InteropNameToID([]byte("Neo.Runtime.Log")) logID := emit.InteropNameToID([]byte("Neo.Runtime.Log"))
return func(id uint32) *vm.InteropFuncPrice { return func(id uint32) *vm.InteropFuncPrice {
if id != logID { if id != logID {
return nil return nil

View file

@ -6,6 +6,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -18,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
src := getVerifyProg(pub, sig, msg) src := getVerifyProg(pub, sig, msg)
v, p := vmAndCompileInterop(t, src) v, p := vmAndCompileInterop(t, src)
p.interops[vm.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))] = func(v *vm.VM) error { p.interops[emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))] = func(v *vm.VM) error {
assert.Equal(t, msg, v.Estack().Pop().Bytes()) assert.Equal(t, msg, v.Estack().Pop().Bytes())
assert.Equal(t, pub, v.Estack().Pop().Bytes()) assert.Equal(t, pub, v.Estack().Pop().Bytes())
assert.Equal(t, sig, v.Estack().Pop().Bytes()) assert.Equal(t, sig, v.Estack().Pop().Bytes())

View file

@ -7,6 +7,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -80,10 +81,10 @@ func newStoragePlugin() *storagePlugin {
mem: make(map[string][]byte), mem: make(map[string][]byte),
interops: make(map[uint32]vm.InteropFunc), interops: make(map[uint32]vm.InteropFunc),
} }
s.interops[vm.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get s.interops[emit.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get
s.interops[vm.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put s.interops[emit.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put
s.interops[vm.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext s.interops[emit.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext
s.interops[vm.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify s.interops[emit.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify
return s return s
} }

View file

@ -19,6 +19,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
) )
// SpawnVM returns a VM with script getter and interop functions set // SpawnVM returns a VM with script getter and interop functions set
@ -263,7 +264,7 @@ var neoInterops = []interop.Function{
// Function slice and then sorts it. // Function slice and then sorts it.
func initIDinInteropsSlice(iops []interop.Function) { func initIDinInteropsSlice(iops []interop.Function) {
for i := range iops { for i := range iops {
iops[i].ID = vm.InteropNameToID([]byte(iops[i].Name)) iops[i].ID = emit.InteropNameToID([]byte(iops[i].Name))
} }
sort.Slice(iops, func(i, j int) bool { sort.Slice(iops, func(i, j int) bool {
return iops[i].ID < iops[j].ID return iops[i].ID < iops[j].ID

View file

@ -63,7 +63,7 @@ func (cs *Contracts) SetNEO(n *NEO) {
func NewContractMD(name string) *ContractMD { func NewContractMD(name string) *ContractMD {
c := &ContractMD{ c := &ContractMD{
ServiceName: name, ServiceName: name,
ServiceID: vm.InteropNameToID([]byte(name)), ServiceID: emit.InteropNameToID([]byte(name)),
Methods: make(map[string]MethodAndPrice), Methods: make(map[string]MethodAndPrice),
} }

View file

@ -1,6 +1,7 @@
package emit package emit
import ( import (
"crypto/sha256"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@ -168,3 +169,9 @@ func isInstructionJmp(op opcode.Opcode) bool {
} }
return false return false
} }
// InteropNameToID returns an identificator of the method based on its name.
func InteropNameToID(name []byte) uint32 {
h := sha256.Sum256(name)
return binary.LittleEndian.Uint32(h[:4])
}

View file

@ -1,11 +1,11 @@
package vm package vm
import ( import (
"crypto/sha256"
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"sort" "sort"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
) )
// InteropFunc allows to hook into the VM. // InteropFunc allows to hook into the VM.
@ -28,35 +28,35 @@ type interopIDFuncPrice struct {
type InteropGetterFunc func(uint32) *InteropFuncPrice type InteropGetterFunc func(uint32) *InteropFuncPrice
var defaultVMInterops = []interopIDFuncPrice{ var defaultVMInterops = []interopIDFuncPrice{
{InteropNameToID([]byte("Neo.Runtime.Log")), {emit.InteropNameToID([]byte("Neo.Runtime.Log")),
InteropFuncPrice{runtimeLog, 1}}, InteropFuncPrice{runtimeLog, 1}},
{InteropNameToID([]byte("Neo.Runtime.Notify")), {emit.InteropNameToID([]byte("Neo.Runtime.Notify")),
InteropFuncPrice{runtimeNotify, 1}}, InteropFuncPrice{runtimeNotify, 1}},
{InteropNameToID([]byte("Neo.Runtime.Serialize")), {emit.InteropNameToID([]byte("Neo.Runtime.Serialize")),
InteropFuncPrice{RuntimeSerialize, 1}}, InteropFuncPrice{RuntimeSerialize, 1}},
{InteropNameToID([]byte("System.Runtime.Serialize")), {emit.InteropNameToID([]byte("System.Runtime.Serialize")),
InteropFuncPrice{RuntimeSerialize, 1}}, InteropFuncPrice{RuntimeSerialize, 1}},
{InteropNameToID([]byte("Neo.Runtime.Deserialize")), {emit.InteropNameToID([]byte("Neo.Runtime.Deserialize")),
InteropFuncPrice{RuntimeDeserialize, 1}}, InteropFuncPrice{RuntimeDeserialize, 1}},
{InteropNameToID([]byte("System.Runtime.Deserialize")), {emit.InteropNameToID([]byte("System.Runtime.Deserialize")),
InteropFuncPrice{RuntimeDeserialize, 1}}, InteropFuncPrice{RuntimeDeserialize, 1}},
{InteropNameToID([]byte("Neo.Enumerator.Create")), {emit.InteropNameToID([]byte("Neo.Enumerator.Create")),
InteropFuncPrice{EnumeratorCreate, 1}}, InteropFuncPrice{EnumeratorCreate, 1}},
{InteropNameToID([]byte("Neo.Enumerator.Next")), {emit.InteropNameToID([]byte("Neo.Enumerator.Next")),
InteropFuncPrice{EnumeratorNext, 1}}, InteropFuncPrice{EnumeratorNext, 1}},
{InteropNameToID([]byte("Neo.Enumerator.Concat")), {emit.InteropNameToID([]byte("Neo.Enumerator.Concat")),
InteropFuncPrice{EnumeratorConcat, 1}}, InteropFuncPrice{EnumeratorConcat, 1}},
{InteropNameToID([]byte("Neo.Enumerator.Value")), {emit.InteropNameToID([]byte("Neo.Enumerator.Value")),
InteropFuncPrice{EnumeratorValue, 1}}, InteropFuncPrice{EnumeratorValue, 1}},
{InteropNameToID([]byte("Neo.Iterator.Create")), {emit.InteropNameToID([]byte("Neo.Iterator.Create")),
InteropFuncPrice{IteratorCreate, 1}}, InteropFuncPrice{IteratorCreate, 1}},
{InteropNameToID([]byte("Neo.Iterator.Concat")), {emit.InteropNameToID([]byte("Neo.Iterator.Concat")),
InteropFuncPrice{IteratorConcat, 1}}, InteropFuncPrice{IteratorConcat, 1}},
{InteropNameToID([]byte("Neo.Iterator.Key")), {emit.InteropNameToID([]byte("Neo.Iterator.Key")),
InteropFuncPrice{IteratorKey, 1}}, InteropFuncPrice{IteratorKey, 1}},
{InteropNameToID([]byte("Neo.Iterator.Keys")), {emit.InteropNameToID([]byte("Neo.Iterator.Keys")),
InteropFuncPrice{IteratorKeys, 1}}, InteropFuncPrice{IteratorKeys, 1}},
{InteropNameToID([]byte("Neo.Iterator.Values")), {emit.InteropNameToID([]byte("Neo.Iterator.Values")),
InteropFuncPrice{IteratorValues, 1}}, InteropFuncPrice{IteratorValues, 1}},
} }
@ -70,12 +70,6 @@ func getDefaultVMInterop(id uint32) *InteropFuncPrice {
return nil return nil
} }
// InteropNameToID returns an identificator of the method based on its name.
func InteropNameToID(name []byte) uint32 {
h := sha256.Sum256(name)
return binary.LittleEndian.Uint32(h[:4])
}
// runtimeLog handles the syscall "Neo.Runtime.Log" for printing and logging stuff. // runtimeLog handles the syscall "Neo.Runtime.Log" for printing and logging stuff.
func runtimeLog(vm *VM) error { func runtimeLog(vm *VM) error {
item := vm.Estack().Pop() item := vm.Estack().Pop()

View file

@ -14,6 +14,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"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/pkg/errors" "github.com/pkg/errors"
) )
@ -483,7 +484,7 @@ func GetInteropID(parameter []byte) uint32 {
return binary.LittleEndian.Uint32(parameter) return binary.LittleEndian.Uint32(parameter)
} }
return InteropNameToID(parameter) return emit.InteropNameToID(parameter)
} }
// GetInteropByID returns interop function together with price. // GetInteropByID returns interop function together with price.

View file

@ -19,7 +19,7 @@ import (
) )
func fooInteropGetter(id uint32) *InteropFuncPrice { func fooInteropGetter(id uint32) *InteropFuncPrice {
if id == InteropNameToID([]byte("foo")) { if id == emit.InteropNameToID([]byte("foo")) {
return &InteropFuncPrice{func(evm *VM) error { return &InteropFuncPrice{func(evm *VM) error {
evm.Estack().PushVal(1) evm.Estack().PushVal(1)
return nil return nil
@ -46,7 +46,7 @@ func TestInteropHookViaID(t *testing.T) {
v.RegisterInteropGetter(fooInteropGetter) v.RegisterInteropGetter(fooInteropGetter)
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
fooid := InteropNameToID([]byte("foo")) fooid := emit.InteropNameToID([]byte("foo"))
var id = make([]byte, 4) var id = make([]byte, 4)
binary.LittleEndian.PutUint32(id, fooid) binary.LittleEndian.PutUint32(id, fooid)
emit.Syscall(buf.BinWriter, string(id)) emit.Syscall(buf.BinWriter, string(id))