vm: move InteropNameToID to emit package
This commit is contained in:
parent
93d2a3e031
commit
bfbbef952a
9 changed files with 40 additions and 34 deletions
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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])
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue