forked from TrueCloudLab/neoneo-go
core: implement System.Json.* interops
This commit is contained in:
parent
d836233352
commit
6339efac11
3 changed files with 100 additions and 0 deletions
29
pkg/core/interop/json/json.go
Normal file
29
pkg/core/interop/json/json.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Serialize handles System.JSON.Serialize syscall.
|
||||||
|
func Serialize(_ *interop.Context, v *vm.VM) error {
|
||||||
|
item := v.Estack().Pop().Item()
|
||||||
|
data, err := stackitem.ToJSON(item)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Estack().PushVal(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize handles System.JSON.Deserialize syscall.
|
||||||
|
func Deserialize(_ *interop.Context, v *vm.VM) error {
|
||||||
|
data := v.Estack().Pop().Bytes()
|
||||||
|
item, err := stackitem.FromJSON(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Estack().PushVal(item)
|
||||||
|
return nil
|
||||||
|
}
|
68
pkg/core/interop/json/json_test.go
Normal file
68
pkg/core/interop/json/json_test.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"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/opcode"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
serializeID = emit.InteropNameToID([]byte("System.Json.Serialize"))
|
||||||
|
deserializeID = emit.InteropNameToID([]byte("System.Json.Deserialize"))
|
||||||
|
)
|
||||||
|
|
||||||
|
func getInterop(id uint32) *vm.InteropFuncPrice {
|
||||||
|
switch id {
|
||||||
|
case serializeID:
|
||||||
|
return &vm.InteropFuncPrice{
|
||||||
|
Func: func(v *vm.VM) error { return Serialize(nil, v) },
|
||||||
|
}
|
||||||
|
case deserializeID:
|
||||||
|
return &vm.InteropFuncPrice{
|
||||||
|
Func: func(v *vm.VM) error { return Deserialize(nil, v) },
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTestFunc(id uint32, arg interface{}, result interface{}) func(t *testing.T) {
|
||||||
|
prog := make([]byte, 5)
|
||||||
|
prog[0] = byte(opcode.SYSCALL)
|
||||||
|
binary.LittleEndian.PutUint32(prog[1:], id)
|
||||||
|
|
||||||
|
return func(t *testing.T) {
|
||||||
|
v := vm.New()
|
||||||
|
v.RegisterInteropGetter(getInterop)
|
||||||
|
v.LoadScript(prog)
|
||||||
|
v.Estack().PushVal(arg)
|
||||||
|
if result == nil {
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, v.Run())
|
||||||
|
require.Equal(t, stackitem.Make(result), v.Estack().Pop().Item())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSerialize(t *testing.T) {
|
||||||
|
t.Run("Serialize", func(t *testing.T) {
|
||||||
|
t.Run("Good", getTestFunc(serializeID, 42, []byte("42")))
|
||||||
|
t.Run("Bad", func(t *testing.T) {
|
||||||
|
arr := stackitem.NewArray([]stackitem.Item{
|
||||||
|
stackitem.NewByteArray(make([]byte, stackitem.MaxSize/2)),
|
||||||
|
stackitem.NewByteArray(make([]byte, stackitem.MaxSize/2)),
|
||||||
|
})
|
||||||
|
getTestFunc(serializeID, arr, nil)(t)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("Deserialize", func(t *testing.T) {
|
||||||
|
t.Run("Good", getTestFunc(deserializeID, []byte("42"), 42))
|
||||||
|
t.Run("Bad", getTestFunc(deserializeID, []byte("{]"), nil))
|
||||||
|
})
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"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/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/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"
|
||||||
|
@ -105,6 +106,8 @@ var systemInterops = []interop.Function{
|
||||||
{Name: "System.Iterator.Key", Func: iterator.Key, Price: 400},
|
{Name: "System.Iterator.Key", Func: iterator.Key, Price: 400},
|
||||||
{Name: "System.Iterator.Keys", Func: iterator.Keys, Price: 400},
|
{Name: "System.Iterator.Keys", Func: iterator.Keys, Price: 400},
|
||||||
{Name: "System.Iterator.Values", Func: iterator.Values, Price: 400},
|
{Name: "System.Iterator.Values", Func: iterator.Values, Price: 400},
|
||||||
|
{Name: "System.Json.Deserialize", Func: json.Deserialize, Price: 500000},
|
||||||
|
{Name: "System.Json.Serialize", Func: json.Serialize, Price: 100000},
|
||||||
{Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200, RequiredFlags: smartcontract.AllowStates},
|
{Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200, RequiredFlags: smartcontract.AllowStates},
|
||||||
{Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1,
|
{Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1,
|
||||||
AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowStates},
|
AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowStates},
|
||||||
|
|
Loading…
Reference in a new issue