vm: move InteropNameToID to a separate package

This commit is contained in:
Evgenii Stratonikov 2020-08-13 10:41:33 +03:00
parent 9cc6e22365
commit f3650e20b0
14 changed files with 60 additions and 52 deletions

View file

@ -6,8 +6,8 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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"
) )
@ -56,7 +56,7 @@ func getPanicSource(need bool, message string) string {
} }
func getLogHandler(logs *[]string) vm.SyscallHandler { func getLogHandler(logs *[]string) vm.SyscallHandler {
logID := emit.InteropNameToID([]byte("System.Runtime.Log")) logID := interopnames.ToID([]byte("System.Runtime.Log"))
return func(v *vm.VM, id uint32) error { return func(v *vm.VM, id uint32) error {
if id != logID { if id != logID {
return errors.New("syscall not found") return errors.New("syscall not found")

View file

@ -4,9 +4,9 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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"
) )
@ -19,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[emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))] = func(v *vm.VM) error { p.interops[interopnames.ToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))] = 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,11 +7,11 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"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/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -109,10 +109,10 @@ func newStoragePlugin() *storagePlugin {
mem: make(map[string][]byte), mem: make(map[string][]byte),
interops: make(map[uint32]func(v *vm.VM) error), interops: make(map[uint32]func(v *vm.VM) error),
} }
s.interops[emit.InteropNameToID([]byte("System.Storage.Get"))] = s.Get s.interops[interopnames.ToID([]byte("System.Storage.Get"))] = s.Get
s.interops[emit.InteropNameToID([]byte("System.Storage.Put"))] = s.Put s.interops[interopnames.ToID([]byte("System.Storage.Put"))] = s.Put
s.interops[emit.InteropNameToID([]byte("System.Storage.GetContext"))] = s.GetContext s.interops[interopnames.ToID([]byte("System.Storage.GetContext"))] = s.GetContext
s.interops[emit.InteropNameToID([]byte("System.Runtime.Notify"))] = s.Notify s.interops[interopnames.ToID([]byte("System.Runtime.Notify"))] = s.Notify
return s return s
} }

View file

@ -4,8 +4,8 @@ import (
"errors" "errors"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
@ -27,7 +27,7 @@ func Invoke(ic *interop.Context) error {
cb.LoadContext(ic.VM, args) cb.LoadContext(ic.VM, args)
switch t := cb.(type) { switch t := cb.(type) {
case *MethodCallback: case *MethodCallback:
id := emit.InteropNameToID([]byte("System.Contract.Call")) id := interopnames.ToID([]byte("System.Contract.Call"))
return ic.SyscallHandler(ic.VM, id) return ic.SyscallHandler(ic.VM, id)
case *SyscallCallback: case *SyscallCallback:
return ic.SyscallHandler(ic.VM, t.desc.ID) return ic.SyscallHandler(ic.VM, t.desc.ID)

View file

@ -2,16 +2,16 @@ package crypto
import ( import (
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
) )
var ( var (
ecdsaSecp256r1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1")) ecdsaSecp256r1VerifyID = interopnames.ToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
ecdsaSecp256k1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256k1")) ecdsaSecp256k1VerifyID = interopnames.ToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256k1"))
ecdsaSecp256r1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")) ecdsaSecp256r1CheckMultisigID = interopnames.ToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
ecdsaSecp256k1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256k1")) ecdsaSecp256k1CheckMultisigID = interopnames.ToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256k1"))
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256")) sha256ID = interopnames.ToID([]byte("Neo.Crypto.SHA256"))
ripemd160ID = emit.InteropNameToID([]byte("Neo.Crypto.RIPEMD160")) ripemd160ID = interopnames.ToID([]byte("Neo.Crypto.RIPEMD160"))
) )
var cryptoInterops = []interop.Function{ var cryptoInterops = []interop.Function{

View file

@ -0,0 +1,12 @@
package interopnames
import (
"crypto/sha256"
"encoding/binary"
)
// ToID returns an identificator of the method based on its name.
func ToID(name []byte) uint32 {
h := sha256.Sum256(name)
return binary.LittleEndian.Uint32(h[:4])
}

View file

@ -5,15 +5,15 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var ( var (
serializeID = emit.InteropNameToID([]byte("System.Json.Serialize")) serializeID = interopnames.ToID([]byte("System.Json.Serialize"))
deserializeID = emit.InteropNameToID([]byte("System.Json.Deserialize")) deserializeID = interopnames.ToID([]byte("System.Json.Deserialize"))
) )
var jsonInterops = []interop.Function{ var jsonInterops = []interop.Function{

View file

@ -12,13 +12,13 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/interop/callback" "github.com/nspcc-dev/neo-go/pkg/core/interop/callback"
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator" "github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator" "github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
"github.com/nspcc-dev/neo-go/pkg/core/interop/json" "github.com/nspcc-dev/neo-go/pkg/core/interop/json"
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"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
@ -125,7 +125,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 = emit.InteropNameToID([]byte(iops[i].Name)) iops[i].ID = interopnames.ToID([]byte(iops[i].Name))
} }
interop.Sort(iops) interop.Sort(iops)
} }

View file

@ -3,9 +3,9 @@ package smartcontract
import ( import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/io" "github.com/nspcc-dev/neo-go/pkg/io"
"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/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -34,7 +34,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.PUSHNULL, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.PUSHNULL, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE()) assert.Equal(t, interopnames.ToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE())
} }
func TestCreateDefaultMultiSigRedeemScript(t *testing.T) { func TestCreateDefaultMultiSigRedeemScript(t *testing.T) {

View file

@ -3,15 +3,15 @@ package vm
import ( import (
"encoding/binary" "encoding/binary"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/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"
) )
var ( var (
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1")) verifyInteropID = interopnames.ToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")) multisigInteropID = interopnames.ToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
) )
func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) { func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {

View file

@ -1,13 +1,13 @@
package emit package emit
import ( import (
"crypto/sha256"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"math/bits" "math/bits"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -124,7 +124,7 @@ func Syscall(w *io.BinWriter, api string) {
return return
} }
buf := make([]byte, 4) buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, InteropNameToID([]byte(api))) binary.LittleEndian.PutUint32(buf, interopnames.ToID([]byte(api)))
Instruction(w, opcode.SYSCALL, buf) Instruction(w, opcode.SYSCALL, buf)
} }
@ -162,9 +162,3 @@ func AppCallWithOperationAndArgs(w *io.BinWriter, scriptHash util.Uint160, opera
func isInstructionJmp(op opcode.Opcode) bool { func isInstructionJmp(op opcode.Opcode) bool {
return opcode.JMP <= op && op <= opcode.CALLL return opcode.JMP <= op && op <= opcode.CALLL
} }
// 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

@ -5,6 +5,7 @@ import (
"errors" "errors"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
@ -201,7 +202,7 @@ func TestEmitSyscall(t *testing.T) {
result := buf.Bytes() result := buf.Bytes()
assert.Equal(t, 5, len(result)) assert.Equal(t, 5, len(result))
assert.Equal(t, opcode.Opcode(result[0]), opcode.SYSCALL) assert.Equal(t, opcode.Opcode(result[0]), opcode.SYSCALL)
assert.Equal(t, binary.LittleEndian.Uint32(result[1:]), InteropNameToID([]byte(syscall))) assert.Equal(t, binary.LittleEndian.Uint32(result[1:]), interopnames.ToID([]byte(syscall)))
buf.Reset() buf.Reset()
} }

View file

@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"sort" "sort"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
@ -19,31 +19,31 @@ type interopIDFuncPrice struct {
} }
var defaultVMInterops = []interopIDFuncPrice{ var defaultVMInterops = []interopIDFuncPrice{
{ID: emit.InteropNameToID([]byte("System.Binary.Deserialize")), {ID: interopnames.ToID([]byte("System.Binary.Deserialize")),
Func: RuntimeDeserialize, Price: 500000}, Func: RuntimeDeserialize, Price: 500000},
{ID: emit.InteropNameToID([]byte("System.Binary.Serialize")), {ID: interopnames.ToID([]byte("System.Binary.Serialize")),
Func: RuntimeSerialize, Price: 100000}, Func: RuntimeSerialize, Price: 100000},
{ID: emit.InteropNameToID([]byte("System.Runtime.Log")), {ID: interopnames.ToID([]byte("System.Runtime.Log")),
Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify}, Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify},
{ID: emit.InteropNameToID([]byte("System.Runtime.Notify")), {ID: interopnames.ToID([]byte("System.Runtime.Notify")),
Func: runtimeNotify, Price: 1000000, RequiredFlags: smartcontract.AllowNotify}, Func: runtimeNotify, Price: 1000000, RequiredFlags: smartcontract.AllowNotify},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Create")), {ID: interopnames.ToID([]byte("System.Enumerator.Create")),
Func: EnumeratorCreate, Price: 400}, Func: EnumeratorCreate, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Next")), {ID: interopnames.ToID([]byte("System.Enumerator.Next")),
Func: EnumeratorNext, Price: 1000000}, Func: EnumeratorNext, Price: 1000000},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Concat")), {ID: interopnames.ToID([]byte("System.Enumerator.Concat")),
Func: EnumeratorConcat, Price: 400}, Func: EnumeratorConcat, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Value")), {ID: interopnames.ToID([]byte("System.Enumerator.Value")),
Func: EnumeratorValue, Price: 400}, Func: EnumeratorValue, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Create")), {ID: interopnames.ToID([]byte("System.Iterator.Create")),
Func: IteratorCreate, Price: 400}, Func: IteratorCreate, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Concat")), {ID: interopnames.ToID([]byte("System.Iterator.Concat")),
Func: IteratorConcat, Price: 400}, Func: IteratorConcat, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Key")), {ID: interopnames.ToID([]byte("System.Iterator.Key")),
Func: IteratorKey, Price: 400}, Func: IteratorKey, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Keys")), {ID: interopnames.ToID([]byte("System.Iterator.Keys")),
Func: IteratorKeys, Price: 400}, Func: IteratorKeys, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Values")), {ID: interopnames.ToID([]byte("System.Iterator.Values")),
Func: IteratorValues, Price: 400}, Func: IteratorValues, Price: 400},
} }

View file

@ -11,6 +11,7 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/internal/random" "github.com/nspcc-dev/neo-go/pkg/internal/random"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -23,7 +24,7 @@ import (
) )
func fooInteropHandler(v *VM, id uint32) error { func fooInteropHandler(v *VM, id uint32) error {
if id == emit.InteropNameToID([]byte("foo")) { if id == interopnames.ToID([]byte("foo")) {
if !v.AddGas(1) { if !v.AddGas(1) {
return errors.New("invalid gas amount") return errors.New("invalid gas amount")
} }