Skip to content

Commit

Permalink
feat(rpc): Implement childstate_getStorageSize RPC call (#1810)
Browse files Browse the repository at this point in the history
* feat: implement childstate_getKeys

* chore: finish unit tests

* chore: add childstate to http.go module init

* chore: address lint warns

* chore: addressing test issues

* chore: address deepsource complaints

* feat: implement childstate_getStorageHash

* feat: implement childstate_getStorageSize

* chore: check nil before return len

* chore: fix export comment

* chore: transform common.Hash prop into pointer

* chore: fix unit test
  • Loading branch information
EclesioMeloJunior authored Oct 5, 2021
1 parent 5c11fb2 commit a04deb6
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 1 deletion.
34 changes: 34 additions & 0 deletions dot/rpc/modules/childstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ type GetStorageHash struct {
Hash *common.Hash
}

// GetChildStorageRequest the request to get the entry child storage hash
type GetChildStorageRequest struct {
KeyChild []byte
EntryKey []byte
Hash *common.Hash
}

// ChildStateModule is the module responsible to implement all the childstate RPC calls
type ChildStateModule struct {
storageAPI StorageAPI
Expand Down Expand Up @@ -80,6 +87,33 @@ func (cs *ChildStateModule) GetKeys(_ *http.Request, req *GetKeysRequest, res *[
return nil
}

// GetStorageSize returns the size of a child storage entry.
func (cs *ChildStateModule) GetStorageSize(_ *http.Request, req *GetChildStorageRequest, res *uint64) error {
var hash common.Hash

if req.Hash == nil {
hash = cs.blockAPI.BestBlockHash()
} else {
hash = *req.Hash
}

stateRoot, err := cs.storageAPI.GetStateRootFromBlock(&hash)
if err != nil {
return err
}

item, err := cs.storageAPI.GetStorageFromChild(stateRoot, req.KeyChild, req.EntryKey)
if err != nil {
return err
}

if item != nil {
*res = uint64(len(item))
}

return nil
}

// GetStorageHash returns the hash of a child storage entry
func (cs *ChildStateModule) GetStorageHash(_ *http.Request, req *GetStorageHash, res *string) error {
var hash common.Hash
Expand Down
66 changes: 65 additions & 1 deletion dot/rpc/modules/childstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"testing"

"github.com/ChainSafe/chaindb"

"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/trie"
Expand Down Expand Up @@ -70,6 +69,71 @@ func TestChildStateGetKeys(t *testing.T) {
}
}

func TestChildStateGetStorageSize(t *testing.T) {
mod, blockHash := setupChildStateStorage(t)
invalidHash := common.BytesToHash([]byte("invalid block hash"))

tests := []struct {
expect uint64
err error
hash *common.Hash
keyChild []byte
entry []byte
}{
{
err: nil,
expect: uint64(len([]byte(":child_first_value"))),
hash: nil,
entry: []byte(":child_first"),
keyChild: []byte(":child_storage_key"),
},
{
err: nil,
expect: uint64(len([]byte(":child_second_value"))),
hash: &blockHash,
entry: []byte(":child_second"),
keyChild: []byte(":child_storage_key"),
},
{
err: nil,
expect: 0,
hash: nil,
entry: []byte(":not_found_so_size_0"),
keyChild: []byte(":child_storage_key"),
},
{
err: fmt.Errorf("child trie does not exist at key %s%s", trie.ChildStorageKeyPrefix, []byte(":not_exist")),
hash: &blockHash,
entry: []byte(":child_second"),
keyChild: []byte(":not_exist"),
},
{
err: chaindb.ErrKeyNotFound,
hash: &invalidHash,
},
}

for _, test := range tests {
var req GetChildStorageRequest
var res uint64

req.Hash = test.hash
req.EntryKey = test.entry
req.KeyChild = test.keyChild

err := mod.GetStorageSize(nil, &req, &res)

if test.err != nil {
require.Error(t, err)
require.Equal(t, err, test.err)
} else {
require.NoError(t, err)
}

require.Equal(t, test.expect, res)
}
}

func TestGetStorageHash(t *testing.T) {
mod, blockHash := setupChildStateStorage(t)
invalidBlockHash := common.BytesToHash([]byte("invalid block hash"))
Expand Down

0 comments on commit a04deb6

Please sign in to comment.