Skip to content

Commit

Permalink
Added extra runtime imports
Browse files Browse the repository at this point in the history
This PR adds following import calls:
- ext_default_child_storage_clear_prefix_version_2
- ext_default_child_storage_root_version_2
- ext_offchain_index_clear_version_1
  • Loading branch information
kishansagathiya committed Jul 10, 2023
1 parent 0fa8662 commit f607013
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/runtime/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Storage interface {
ClearChildStorage(keyToChild, key []byte) error
NextKey([]byte) []byte
ClearPrefixInChild(keyToChild, prefix []byte) error
ClearPrefixInChildWithLimit(keyToChild, prefix []byte, limit uint32) error
GetChildNextKey(keyToChild, key []byte) ([]byte, error)
GetChild(keyToChild []byte) (*trie.Trie, error)
ClearPrefix(prefix []byte) (err error)
Expand Down
20 changes: 20 additions & 0 deletions lib/runtime/storage/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,26 @@ func (s *TrieState) ClearPrefixInChild(keyToChild, prefix []byte) error {
return nil
}

func (s *TrieState) ClearPrefixInChildWithLimit(keyToChild, prefix []byte, limit uint32) error {
s.lock.Lock()
defer s.lock.Unlock()

child, err := s.t.GetChild(keyToChild)
if err != nil {
return err
}
if child == nil {
return nil
}

_, _, err = child.ClearPrefixLimit(prefix, limit)
if err != nil {
return fmt.Errorf("clearing prefix in child trie located at key 0x%x: %w", keyToChild, err)
}

return nil
}

// GetChildNextKey returns the next lexicographical larger key from child storage. If it does not exist, it returns nil.
func (s *TrieState) GetChildNextKey(keyToChild, key []byte) ([]byte, error) {
s.lock.RLock()
Expand Down
55 changes: 55 additions & 0 deletions lib/runtime/wasmer/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ package wasmer
// extern int64_t ext_default_child_storage_next_key_version_1(void *context, int64_t a, int64_t b);
// extern int64_t ext_default_child_storage_read_version_1(void *context, int64_t a, int64_t b, int64_t c, int32_t d);
// extern int64_t ext_default_child_storage_root_version_1(void *context, int64_t a);
// extern int64_t ext_default_child_storage_root_version_2(void *context, int64_t a, int32_t b);
// extern void ext_default_child_storage_set_version_1(void *context, int64_t a, int64_t b, int64_t c);
// extern void ext_default_child_storage_storage_kill_version_1(void *context, int64_t a);
// extern int32_t ext_default_child_storage_storage_kill_version_2(void *context, int64_t a, int64_t b);
// extern int64_t ext_default_child_storage_storage_kill_version_3(void *context, int64_t a, int64_t b);
// extern void ext_default_child_storage_clear_prefix_version_1(void *context, int64_t a, int64_t b);
// extern int64_t ext_default_child_storage_clear_prefix_version_2(void *context, int64_t a, int64_t b, int64_t c);
// extern int32_t ext_default_child_storage_exists_version_1(void *context, int64_t a, int64_t b);
//
// extern void ext_allocator_free_version_1(void *context, int32_t a);
Expand All @@ -66,6 +68,7 @@ package wasmer
// extern int32_t ext_hashing_twox_128_version_1(void *context, int64_t a);
// extern int32_t ext_hashing_twox_64_version_1(void *context, int64_t a);
//
// extern void ext_offchain_index_clear_version_1(void *context, int64_t a);
// extern void ext_offchain_index_set_version_1(void *context, int64_t a, int64_t b);
// extern int32_t ext_offchain_is_validator_version_1(void *context);
// extern void ext_offchain_local_storage_clear_version_1(void *context, int32_t a, int64_t b);
Expand Down Expand Up @@ -1060,6 +1063,32 @@ func ext_default_child_storage_clear_prefix_version_1(context unsafe.Pointer, ch
}
}

//export ext_default_child_storage_clear_prefix_version_2
func ext_default_child_storage_clear_prefix_version_2(context unsafe.Pointer, childStorageKey, prefixSpan, limitSpan C.int64_t) C.int64_t {
logger.Debug("executing...")

instanceContext := wasm.IntoInstanceContext(context)
ctx := instanceContext.Data().(*runtime.Context)
storage := ctx.Storage

keyToChild := asMemorySlice(instanceContext, childStorageKey)
prefix := asMemorySlice(instanceContext, prefixSpan)

var limit *uint32
err := scale.Unmarshal(asMemorySlice(instanceContext, limitSpan), limit)
if err != nil {
logger.Errorf("failed to decode limit: %s", err)
}

err = storage.ClearPrefixInChildWithLimit(keyToChild, prefix, *limit)
if err != nil {
logger.Errorf("failed to clear prefix in child with limit: %s", err)
}

// TODO: Should this always be 0 or could this be something else as well?
return C.int64_t(0)
}

//export ext_default_child_storage_exists_version_1
func ext_default_child_storage_exists_version_1(context unsafe.Pointer,
childStorageKey, key C.int64_t) C.int32_t {
Expand Down Expand Up @@ -1158,6 +1187,13 @@ func ext_default_child_storage_root_version_1(context unsafe.Pointer,
return C.int64_t(root)
}

//export ext_default_child_storage_root_version_2
func ext_default_child_storage_root_version_2(context unsafe.Pointer,
childStorageKey C.int64_t, stateVersion C.int32_t) (ptrSize C.int64_t) {
// TODO: Implement this after we have storage trie version 1 implemented #2418
return ext_default_child_storage_root_version_1(context, childStorageKey)
}

//export ext_default_child_storage_set_version_1
func ext_default_child_storage_set_version_1(context unsafe.Pointer,
childStorageKeySpan, keySpan, valueSpan C.int64_t) {
Expand Down Expand Up @@ -1503,6 +1539,22 @@ func ext_offchain_index_set_version_1(context unsafe.Pointer, keySpan, valueSpan
}
}

//export ext_offchain_index_clear_version_1
func ext_offchain_index_clear_version_1(context unsafe.Pointer, keySpan C.int64_t) {
// Remove a key and its associated value from the Offchain DB.
// https://github.com/paritytech/substrate/blob/4d608f9c42e8d70d835a748fa929e59a99497e90/primitives/io/src/lib.rs#L1213
logger.Trace("executing...")

instanceContext := wasm.IntoInstanceContext(context)
runtimeCtx := instanceContext.Data().(*runtime.Context)

storageKey := asMemorySlice(instanceContext, keySpan)
err := runtimeCtx.NodeStorage.BaseDB.Del(storageKey)
if err != nil {
logger.Errorf("failed to set value in raw storage: %s", err)
}
}

//export ext_offchain_local_storage_clear_version_1
func ext_offchain_local_storage_clear_version_1(context unsafe.Pointer, kind C.int32_t, key C.int64_t) {
logger.Trace("executing...")
Expand Down Expand Up @@ -2116,12 +2168,14 @@ func importsNodeRuntime() (imports *wasm.Imports, err error) {
{"ext_crypto_sr25519_verify_version_2", ext_crypto_sr25519_verify_version_2, C.ext_crypto_sr25519_verify_version_2},
{"ext_crypto_start_batch_verify_version_1", ext_crypto_start_batch_verify_version_1, C.ext_crypto_start_batch_verify_version_1},
{"ext_default_child_storage_clear_prefix_version_1", ext_default_child_storage_clear_prefix_version_1, C.ext_default_child_storage_clear_prefix_version_1},
{"ext_default_child_storage_clear_prefix_version_2", ext_default_child_storage_clear_prefix_version_2, C.ext_default_child_storage_clear_prefix_version_2},
{"ext_default_child_storage_clear_version_1", ext_default_child_storage_clear_version_1, C.ext_default_child_storage_clear_version_1},
{"ext_default_child_storage_exists_version_1", ext_default_child_storage_exists_version_1, C.ext_default_child_storage_exists_version_1},
{"ext_default_child_storage_get_version_1", ext_default_child_storage_get_version_1, C.ext_default_child_storage_get_version_1},
{"ext_default_child_storage_next_key_version_1", ext_default_child_storage_next_key_version_1, C.ext_default_child_storage_next_key_version_1},
{"ext_default_child_storage_read_version_1", ext_default_child_storage_read_version_1, C.ext_default_child_storage_read_version_1},
{"ext_default_child_storage_root_version_1", ext_default_child_storage_root_version_1, C.ext_default_child_storage_root_version_1},
{"ext_default_child_storage_root_version_2", ext_default_child_storage_root_version_2, C.ext_default_child_storage_root_version_2},
{"ext_default_child_storage_set_version_1", ext_default_child_storage_set_version_1, C.ext_default_child_storage_set_version_1},
{"ext_default_child_storage_storage_kill_version_1", ext_default_child_storage_storage_kill_version_1, C.ext_default_child_storage_storage_kill_version_1},
{"ext_default_child_storage_storage_kill_version_2", ext_default_child_storage_storage_kill_version_2, C.ext_default_child_storage_storage_kill_version_2},
Expand All @@ -2139,6 +2193,7 @@ func importsNodeRuntime() (imports *wasm.Imports, err error) {
{"ext_misc_print_num_version_1", ext_misc_print_num_version_1, C.ext_misc_print_num_version_1},
{"ext_misc_print_utf8_version_1", ext_misc_print_utf8_version_1, C.ext_misc_print_utf8_version_1},
{"ext_misc_runtime_version_version_1", ext_misc_runtime_version_version_1, C.ext_misc_runtime_version_version_1},
{"ext_offchain_index_clear_version_1", ext_offchain_index_clear_version_1, C.ext_offchain_index_clear_version_1},
{"ext_offchain_http_request_add_header_version_1", ext_offchain_http_request_add_header_version_1, C.ext_offchain_http_request_add_header_version_1},
{"ext_offchain_http_request_start_version_1", ext_offchain_http_request_start_version_1, C.ext_offchain_http_request_start_version_1},
{"ext_offchain_index_set_version_1", ext_offchain_index_set_version_1, C.ext_offchain_index_set_version_1},
Expand Down
69 changes: 69 additions & 0 deletions lib/runtime/wasmer/imports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ var testChildKey = []byte("childKey")
var testKey = []byte("key")
var testValue = []byte("value")

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

testKey := []byte("testkey")

Check failure on line 39 in lib/runtime/wasmer/imports_test.go

View workflow job for this annotation

GitHub Actions / linting

shadow: declaration of "testKey" shadows declaration at line 33 (govet)
testValue := []byte("testvalue")

Check failure on line 40 in lib/runtime/wasmer/imports_test.go

View workflow job for this annotation

GitHub Actions / linting

shadow: declaration of "testValue" shadows declaration at line 34 (govet)

err := inst.ctx.NodeStorage.BaseDB.Put(testKey, testValue)
require.NoError(t, err)

encKey, err := scale.Marshal(testKey)
require.NoError(t, err)

_, err = inst.Exec("ext_offchain_index_clear_version_1", encKey)
require.NoError(t, err)

value, err := inst.ctx.NodeStorage.BaseDB.Get(testKey)
require.NoError(t, err)

require.True(t, bytes.Equal(testValue, value))
}

func Test_ext_offchain_timestamp_version_1(t *testing.T) {
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)
runtimeFunc, ok := inst.vm.Exports["rtm_ext_offchain_timestamp_version_1"]
Expand Down Expand Up @@ -1283,6 +1304,54 @@ func Test_ext_default_child_storage_clear_version_1(t *testing.T) {
require.Nil(t, val)
}

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

prefix := []byte("key")
limit := uint32(0)

testKeyValuePair := []struct {
key []byte
value []byte
}{
{[]byte("keyOne"), []byte("value1")},
{[]byte("keyTwo"), []byte("value2")},
{[]byte("keyThree"), []byte("value3")},
}

err := inst.ctx.Storage.SetChild(testChildKey, trie.NewEmptyTrie())
require.NoError(t, err)

for _, kv := range testKeyValuePair {
err = inst.ctx.Storage.SetChildStorage(testChildKey, kv.key, kv.value)
require.NoError(t, err)
}

// Confirm if value is set
keys, err := inst.ctx.Storage.(*storage.TrieState).GetKeysWithPrefixFromChild(testChildKey, prefix)
require.NoError(t, err)
require.Equal(t, 3, len(keys))

encChildKey, err := scale.Marshal(testChildKey)
require.NoError(t, err)

encPrefix, err := scale.Marshal(prefix)
require.NoError(t, err)

encLimit, err := scale.Marshal(limit)
require.NoError(t, err)

data := append(encChildKey, encPrefix...)
data = append(data, encLimit...)

_, err = inst.Exec("rtm_ext_default_child_storage_clear_prefix_version_2", data)
require.NoError(t, err)

keys, err = inst.ctx.Storage.(*storage.TrieState).GetKeysWithPrefixFromChild(testChildKey, prefix)
require.NoError(t, err)
require.Equal(t, 0, len(keys))
}

func Test_ext_default_child_storage_clear_prefix_version_1(t *testing.T) {
t.Parallel()
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)
Expand Down

0 comments on commit f607013

Please sign in to comment.