core: add System.Binary.Base64Encode(Decode) interops

Part of #1055
This commit is contained in:
Anna Shaleva 2020-07-15 11:49:24 +03:00
parent f31ce9289d
commit 74d2f437f4
5 changed files with 72 additions and 2 deletions

View file

@ -9,6 +9,8 @@ type Syscall struct {
// All lists are sorted, keep 'em this way, please.
var syscalls = map[string]map[string]Syscall{
"binary": {
"Base64Decode": {"System.Binary.Base64Decode", false},
"Base64Encode": {"System.Binary.Base64Encode", false},
"Deserialize": {"System.Binary.Deserialize", false},
"Serialize": {"System.Binary.Serialize", false},
},

View file

@ -2,6 +2,7 @@ package core
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"sort"
@ -192,3 +193,22 @@ func runtimeSerialize(_ *interop.Context, v *vm.VM) error {
func runtimeDeserialize(_ *interop.Context, v *vm.VM) error {
return vm.RuntimeDeserialize(v)
}
// runtimeEncode encodes top stack item into a base64 string.
func runtimeEncode(_ *interop.Context, v *vm.VM) error {
src := v.Estack().Pop().Bytes()
result := base64.StdEncoding.EncodeToString(src)
v.Estack().PushVal([]byte(result))
return nil
}
// runtimeDecode decodes top stack item from base64 string to byte array.
func runtimeDecode(_ *interop.Context, v *vm.VM) error {
src := string(v.Estack().Pop().Bytes())
result, err := base64.StdEncoding.DecodeString(src)
if err != nil {
return err
}
v.Estack().PushVal(result)
return nil
}

View file

@ -1,6 +1,7 @@
package core
import (
"encoding/base64"
"fmt"
"testing"
@ -214,6 +215,39 @@ func TestECDSAVerify(t *testing.T) {
})
}
func TestRuntimeEncode(t *testing.T) {
str := []byte("my pretty string")
v, ic, bc := createVM(t)
defer bc.Close()
v.Estack().PushVal(str)
require.NoError(t, runtimeEncode(ic, v))
expected := []byte(base64.StdEncoding.EncodeToString(str))
actual := v.Estack().Pop().Bytes()
require.Equal(t, expected, actual)
}
func TestRuntimeDecode(t *testing.T) {
expected := []byte("my pretty string")
str := base64.StdEncoding.EncodeToString(expected)
v, ic, bc := createVM(t)
defer bc.Close()
t.Run("positive", func(t *testing.T) {
v.Estack().PushVal(str)
require.NoError(t, runtimeDecode(ic, v))
actual := v.Estack().Pop().Bytes()
require.Equal(t, expected, actual)
})
t.Run("error", func(t *testing.T) {
v.Estack().PushVal(str + "%")
require.Error(t, runtimeDecode(ic, v))
})
}
// Helper functions to create VM, InteropContext, TX, Account, Contract.
func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {

View file

@ -69,6 +69,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.Base64Decode", Func: runtimeDecode, Price: 100000},
{Name: "System.Binary.Base64Encode", Func: runtimeEncode, Price: 100000},
{Name: "System.Binary.Deserialize", Func: runtimeDeserialize, Price: 500000},
{Name: "System.Binary.Serialize", Func: runtimeSerialize, Price: 100000},
{Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 2500000,

View file

@ -16,3 +16,15 @@ func Serialize(item interface{}) []byte {
func Deserialize(b []byte) interface{} {
return nil
}
// Base64Encode encodes given byte slice into a base64 string and returns byte
// representation of this string. It uses `System.Binary.Base64Encode` interop.
func Base64Encode(b []byte) []byte {
return nil
}
// Base64Decode decodes given base64 string represented as a byte slice into
// byte slice. It uses `System.Binary.Base64Decode` interop.
func Base64Decode(b []byte) []byte {
return nil
}