From 18066143bdf53d52090e54d288e650de88da7646 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 16 Jun 2020 10:56:06 +0300 Subject: [PATCH] core,vm: adjust binary (de-)serialization syscalls Related #1027. 1. Move System.Runtime.(De)serialize to System.Binary.* 2. Rename compiler stubs. 3. Adjust opcode prices. --- pkg/compiler/syscall.go | 4 ++-- pkg/core/interops.go | 4 ++-- pkg/interop/binary/binary.go | 18 ++++++++++++++++++ pkg/interop/runtime/runtime.go | 14 -------------- pkg/vm/interop.go | 12 ++++++------ pkg/vm/vm_test.go | 8 ++++---- 6 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 pkg/interop/binary/binary.go diff --git a/pkg/compiler/syscall.go b/pkg/compiler/syscall.go index 374dacfe7..0be51d22a 100644 --- a/pkg/compiler/syscall.go +++ b/pkg/compiler/syscall.go @@ -25,8 +25,8 @@ var syscalls = map[string]map[string]string{ "Notify": "System.Runtime.Notify", "Log": "System.Runtime.Log", "GetTime": "System.Runtime.GetTime", - "Serialize": "System.Runtime.Serialize", - "Deserialize": "System.Runtime.Deserialize", + "Serialize": "System.Binary.Serialize", + "Deserialize": "System.Binary.Deserialize", }, "blockchain": { "GetBlock": "System.Blockchain.GetBlock", diff --git a/pkg/core/interops.go b/pkg/core/interops.go index d11f4e329..12e7761cb 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -68,6 +68,8 @@ func getInteropFromSlice(ic *interop.Context, slice []interop.Function) func(uin // All lists are sorted, keep 'em this way, please. var systemInterops = []interop.Function{ + {Name: "System.Binary.Deserialize", Func: runtimeDeserialize, Price: 500000}, + {Name: "System.Binary.Serialize", Func: runtimeSerialize, Price: 100000}, {Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 250, AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowStates}, {Name: "System.Blockchain.GetContract", Func: bcGetContract, Price: 100, @@ -104,14 +106,12 @@ var systemInterops = []interop.Function{ {Name: "System.Iterator.Keys", Func: iterator.Keys, Price: 1}, {Name: "System.Iterator.Values", Func: iterator.Values, Price: 1}, {Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200, RequiredFlags: smartcontract.AllowStates}, - {Name: "System.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1}, {Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1, AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowStates}, {Name: "System.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 1}, {Name: "System.Runtime.Log", Func: runtimeLog, Price: 1, RequiredFlags: smartcontract.AllowNotify}, {Name: "System.Runtime.Notify", Func: runtimeNotify, Price: 1, RequiredFlags: smartcontract.AllowNotify}, {Name: "System.Runtime.Platform", Func: runtimePlatform, Price: 1}, - {Name: "System.Runtime.Serialize", Func: runtimeSerialize, Price: 1}, {Name: "System.Storage.Delete", Func: storageDelete, Price: StoragePrice, AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowModifyStates}, {Name: "System.Storage.Find", Func: storageFind, Price: 1000000, diff --git a/pkg/interop/binary/binary.go b/pkg/interop/binary/binary.go new file mode 100644 index 000000000..8a847e47c --- /dev/null +++ b/pkg/interop/binary/binary.go @@ -0,0 +1,18 @@ +/* +Package binary provides binary serialization routines. +*/ +package binary + +// Serialize serializes any given item into a byte slice. It works for all +// regular VM types (not ones from interop package) and allows to save them in +// storage or pass into Notify and then Deserialize them on the next run or in +// the external event receiver. It uses `System.Binary.Serialize` syscall. +func Serialize(item interface{}) []byte { + return nil +} + +// Deserialize unpacks previously serialized value from a byte slice, it's the +// opposite of Serialize. It uses `System.Binary.Deserialize` syscall. +func Deserialize(b []byte) interface{} { + return nil +} diff --git a/pkg/interop/runtime/runtime.go b/pkg/interop/runtime/runtime.go index ec7c52a8b..916fed6fb 100644 --- a/pkg/interop/runtime/runtime.go +++ b/pkg/interop/runtime/runtime.go @@ -54,17 +54,3 @@ func Application() byte { func Verification() byte { return 0x00 } - -// Serialize serializes any given item into a byte slice. It works for all -// regular VM types (not ones from interop package) and allows to save them in -// storage or pass into Notify and then Deserialize them on the next run or in -// the external event receiver. It uses `System.Runtime.Serialize` syscall. -func Serialize(item interface{}) []byte { - return nil -} - -// Deserialize unpacks previously serialized value from a byte slice, it's the -// opposite of Serialize. It uses `System.Runtime.Deserialize` syscall. -func Deserialize(b []byte) interface{} { - return nil -} diff --git a/pkg/vm/interop.go b/pkg/vm/interop.go index 2d8fb848c..70526f85a 100644 --- a/pkg/vm/interop.go +++ b/pkg/vm/interop.go @@ -35,14 +35,14 @@ type interopIDFuncPrice struct { type InteropGetterFunc func(uint32) *InteropFuncPrice var defaultVMInterops = []interopIDFuncPrice{ + {emit.InteropNameToID([]byte("System.Binary.Deserialize")), + InteropFuncPrice{Func: RuntimeDeserialize, Price: 500000}}, + {emit.InteropNameToID([]byte("System.Binary.Serialize")), + InteropFuncPrice{Func: RuntimeSerialize, Price: 100000}}, {emit.InteropNameToID([]byte("System.Runtime.Log")), InteropFuncPrice{Func: runtimeLog, Price: 1}}, {emit.InteropNameToID([]byte("System.Runtime.Notify")), InteropFuncPrice{Func: runtimeNotify, Price: 1}}, - {emit.InteropNameToID([]byte("System.Runtime.Serialize")), - InteropFuncPrice{Func: RuntimeSerialize, Price: 1}}, - {emit.InteropNameToID([]byte("System.Runtime.Deserialize")), - InteropFuncPrice{Func: RuntimeDeserialize, Price: 1}}, {emit.InteropNameToID([]byte("System.Enumerator.Create")), InteropFuncPrice{Func: EnumeratorCreate, Price: 1}}, {emit.InteropNameToID([]byte("System.Enumerator.Next")), @@ -87,7 +87,7 @@ func runtimeNotify(vm *VM) error { return nil } -// RuntimeSerialize handles syscalls System.Runtime.Serialize and System.Runtime.Serialize. +// RuntimeSerialize handles System.Binary.Serialize syscall. func RuntimeSerialize(vm *VM) error { item := vm.Estack().Pop() data, err := stackitem.SerializeItem(item.value) @@ -102,7 +102,7 @@ func RuntimeSerialize(vm *VM) error { return nil } -// RuntimeDeserialize handles syscalls System.Runtime.Deserialize and System.Runtime.Deserialize. +// RuntimeDeserialize handles System.Binary.Deserialize syscall. func RuntimeDeserialize(vm *VM) error { data := vm.Estack().Pop().Bytes() diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 17ba7c72d..185848275 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -656,8 +656,8 @@ func getSyscallProg(name string) (prog []byte) { } func getSerializeProg() (prog []byte) { - prog = append(prog, getSyscallProg("System.Runtime.Serialize")...) - prog = append(prog, getSyscallProg("System.Runtime.Deserialize")...) + prog = append(prog, getSyscallProg("System.Binary.Serialize")...) + prog = append(prog, getSyscallProg("System.Binary.Deserialize")...) prog = append(prog, byte(opcode.RET)) return @@ -762,7 +762,7 @@ func TestSerializeStruct(t *testing.T) { } func TestDeserializeUnknown(t *testing.T) { - prog := append(getSyscallProg("System.Runtime.Deserialize"), byte(opcode.RET)) + prog := append(getSyscallProg("System.Binary.Deserialize"), byte(opcode.RET)) data, err := stackitem.SerializeItem(stackitem.NewBigInteger(big.NewInt(123))) require.NoError(t, err) @@ -798,7 +798,7 @@ func TestSerializeMapCompat(t *testing.T) { emit.Bytes(buf.BinWriter, []byte("key")) emit.Bytes(buf.BinWriter, []byte("value")) emit.Opcode(buf.BinWriter, opcode.SETITEM) - emit.Syscall(buf.BinWriter, "System.Runtime.Serialize") + emit.Syscall(buf.BinWriter, "System.Binary.Serialize") require.NoError(t, buf.Err) vm := load(buf.Bytes())