From 4d2ad4b9e2c6a1cad074d68c5ec35d39f44adfea Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Thu, 4 Mar 2021 13:52:22 +0300 Subject: [PATCH] core: remove System.Json.[Serialize, Deserialize] interops And move their tests to native StdLib. --- pkg/compiler/syscall_test.go | 2 - pkg/core/interop/interopnames/names.go | 4 -- pkg/core/interop/json/json.go | 28 ------------ pkg/core/interop/json/json_test.go | 63 -------------------------- pkg/core/interops.go | 3 -- pkg/core/native/std_test.go | 44 ++++++++++++++++++ pkg/interop/json/json.go | 30 ------------ 7 files changed, 44 insertions(+), 130 deletions(-) delete mode 100644 pkg/core/interop/json/json.go delete mode 100644 pkg/core/interop/json/json_test.go delete mode 100644 pkg/interop/json/json.go diff --git a/pkg/compiler/syscall_test.go b/pkg/compiler/syscall_test.go index 01f91038e..d190f7664 100644 --- a/pkg/compiler/syscall_test.go +++ b/pkg/compiler/syscall_test.go @@ -75,8 +75,6 @@ func TestSyscallExecution(t *testing.T) { "iterator.Create": {interopnames.SystemIteratorCreate, []string{pubs}, false}, "iterator.Next": {interopnames.SystemIteratorNext, []string{"iterator.Iterator{}"}, false}, "iterator.Value": {interopnames.SystemIteratorValue, []string{"iterator.Iterator{}"}, false}, - "json.FromJSON": {interopnames.SystemJSONDeserialize, []string{b}, false}, - "json.ToJSON": {interopnames.SystemJSONSerialize, []string{b}, false}, "runtime.CheckWitness": {interopnames.SystemRuntimeCheckWitness, []string{b}, false}, "runtime.GasLeft": {interopnames.SystemRuntimeGasLeft, nil, false}, "runtime.GetCallingScriptHash": {interopnames.SystemRuntimeGetCallingScriptHash, nil, false}, diff --git a/pkg/core/interop/interopnames/names.go b/pkg/core/interop/interopnames/names.go index 47dd802f9..ab915a976 100644 --- a/pkg/core/interop/interopnames/names.go +++ b/pkg/core/interop/interopnames/names.go @@ -23,8 +23,6 @@ const ( SystemIteratorCreate = "System.Iterator.Create" SystemIteratorNext = "System.Iterator.Next" SystemIteratorValue = "System.Iterator.Value" - SystemJSONDeserialize = "System.Json.Deserialize" - SystemJSONSerialize = "System.Json.Serialize" SystemRuntimeCheckWitness = "System.Runtime.CheckWitness" SystemRuntimeGasLeft = "System.Runtime.GasLeft" SystemRuntimeGetCallingScriptHash = "System.Runtime.GetCallingScriptHash" @@ -73,8 +71,6 @@ var names = []string{ SystemIteratorCreate, SystemIteratorNext, SystemIteratorValue, - SystemJSONDeserialize, - SystemJSONSerialize, SystemRuntimeCheckWitness, SystemRuntimeGasLeft, SystemRuntimeGetCallingScriptHash, diff --git a/pkg/core/interop/json/json.go b/pkg/core/interop/json/json.go deleted file mode 100644 index 5be269939..000000000 --- a/pkg/core/interop/json/json.go +++ /dev/null @@ -1,28 +0,0 @@ -package json - -import ( - "github.com/nspcc-dev/neo-go/pkg/core/interop" - "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" -) - -// Serialize handles System.JSON.Serialize syscall. -func Serialize(ic *interop.Context) error { - item := ic.VM.Estack().Pop().Item() - data, err := stackitem.ToJSON(item) - if err != nil { - return err - } - ic.VM.Estack().PushVal(data) - return nil -} - -// Deserialize handles System.JSON.Deserialize syscall. -func Deserialize(ic *interop.Context) error { - data := ic.VM.Estack().Pop().Bytes() - item, err := stackitem.FromJSON(data) - if err != nil { - return err - } - ic.VM.Estack().PushVal(item) - return nil -} diff --git a/pkg/core/interop/json/json_test.go b/pkg/core/interop/json/json_test.go deleted file mode 100644 index 056a29c76..000000000 --- a/pkg/core/interop/json/json_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package json - -import ( - "encoding/binary" - "testing" - - "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/opcode" - "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" - "github.com/stretchr/testify/require" -) - -var ( - serializeID = interopnames.ToID([]byte(interopnames.SystemJSONSerialize)) - deserializeID = interopnames.ToID([]byte(interopnames.SystemJSONDeserialize)) -) - -var jsonInterops = []interop.Function{ - {ID: serializeID, Func: Serialize}, - {ID: deserializeID, Func: Deserialize}, -} - -func init() { - interop.Sort(jsonInterops) -} - -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) { - ic := &interop.Context{} - ic.Functions = append(ic.Functions, jsonInterops) - v := ic.SpawnVM() - 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)) - }) -} diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 6044af302..0952efc7c 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -15,7 +15,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "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/json" "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/smartcontract/callflag" @@ -50,8 +49,6 @@ var systemInterops = []interop.Function{ {Name: interopnames.SystemIteratorCreate, Func: iterator.Create, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemIteratorNext, Func: iterator.Next, Price: 1 << 15, ParamCount: 1}, {Name: interopnames.SystemIteratorValue, Func: iterator.Value, Price: 1 << 4, ParamCount: 1}, - {Name: interopnames.SystemJSONDeserialize, Func: json.Deserialize, Price: 1 << 14, ParamCount: 1}, - {Name: interopnames.SystemJSONSerialize, Func: json.Serialize, Price: 1 << 12, ParamCount: 1}, {Name: interopnames.SystemRuntimeCheckWitness, Func: runtime.CheckWitness, Price: 1 << 10, RequiredFlags: callflag.NoneFlag, ParamCount: 1}, {Name: interopnames.SystemRuntimeGasLeft, Func: runtime.GasLeft, Price: 1 << 4}, diff --git a/pkg/core/native/std_test.go b/pkg/core/native/std_test.go index ee1baaca8..afbe7460f 100644 --- a/pkg/core/native/std_test.go +++ b/pkg/core/native/std_test.go @@ -94,3 +94,47 @@ func TestStdLibItoaAtoi(t *testing.T) { } }) } + +func TestStdLibJSON(t *testing.T) { + s := newStd() + ic := &interop.Context{VM: vm.New()} + var actual stackitem.Item + + t.Run("JSONSerialize", func(t *testing.T) { + t.Run("Good", func(t *testing.T) { + require.NotPanics(t, func() { + actual = s.jsonSerialize(ic, []stackitem.Item{stackitem.Make(42)}) + }) + + require.Equal(t, stackitem.Make([]byte("42")), actual) + }) + + 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)), + }) + require.Panics(t, func() { + _ = s.jsonSerialize(ic, []stackitem.Item{arr}) + }) + }) + }) + + t.Run("JSONDeserialize", func(t *testing.T) { + t.Run("Good", func(t *testing.T) { + require.NotPanics(t, func() { + actual = s.jsonDeserialize(ic, []stackitem.Item{stackitem.Make("42")}) + }) + + require.Equal(t, stackitem.Make(42), actual) + }) + t.Run("Bad", func(t *testing.T) { + require.Panics(t, func() { + _ = s.jsonDeserialize(ic, []stackitem.Item{stackitem.Make("{]")}) + }) + require.Panics(t, func() { + _ = s.jsonDeserialize(ic, []stackitem.Item{stackitem.NewInterop(nil)}) + }) + }) + }) +} diff --git a/pkg/interop/json/json.go b/pkg/interop/json/json.go deleted file mode 100644 index 05eede334..000000000 --- a/pkg/interop/json/json.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Package json provides various JSON serialization/deserialization routines. -*/ -package json - -import "github.com/nspcc-dev/neo-go/pkg/interop/neogointernal" - -// ToJSON serializes value to json. It uses `System.Json.Serialize` syscall. -// Serialization format is the following: -// []byte -> base64 string -// bool -> json boolean -// nil -> Null -// string -> base64 encoded sequence of underlying bytes -// (u)int* -> integer, only value in -2^53..2^53 are allowed -// []interface{} -> json array -// map[type1]type2 -> json object with string keys marshaled as strings (not base64). -func ToJSON(item interface{}) []byte { - return neogointernal.Syscall1("System.Json.Serialize", item).([]byte) -} - -// FromJSON deserializes value from json. It uses `System.Json.Deserialize` syscall. -// It performs deserialization as follows: -// strings -> []byte (string) from base64 -// integers -> (u)int* types -// null -> interface{}(nil) -// arrays -> []interface{} -// maps -> map[string]interface{} -func FromJSON(data []byte) interface{} { - return neogointernal.Syscall1("System.Json.Deserialize", data).(interface{}) -}