Skip to content

Commit e963332

Browse files
Add extra required runtime imports for parachain validation
This commit 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
1 parent d594e1e commit e963332

9 files changed

Lines changed: 159 additions & 1 deletion

File tree

lib/runtime/constants.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const (
88
// v0.9 test API wasm
99
HOST_API_TEST_RUNTIME = "hostapi_runtime"
1010
HOST_API_TEST_RUNTIME_FP = "hostapi_runtime.compact.wasm"
11-
HOST_API_TEST_RUNTIME_URL = "https://github.com/ChainSafe/polkadot-spec/blob/4d190603d21d4431888bcb1ec546c4dc03b7bf93/test/runtimes/hostapi/hostapi_runtime.compact.wasm?raw=true" //nolint:lll
11+
HOST_API_TEST_RUNTIME_URL = "https://raw.githubusercontent.com/ChainSafe/gossamer/kishan/feat/extra-runtime-imports/lib/runtime/wasmer/hostapi_runtime.compact.wasm" //nolint:lll
1212

1313
// v0.9.29 polkadot
1414
POLKADOT_RUNTIME_v0929 = "polkadot_runtime-v929"

lib/runtime/interfaces.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type Storage interface {
2424
ClearChildStorage(keyToChild, key []byte) error
2525
NextKey([]byte) []byte
2626
ClearPrefixInChild(keyToChild, prefix []byte) error
27+
ClearPrefixInChildWithLimit(keyToChild, prefix []byte, limit uint32) error
2728
GetChildNextKey(keyToChild, key []byte) ([]byte, error)
2829
GetChild(keyToChild []byte) (*trie.Trie, error)
2930
ClearPrefix(prefix []byte) (err error)

lib/runtime/storage/trie.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,26 @@ func (s *TrieState) ClearPrefixInChild(keyToChild, prefix []byte) error {
253253
return nil
254254
}
255255

256+
func (s *TrieState) ClearPrefixInChildWithLimit(keyToChild, prefix []byte, limit uint32) error {
257+
s.lock.Lock()
258+
defer s.lock.Unlock()
259+
260+
child, err := s.t.GetChild(keyToChild)
261+
if err != nil {
262+
return err
263+
}
264+
if child == nil {
265+
return nil
266+
}
267+
268+
_, _, err = child.ClearPrefixLimit(prefix, limit)
269+
if err != nil {
270+
return fmt.Errorf("clearing prefix in child trie located at key 0x%x: %w", keyToChild, err)
271+
}
272+
273+
return nil
274+
}
275+
256276
// GetChildNextKey returns the next lexicographical larger key from child storage. If it does not exist, it returns nil.
257277
func (s *TrieState) GetChildNextKey(keyToChild, key []byte) ([]byte, error) {
258278
s.lock.RLock()
43.2 KB
Binary file not shown.

lib/runtime/wasmer/imports.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,32 @@ func ext_default_child_storage_clear_prefix_version_1(env interface{}, args []wa
10491049
return nil, nil
10501050
}
10511051

1052+
//export ext_default_child_storage_clear_prefix_version_2
1053+
func ext_default_child_storage_clear_prefix_version_2(env interface{}, args []wasmer.Value) ([]wasmer.Value, error) {
1054+
logger.Debug("executing...")
1055+
1056+
instanceContext := env.(*runtime.Context)
1057+
storage := instanceContext.Storage
1058+
childStorageKey := args[0].I64()
1059+
prefixSpan := args[1].I64()
1060+
limitSpan := args[2].I64()
1061+
1062+
keyToChild := asMemorySlice(instanceContext, childStorageKey)
1063+
prefix := asMemorySlice(instanceContext, prefixSpan)
1064+
1065+
var limit *uint32
1066+
err := scale.Unmarshal(asMemorySlice(instanceContext, limitSpan), limit)
1067+
if err != nil {
1068+
logger.Errorf("failed to decode limit: %s", err)
1069+
}
1070+
1071+
err = storage.ClearPrefixInChildWithLimit(keyToChild, prefix, *limit)
1072+
if err != nil {
1073+
logger.Errorf("failed to clear prefix in child with limit: %s", err)
1074+
}
1075+
return []wasmer.Value{wasmer.NewI64(0)}, nil
1076+
}
1077+
10521078
//export ext_default_child_storage_exists_version_1
10531079
func ext_default_child_storage_exists_version_1(env interface{}, args []wasmer.Value) ([]wasmer.Value, error) {
10541080
logger.Debug("executing...")
@@ -1162,6 +1188,12 @@ func ext_default_child_storage_root_version_1(env interface{}, args []wasmer.Val
11621188
return []wasmer.Value{wasmer.NewI64(root)}, nil
11631189
}
11641190

1191+
//export ext_default_child_storage_root_version_2
1192+
func ext_default_child_storage_root_version_2(env interface{}, args []wasmer.Value) ([]wasmer.Value, error) {
1193+
// TODO: Implement this after we have storage trie version 1 implemented #2418
1194+
return ext_default_child_storage_root_version_1(env, args)
1195+
}
1196+
11651197
//export ext_default_child_storage_set_version_1
11661198
func ext_default_child_storage_set_version_1(env interface{}, args []wasmer.Value) ([]wasmer.Value, error) {
11671199
logger.Debug("executing...")
@@ -1570,6 +1602,23 @@ func ext_offchain_index_set_version_1(env interface{}, args []wasmer.Value) ([]w
15701602
return nil, nil
15711603
}
15721604

1605+
//export ext_offchain_index_clear_version_1
1606+
func ext_offchain_index_clear_version_1(env interface{}, args []wasmer.Value) ([]wasmer.Value, error) {
1607+
// Remove a key and its associated value from the Offchain DB.
1608+
// https://github.com/paritytech/substrate/blob/4d608f9c42e8d70d835a748fa929e59a99497e90/primitives/io/src/lib.rs#L1213
1609+
logger.Trace("executing...")
1610+
instanceContext := env.(*runtime.Context)
1611+
keySpan := args[0].I64()
1612+
1613+
storageKey := asMemorySlice(instanceContext, keySpan)
1614+
err := instanceContext.NodeStorage.BaseDB.Del(storageKey)
1615+
1616+
if err != nil {
1617+
logger.Errorf("failed to set value in raw storage: %s", err)
1618+
}
1619+
return nil, nil
1620+
}
1621+
15731622
//export ext_offchain_local_storage_clear_version_1
15741623
func ext_offchain_local_storage_clear_version_1(env interface{}, args []wasmer.Value) ([]wasmer.Value, error) {
15751624
logger.Trace("executing...")

lib/runtime/wasmer/imports_func.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ func importsNodeRuntime(store *wasmer.Store, memory *wasmer.Memory, ctx *runtime
2929
importsMap["memory"] = memory
3030
}
3131

32+
importsMap["ext_offchain_index_clear_version_1"] = wasmer.NewFunctionWithEnvironment(store,
33+
wasmer.NewFunctionType(
34+
wasmer.NewValueTypes(wasmer.I64),
35+
wasmer.NewValueTypes(),
36+
), ctx, ext_offchain_index_clear_version_1)
37+
3238
importsMap["ext_logging_log_version_1"] = wasmer.NewFunctionWithEnvironment(store,
3339
wasmer.NewFunctionType(
3440
wasmer.NewValueTypes(wasmer.I32, wasmer.I64, wasmer.I64),
@@ -257,6 +263,12 @@ func importsNodeRuntime(store *wasmer.Store, memory *wasmer.Memory, ctx *runtime
257263
wasmer.NewValueTypes(),
258264
), ctx, ext_default_child_storage_clear_prefix_version_1)
259265

266+
importsMap["ext_default_child_storage_clear_prefix_version_2"] = wasmer.NewFunctionWithEnvironment(store,
267+
wasmer.NewFunctionType(
268+
wasmer.NewValueTypes(wasmer.I64, wasmer.I64, wasmer.I64),
269+
wasmer.NewValueTypes(wasmer.I64),
270+
), ctx, ext_default_child_storage_clear_prefix_version_2)
271+
260272
importsMap["ext_default_child_storage_exists_version_1"] = wasmer.NewFunctionWithEnvironment(store,
261273
wasmer.NewFunctionType(
262274
wasmer.NewValueTypes(wasmer.I64, wasmer.I64),
@@ -281,6 +293,12 @@ func importsNodeRuntime(store *wasmer.Store, memory *wasmer.Memory, ctx *runtime
281293
wasmer.NewValueTypes(wasmer.I64),
282294
), ctx, ext_default_child_storage_root_version_1)
283295

296+
importsMap["ext_default_child_storage_root_version_2"] = wasmer.NewFunctionWithEnvironment(store,
297+
wasmer.NewFunctionType(
298+
wasmer.NewValueTypes(wasmer.I64, wasmer.I32),
299+
wasmer.NewValueTypes(wasmer.I64),
300+
), ctx, ext_default_child_storage_root_version_2)
301+
284302
importsMap["ext_default_child_storage_set_version_1"] = wasmer.NewFunctionWithEnvironment(store,
285303
wasmer.NewFunctionType(
286304
wasmer.NewValueTypes(wasmer.I64, wasmer.I64, wasmer.I64),

lib/runtime/wasmer/imports_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@ var testChildKey = []byte("childKey")
3535
var testKey = []byte("key")
3636
var testValue = []byte("value")
3737

38+
func Test_ext_offchain_index_clear_version_1(t *testing.T) {
39+
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)
40+
41+
testKey := []byte("testkey")
42+
testValue := []byte("testvalue")
43+
err := inst.ctx.NodeStorage.BaseDB.Put(testKey, testValue)
44+
require.NoError(t, err)
45+
46+
encKey, err := scale.Marshal(testKey)
47+
require.NoError(t, err)
48+
49+
_, err = inst.Exec("ext_offchain_index_clear_version_1", encKey)
50+
require.NoError(t, err)
51+
52+
value, err := inst.ctx.NodeStorage.BaseDB.Get(testKey)
53+
require.NoError(t, err)
54+
55+
require.True(t, bytes.Equal(testValue, value))
56+
}
57+
3858
func Test_ext_offchain_timestamp_version_1(t *testing.T) {
3959
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)
4060
runtimeFunc, err := inst.vm.Exports.GetFunction("rtm_ext_offchain_timestamp_version_1")
@@ -1289,6 +1309,54 @@ func Test_ext_default_child_storage_clear_prefix_version_1(t *testing.T) {
12891309
require.Equal(t, 0, len(keys))
12901310
}
12911311

1312+
func Test_ext_default_child_storage_clear_prefix_version_2(t *testing.T) {
1313+
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)
1314+
1315+
prefix := []byte("key")
1316+
limit := uint32(0)
1317+
1318+
testKeyValuePair := []struct {
1319+
key []byte
1320+
value []byte
1321+
}{
1322+
{[]byte("keyOne"), []byte("value1")},
1323+
{[]byte("keyTwo"), []byte("value2")},
1324+
{[]byte("keyThree"), []byte("value3")},
1325+
}
1326+
1327+
err := inst.ctx.Storage.SetChild(testChildKey, trie.NewEmptyTrie())
1328+
require.NoError(t, err)
1329+
1330+
for _, kv := range testKeyValuePair {
1331+
err = inst.ctx.Storage.SetChildStorage(testChildKey, kv.key, kv.value)
1332+
require.NoError(t, err)
1333+
}
1334+
1335+
// Confirm if value is set
1336+
keys, err := inst.ctx.Storage.(*storage.TrieState).GetKeysWithPrefixFromChild(testChildKey, prefix)
1337+
require.NoError(t, err)
1338+
require.Equal(t, 3, len(keys))
1339+
1340+
encChildKey, err := scale.Marshal(testChildKey)
1341+
require.NoError(t, err)
1342+
1343+
encPrefix, err := scale.Marshal(prefix)
1344+
require.NoError(t, err)
1345+
1346+
encLimit, err := scale.Marshal(limit)
1347+
require.NoError(t, err)
1348+
1349+
data := append(encChildKey, encPrefix...)
1350+
data = append(data, encLimit...)
1351+
1352+
_, err = inst.Exec("rtm_ext_default_child_storage_clear_prefix_version_2", data)
1353+
require.NoError(t, err)
1354+
1355+
keys, err = inst.ctx.Storage.(*storage.TrieState).GetKeysWithPrefixFromChild(testChildKey, prefix)
1356+
require.NoError(t, err)
1357+
require.Equal(t, 0, len(keys))
1358+
}
1359+
12921360
func Test_ext_default_child_storage_exists_version_1(t *testing.T) {
12931361
inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)
12941362

lib/runtime/wasmer/instance.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ func (in *Instance) Exec(function string, data []byte) (result []byte, err error
268268
memory := in.ctx.Memory.Data()
269269
copy(memory[inputPtr:inputPtr+dataLength], data)
270270

271+
fmt.Println("in.vm.Exports", in.vm.Exports)
271272
runtimeFunc, err := in.vm.Exports.GetFunction(function)
272273
if err != nil {
273274
return nil, fmt.Errorf("%w: %s", ErrExportFunctionNotFound, function)

lib/runtime/wasmer/interfaces.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type Storage interface {
2323
ClearChildStorage(keyToChild, key []byte) error
2424
NextKey([]byte) []byte
2525
ClearPrefixInChild(keyToChild, prefix []byte) error
26+
ClearPrefixInChildWithLimit(keyToChild, prefix []byte, limit uint32) error
2627
GetChildNextKey(keyToChild, key []byte) ([]byte, error)
2728
GetChild(keyToChild []byte) (*trie.Trie, error)
2829
ClearPrefix(prefix []byte) (err error)

0 commit comments

Comments
 (0)