From 62da970bbba40c830b2ad7d2d7283e78951fddba Mon Sep 17 00:00:00 2001 From: noot <36753753+noot@users.noreply.github.com> Date: Thu, 11 Mar 2021 20:02:44 -0500 Subject: [PATCH] update sign_ functs to return fixed size byte optional (#1451) --- lib/common/optional/types.go | 72 ++++++++++++++++++++++++++++++ lib/runtime/life/instance.go | 4 +- lib/runtime/wasmer/imports.go | 23 ++++++++-- lib/runtime/wasmer/imports_test.go | 4 +- 4 files changed, 96 insertions(+), 7 deletions(-) diff --git a/lib/common/optional/types.go b/lib/common/optional/types.go index dd644a6e2d..b06ac7cdf1 100644 --- a/lib/common/optional/types.go +++ b/lib/common/optional/types.go @@ -20,6 +20,7 @@ import ( "encoding/binary" "fmt" "io" + "io/ioutil" "math/big" "github.com/ChainSafe/gossamer/lib/common" @@ -165,6 +166,77 @@ func (x *Bytes) Decode(r io.Reader) (*Bytes, error) { return x, nil } +// FixedSizeBytes represents an optional FixedSizeBytes type. It does not length-encode the value when encoding. +type FixedSizeBytes struct { + exists bool + value []byte +} + +// NewFixedSizeBytes returns a new optional.FixedSizeBytes +func NewFixedSizeBytes(exists bool, value []byte) *FixedSizeBytes { + return &FixedSizeBytes{ + exists: exists, + value: value, + } +} + +// Exists returns true if the value is Some, false if it is None. +func (x *FixedSizeBytes) Exists() bool { + return x.exists +} + +// Value returns the []byte value. It returns nil if it is None. +func (x *FixedSizeBytes) Value() []byte { + return x.value +} + +// String returns the value as a string. +func (x *FixedSizeBytes) String() string { + if !x.exists { + return none + } + return fmt.Sprintf("%x", x.value) +} + +// Set sets the exists and value fields. +func (x *FixedSizeBytes) Set(exists bool, value []byte) { + x.exists = exists + x.value = value +} + +// Encode returns the SCALE encoded optional +func (x *FixedSizeBytes) Encode() ([]byte, error) { + if x == nil || !x.exists { + return []byte{0}, nil + } + + return append([]byte{1}, x.value...), nil +} + +// Decode return an optional FixedSizeBytes from scale encoded data +func (x *FixedSizeBytes) Decode(r io.Reader) (*FixedSizeBytes, error) { + exists, err := common.ReadByte(r) + if err != nil { + return nil, err + } + + if exists > 1 { + return nil, ErrInvalidOptional + } + + x.exists = (exists != 0) + + if x.exists { + value, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + x.value = value + } + + return x, nil +} + // Boolean represents an optional bool type. type Boolean struct { exists bool diff --git a/lib/runtime/life/instance.go b/lib/runtime/life/instance.go index 89edf34ad0..9786f176e2 100644 --- a/lib/runtime/life/instance.go +++ b/lib/runtime/life/instance.go @@ -110,8 +110,8 @@ func NewInstance(code []byte, cfg *Config) (runtime.Instance, error) { } ctx = runtimeCtx - inst.version, err = inst.Version() - return inst, err + inst.version, _ = inst.Version() + return inst, nil } // Memory is a thin wrapper around life's memory to support diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index 7284c26eb6..e1c00f1691 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -331,7 +331,7 @@ func ext_crypto_ed25519_sign_version_1(context unsafe.Pointer, keyTypeID C.int32 logger.Error("[ext_crypto_ed25519_sign_version_1] could not sign message") } - ret, err = toWasmMemoryOptional(instanceContext, sig) + ret, err = toWasmMemoryFixedSizeOptional(instanceContext, sig) if err != nil { logger.Error("[ext_crypto_ed25519_sign_version_1] failed to allocate memory", err) return 0 @@ -494,7 +494,7 @@ func ext_crypto_sr25519_generate_version_1(context unsafe.Pointer, keyTypeID C.i ks, err := runtimeCtx.Keystore.GetKeystore(id) if err != nil { - logger.Warn("[ext_crypto_ed25519_sign_version_1]", "name", id, "error", err) + logger.Warn("[ext_crypto_sr25519_generate_version_1]", "name", id, "error", err) return 0 } @@ -593,7 +593,7 @@ func ext_crypto_sr25519_sign_version_1(context unsafe.Pointer, keyTypeID, key C. return C.int64_t(emptyRet) } - ret, err = toWasmMemoryOptional(instanceContext, sig) + ret, err = toWasmMemoryFixedSizeOptional(instanceContext, sig) if err != nil { logger.Error("[ext_crypto_sr25519_sign_version_1] failed to allocate memory", "error", err) return C.int64_t(emptyRet) @@ -1950,6 +1950,23 @@ func toWasmMemoryOptionalUint32(context wasm.InstanceContext, data *uint32) (int return toWasmMemory(context, enc) } +// Wraps slice in optional.FixedSizeBytes and copies result to wasm memory. Returns resulting 64bit span descriptor +func toWasmMemoryFixedSizeOptional(context wasm.InstanceContext, data []byte) (int64, error) { + var opt *optional.FixedSizeBytes + if data == nil { + opt = optional.NewFixedSizeBytes(false, nil) + } else { + opt = optional.NewFixedSizeBytes(true, data) + } + + enc, err := opt.Encode() + if err != nil { + return 0, err + } + + return toWasmMemory(context, enc) +} + // ImportsNodeRuntime returns the imports for the v0.8 runtime func ImportsNodeRuntime() (*wasm.Imports, error) { //nolint var err error diff --git a/lib/runtime/wasmer/imports_test.go b/lib/runtime/wasmer/imports_test.go index 774a97cb08..516171413c 100644 --- a/lib/runtime/wasmer/imports_test.go +++ b/lib/runtime/wasmer/imports_test.go @@ -513,7 +513,7 @@ func Test_ext_crypto_ed25519_sign_version_1(t *testing.T) { buf := &bytes.Buffer{} buf.Write(out.([]byte)) - value, err := new(optional.Bytes).Decode(buf) + value, err := new(optional.FixedSizeBytes).Decode(buf) require.NoError(t, err) ok, err := kp.Public().Verify(msgData, value.Value()) @@ -732,7 +732,7 @@ func Test_ext_crypto_sr25519_sign_version_1(t *testing.T) { buf := &bytes.Buffer{} buf.Write(out.([]byte)) - value, err := new(optional.Bytes).Decode(buf) + value, err := new(optional.FixedSizeBytes).Decode(buf) require.NoError(t, err) require.True(t, value.Exists())