From bfbbef952ab3e62abb263b20ddbf60bec2aab23c Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 15 Apr 2020 17:13:50 +0300 Subject: [PATCH] vm: move InteropNameToID to emit package --- pkg/compiler/panic_test.go | 3 ++- pkg/compiler/verify_test.go | 3 ++- pkg/compiler/vm_test.go | 9 +++++---- pkg/core/interops.go | 3 ++- pkg/core/native/contract.go | 2 +- pkg/vm/emit/emit.go | 7 +++++++ pkg/vm/interop.go | 40 ++++++++++++++++--------------------- pkg/vm/vm.go | 3 ++- pkg/vm/vm_test.go | 4 ++-- 9 files changed, 40 insertions(+), 34 deletions(-) diff --git a/pkg/compiler/panic_test.go b/pkg/compiler/panic_test.go index cdc857a82..e8e506db4 100644 --- a/pkg/compiler/panic_test.go +++ b/pkg/compiler/panic_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/nspcc-dev/neo-go/pkg/vm" + "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/stretchr/testify/require" ) @@ -54,7 +55,7 @@ func getPanicSource(need bool, message string) string { } 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 { if id != logID { return nil diff --git a/pkg/compiler/verify_test.go b/pkg/compiler/verify_test.go index 8d0151625..9ea772f13 100644 --- a/pkg/compiler/verify_test.go +++ b/pkg/compiler/verify_test.go @@ -6,6 +6,7 @@ import ( "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/emit" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -18,7 +19,7 @@ func TestVerifyGood(t *testing.T) { src := getVerifyProg(pub, sig, msg) 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, pub, v.Estack().Pop().Bytes()) assert.Equal(t, sig, v.Estack().Pop().Bytes()) diff --git a/pkg/compiler/vm_test.go b/pkg/compiler/vm_test.go index b97d14acd..c180bf55a 100644 --- a/pkg/compiler/vm_test.go +++ b/pkg/compiler/vm_test.go @@ -7,6 +7,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/compiler" "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/require" ) @@ -80,10 +81,10 @@ func newStoragePlugin() *storagePlugin { mem: make(map[string][]byte), interops: make(map[uint32]vm.InteropFunc), } - s.interops[vm.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get - s.interops[vm.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put - s.interops[vm.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext - s.interops[vm.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify + s.interops[emit.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get + s.interops[emit.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put + s.interops[emit.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext + s.interops[emit.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify return s } diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 05443042e..ccb040bd6 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -19,6 +19,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" "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 @@ -263,7 +264,7 @@ var neoInterops = []interop.Function{ // Function slice and then sorts it. func initIDinInteropsSlice(iops []interop.Function) { 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 { return iops[i].ID < iops[j].ID diff --git a/pkg/core/native/contract.go b/pkg/core/native/contract.go index 150fb4ee8..332276320 100644 --- a/pkg/core/native/contract.go +++ b/pkg/core/native/contract.go @@ -63,7 +63,7 @@ func (cs *Contracts) SetNEO(n *NEO) { func NewContractMD(name string) *ContractMD { c := &ContractMD{ ServiceName: name, - ServiceID: vm.InteropNameToID([]byte(name)), + ServiceID: emit.InteropNameToID([]byte(name)), Methods: make(map[string]MethodAndPrice), } diff --git a/pkg/vm/emit/emit.go b/pkg/vm/emit/emit.go index 81d81ecef..1aed92884 100644 --- a/pkg/vm/emit/emit.go +++ b/pkg/vm/emit/emit.go @@ -1,6 +1,7 @@ package emit import ( + "crypto/sha256" "encoding/binary" "errors" "fmt" @@ -168,3 +169,9 @@ func isInstructionJmp(op opcode.Opcode) bool { } 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]) +} diff --git a/pkg/vm/interop.go b/pkg/vm/interop.go index d1ec282ba..930892f27 100644 --- a/pkg/vm/interop.go +++ b/pkg/vm/interop.go @@ -1,11 +1,11 @@ package vm import ( - "crypto/sha256" - "encoding/binary" "errors" "fmt" "sort" + + "github.com/nspcc-dev/neo-go/pkg/vm/emit" ) // InteropFunc allows to hook into the VM. @@ -28,35 +28,35 @@ type interopIDFuncPrice struct { type InteropGetterFunc func(uint32) *InteropFuncPrice var defaultVMInterops = []interopIDFuncPrice{ - {InteropNameToID([]byte("Neo.Runtime.Log")), + {emit.InteropNameToID([]byte("Neo.Runtime.Log")), InteropFuncPrice{runtimeLog, 1}}, - {InteropNameToID([]byte("Neo.Runtime.Notify")), + {emit.InteropNameToID([]byte("Neo.Runtime.Notify")), InteropFuncPrice{runtimeNotify, 1}}, - {InteropNameToID([]byte("Neo.Runtime.Serialize")), + {emit.InteropNameToID([]byte("Neo.Runtime.Serialize")), InteropFuncPrice{RuntimeSerialize, 1}}, - {InteropNameToID([]byte("System.Runtime.Serialize")), + {emit.InteropNameToID([]byte("System.Runtime.Serialize")), InteropFuncPrice{RuntimeSerialize, 1}}, - {InteropNameToID([]byte("Neo.Runtime.Deserialize")), + {emit.InteropNameToID([]byte("Neo.Runtime.Deserialize")), InteropFuncPrice{RuntimeDeserialize, 1}}, - {InteropNameToID([]byte("System.Runtime.Deserialize")), + {emit.InteropNameToID([]byte("System.Runtime.Deserialize")), InteropFuncPrice{RuntimeDeserialize, 1}}, - {InteropNameToID([]byte("Neo.Enumerator.Create")), + {emit.InteropNameToID([]byte("Neo.Enumerator.Create")), InteropFuncPrice{EnumeratorCreate, 1}}, - {InteropNameToID([]byte("Neo.Enumerator.Next")), + {emit.InteropNameToID([]byte("Neo.Enumerator.Next")), InteropFuncPrice{EnumeratorNext, 1}}, - {InteropNameToID([]byte("Neo.Enumerator.Concat")), + {emit.InteropNameToID([]byte("Neo.Enumerator.Concat")), InteropFuncPrice{EnumeratorConcat, 1}}, - {InteropNameToID([]byte("Neo.Enumerator.Value")), + {emit.InteropNameToID([]byte("Neo.Enumerator.Value")), InteropFuncPrice{EnumeratorValue, 1}}, - {InteropNameToID([]byte("Neo.Iterator.Create")), + {emit.InteropNameToID([]byte("Neo.Iterator.Create")), InteropFuncPrice{IteratorCreate, 1}}, - {InteropNameToID([]byte("Neo.Iterator.Concat")), + {emit.InteropNameToID([]byte("Neo.Iterator.Concat")), InteropFuncPrice{IteratorConcat, 1}}, - {InteropNameToID([]byte("Neo.Iterator.Key")), + {emit.InteropNameToID([]byte("Neo.Iterator.Key")), InteropFuncPrice{IteratorKey, 1}}, - {InteropNameToID([]byte("Neo.Iterator.Keys")), + {emit.InteropNameToID([]byte("Neo.Iterator.Keys")), InteropFuncPrice{IteratorKeys, 1}}, - {InteropNameToID([]byte("Neo.Iterator.Values")), + {emit.InteropNameToID([]byte("Neo.Iterator.Values")), InteropFuncPrice{IteratorValues, 1}}, } @@ -70,12 +70,6 @@ func getDefaultVMInterop(id uint32) *InteropFuncPrice { 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. func runtimeLog(vm *VM) error { item := vm.Estack().Pop() diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index ba11b3e80..43eda9542 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -14,6 +14,7 @@ import ( "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/util" + "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/pkg/errors" ) @@ -483,7 +484,7 @@ func GetInteropID(parameter []byte) uint32 { return binary.LittleEndian.Uint32(parameter) } - return InteropNameToID(parameter) + return emit.InteropNameToID(parameter) } // GetInteropByID returns interop function together with price. diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index afe15ce62..56698c2c0 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -19,7 +19,7 @@ import ( ) func fooInteropGetter(id uint32) *InteropFuncPrice { - if id == InteropNameToID([]byte("foo")) { + if id == emit.InteropNameToID([]byte("foo")) { return &InteropFuncPrice{func(evm *VM) error { evm.Estack().PushVal(1) return nil @@ -46,7 +46,7 @@ func TestInteropHookViaID(t *testing.T) { v.RegisterInteropGetter(fooInteropGetter) buf := io.NewBufBinWriter() - fooid := InteropNameToID([]byte("foo")) + fooid := emit.InteropNameToID([]byte("foo")) var id = make([]byte, 4) binary.LittleEndian.PutUint32(id, fooid) emit.Syscall(buf.BinWriter, string(id))