Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(lib/runtime/wasmer): implement ext_default_child_storage_storage…
…_kill_version_3 (#1878)
  • Loading branch information
edwardmack committed Oct 25, 2021
1 parent b7da83b commit a719a60
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 8 deletions.
64 changes: 56 additions & 8 deletions lib/runtime/wasmer/imports.go
Expand Up @@ -1142,19 +1142,67 @@ func ext_default_child_storage_storage_kill_version_2(context unsafe.Pointer, ch
return 0
}

//export ext_default_child_storage_storage_kill_version_3
func ext_default_child_storage_storage_kill_version_3(context unsafe.Pointer, childStorageKeySpan, _ C.int64_t) C.int64_t {
logger.Debug("[ext_default_child_storage_storage_kill_version_3] executing...")
logger.Warn("[ext_default_child_storage_storage_kill_version_3] somewhat unimplemented")
// TODO: need to use `limit` parameter (#1793)
type noneRemain uint32
type someRemain uint32

func (noneRemain) Index() uint {
return 0
}
func (someRemain) Index() uint {
return 1
}

//export ext_default_child_storage_storage_kill_version_3
func ext_default_child_storage_storage_kill_version_3(context unsafe.Pointer, childStorageKeySpan, lim C.int64_t) C.int64_t {
logger.Debug("executing...")
instanceContext := wasm.IntoInstanceContext(context)
ctx := instanceContext.Data().(*runtime.Context)
storage := ctx.Storage

childStorageKey := asMemorySlice(instanceContext, childStorageKeySpan)
storage.DeleteChild(childStorageKey)
return 0

limitBytes := asMemorySlice(instanceContext, lim)
buf := &bytes.Buffer{}
buf.Write(limitBytes)

limit, err := optional.NewBytes(true, nil).Decode(buf)
if err != nil {
logger.Warn("cannot generate limit", "error", err)
}

deleted, all, err := storage.DeleteChildLimit(childStorageKey, limit)
if err != nil {
logger.Warn("cannot get child storage", "error", err)
return C.int64_t(0)
}

vdt, err := scale.NewVaryingDataType(noneRemain(0), someRemain(0))
if err != nil {
logger.Warn("cannot create new varying data type", "error", err)
}

if all {
err = vdt.Set(noneRemain(deleted))
} else {
err = vdt.Set(someRemain(deleted))
}
if err != nil {
logger.Warn("cannot set varying data type", "error", err)
return C.int64_t(0)
}

encoded, err := scale.Marshal(vdt)
if err != nil {
logger.Warn("problem marshaling varying data type", "error", err)
return C.int64_t(0)
}

out, err := toWasmMemoryOptional(instanceContext, encoded)
if err != nil {
logger.Warn("failed to allocate", "error", err)
return 0
}

return C.int64_t(out)
}

//export ext_allocator_free_version_1
Expand Down
48 changes: 48 additions & 0 deletions lib/runtime/wasmer/imports_test.go
Expand Up @@ -1226,6 +1226,54 @@ func Test_ext_default_child_storage_storage_kill_version_2_limit_none(t *testing
require.Nil(t, child)
}

func Test_ext_default_child_storage_storage_kill_version_3(t *testing.T) {
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)

tr := trie.NewEmptyTrie()
tr.Put([]byte(`key2`), []byte(`value2`))
tr.Put([]byte(`key1`), []byte(`value1`))
tr.Put([]byte(`key3`), []byte(`value3`))
err := inst.ctx.Storage.SetChild(testChildKey, tr)
require.NoError(t, err)

testLimitBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(testLimitBytes, uint32(2))
optLimit2 := optional.NewBytes(true, testLimitBytes)

testCases := []struct {
key []byte
limit *optional.Bytes
expected []byte
errMsg string
}{
{key: []byte(`fakekey`), limit: optLimit2, expected: []byte{0, 0, 0, 0, 0}, errMsg: "Failed to call the `rtm_ext_default_child_storage_storage_kill_version_3` exported function."},
{key: testChildKey, limit: optLimit2, expected: []byte{1, 2, 0, 0, 0}},
{key: testChildKey, limit: nil, expected: []byte{0, 1, 0, 0, 0}},
}

for _, test := range testCases {
encChildKey, err := scale.Marshal(test.key)
require.NoError(t, err)
encOptLimit, err := test.limit.Encode()
require.NoError(t, err)
res, err := inst.Exec("rtm_ext_default_child_storage_storage_kill_version_3", append(encChildKey, encOptLimit...))
if test.errMsg != "" {
require.Error(t, err)
require.EqualError(t, err, test.errMsg)
continue
}

require.NoError(t, err)

buf := &bytes.Buffer{}
buf.Write(res)

read, err := new(optional.Bytes).Decode(buf)
require.NoError(t, err)
require.Equal(t, test.expected, read.Value())
}
}

func Test_ext_storage_append_version_1(t *testing.T) {
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)

Expand Down

0 comments on commit a719a60

Please sign in to comment.