Skip to content

Commit

Permalink
Fix issue centrifuge#66 by returning a bool if a storage value is empty
Browse files Browse the repository at this point in the history
  • Loading branch information
philipstanislaus committed Mar 24, 2020
1 parent 1be572e commit b0e58dd
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 21 deletions.
23 changes: 15 additions & 8 deletions rpc/state/get_child_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,30 @@ import (
"github.com/centrifuge/go-substrate-rpc-client/types"
)

// GetChildStorage retreives the child storage for a key and decodes them into the provided interface
func (s *State) GetChildStorage(childStorageKey, key types.StorageKey, target interface{}, blockHash types.Hash) error {
// GetChildStorage retreives the child storage for a key and decodes them into the provided interface. Ok is true if the
// value is not empty.
func (s *State) GetChildStorage(childStorageKey, key types.StorageKey, target interface{}, blockHash types.Hash) (ok bool, err error) {
raw, err := s.getChildStorageRaw(childStorageKey, key, &blockHash)
if err != nil {
return err
return false, err
}
return types.DecodeFromBytes(*raw, target)
if len(*raw) == 0 {
return false, nil
}
return true, types.DecodeFromBytes(*raw, target)
}

// GetChildStorageLatest retreives the child storage for a key for the latest block height and decodes them into the
// provided interface
func (s *State) GetChildStorageLatest(childStorageKey, key types.StorageKey, target interface{}) error {
// provided interface. Ok is true if the value is not empty.
func (s *State) GetChildStorageLatest(childStorageKey, key types.StorageKey, target interface{}) (ok bool, err error) {
raw, err := s.getChildStorageRaw(childStorageKey, key, nil)
if err != nil {
return err
return false, err
}
if len(*raw) == 0 {
return false, nil
}
return types.DecodeFromBytes(*raw, target)
return true, types.DecodeFromBytes(*raw, target)
}

// GetChildStorageRaw retreives the child storage for a key as raw bytes, without decoding them
Expand Down
6 changes: 4 additions & 2 deletions rpc/state/get_child_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ var key = types.NewStorageKey(types.MustHexDecodeString(mockSrv.childStorageTrie

func TestState_GetChildStorageLatest(t *testing.T) {
var decoded ChildStorageTrieTestVal
err := state.GetChildStorageLatest(childStorageKey, key, &decoded)
ok, err := state.GetChildStorageLatest(childStorageKey, key, &decoded)
assert.True(t, ok)
assert.NoError(t, err)
assert.Equal(t, mockSrv.childStorageTrieValue, decoded)
}

func TestState_GetChildStorage(t *testing.T) {
var decoded ChildStorageTrieTestVal
err := state.GetChildStorageLatest(childStorageKey, key, &decoded)
ok, err := state.GetChildStorageLatest(childStorageKey, key, &decoded)
assert.True(t, ok)
assert.NoError(t, err)
assert.Equal(t, mockSrv.childStorageTrieValue, decoded, mockSrv.blockHashLatest)
}
Expand Down
27 changes: 19 additions & 8 deletions rpc/state/get_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,37 @@
package state

import (
"fmt"

"github.com/centrifuge/go-substrate-rpc-client/client"
"github.com/centrifuge/go-substrate-rpc-client/types"
)

// GetStorage retreives the stored data and decodes them into the provided interface
func (s *State) GetStorage(key types.StorageKey, target interface{}, blockHash types.Hash) error {
// GetStorage retreives the stored data and decodes them into the provided interface. Ok is true if the value is not
// empty.
func (s *State) GetStorage(key types.StorageKey, target interface{}, blockHash types.Hash) (ok bool, err error) {
raw, err := s.getStorageRaw(key, &blockHash)
if err != nil {
return err
return false, err
}
fmt.Printf("%#v", raw)
if len(*raw) == 0 {
return false, nil
}
return types.DecodeFromBytes(*raw, target)
return true, types.DecodeFromBytes(*raw, target)
}

// GetStorageLatest retreives the stored data for the latest block height and decodes them into the provided interface
func (s *State) GetStorageLatest(key types.StorageKey, target interface{}) error {
// GetStorageLatest retreives the stored data for the latest block height and decodes them into the provided interface.
// Ok is true if the value is not empty.
func (s *State) GetStorageLatest(key types.StorageKey, target interface{}) (ok bool, err error) {
raw, err := s.getStorageRaw(key, nil)
if err != nil {
return err
return false, err
}
if len(*raw) == 0 {
return false, nil
}
return types.DecodeFromBytes(*raw, target)
return true, types.DecodeFromBytes(*raw, target)
}

// GetStorageRaw retreives the stored data as raw bytes, without decoding them
Expand Down
13 changes: 11 additions & 2 deletions rpc/state/get_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,27 @@ import (

func TestState_GetStorageLatest(t *testing.T) {
var decoded types.U64
err := state.GetStorageLatest(types.MustHexDecodeString(mockSrv.storageKeyHex), &decoded)
ok, err := state.GetStorageLatest(types.MustHexDecodeString(mockSrv.storageKeyHex), &decoded)
assert.NoError(t, err)
assert.True(t, ok)
assert.Equal(t, types.U64(0x5d892db8), decoded)
}

func TestState_GetStorage(t *testing.T) {
var decoded types.U64
err := state.GetStorage(types.MustHexDecodeString(mockSrv.storageKeyHex), &decoded, mockSrv.blockHashLatest)
ok, err := state.GetStorage(types.MustHexDecodeString(mockSrv.storageKeyHex), &decoded, mockSrv.blockHashLatest)
assert.NoError(t, err)
assert.True(t, ok)
assert.Equal(t, types.U64(0x5d892db8), decoded)
}

func TestState_GetStorageEmpty(t *testing.T) {
var decoded types.U64
ok, err := state.GetStorage([]byte{0xab}, &decoded, mockSrv.blockHashLatest)
assert.NoError(t, err)
assert.False(t, ok)
}

func TestState_GetStorageRawLatest(t *testing.T) {
data, err := state.GetStorageRawLatest(types.MustHexDecodeString(mockSrv.storageKeyHex))
assert.NoError(t, err)
Expand Down
4 changes: 3 additions & 1 deletion rpc/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type MockSrv struct {
metadata *types.Metadata
runtimeVersion types.RuntimeVersion
storageKeyHex string
storageKeyHexEmpty string
storageChangeSets []types.StorageChangeSet
storageDataHex string
storageSize types.U64
Expand Down Expand Up @@ -82,7 +83,7 @@ func (s *MockSrv) GetKeys(key string, hash *string) []string {

func (s *MockSrv) GetStorage(key string, hash *string) string {
if key != s.storageKeyHex {
panic("key not found")
return ""
}
return mockSrv.storageDataHex
}
Expand Down Expand Up @@ -168,6 +169,7 @@ var mockSrv = MockSrv{
metadataString: types.ExamplaryMetadataV4String,
runtimeVersion: types.RuntimeVersion{APIs: []types.RuntimeVersionAPI{{APIID: "0xdf6acb689907609b", Version: 0x2}, {APIID: "0x37e397fc7c91f5e4", Version: 0x1}, {APIID: "0x40fe3ad401f8959a", Version: 0x3}, {APIID: "0xd2bc9897eed08f15", Version: 0x1}, {APIID: "0xf78b278be53f454c", Version: 0x1}, {APIID: "0xed99c5acb25eedf5", Version: 0x2}, {APIID: "0xdd718d5cc53262d4", Version: 0x1}, {APIID: "0x7801759919ee83e5", Version: 0x1}}, AuthoringVersion: 0xa, ImplName: "substrate-node", ImplVersion: 0x3e, SpecName: "node", SpecVersion: 0x3c}, //nolint:lll
storageKeyHex: "0x0e4944cfd98d6f4cc374d16f5a4e3f9c",
storageKeyHexEmpty: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
storageChangeSets: []types.StorageChangeSet{{Block: types.Hash{0xdd, 0x18, 0x16, 0xb6, 0xf6, 0x88, 0x9f, 0x46, 0xe2, 0x3b, 0xd, 0x67, 0x50, 0xbc, 0x44, 0x1a, 0xf9, 0xda, 0xd0, 0xfd, 0xa8, 0xba, 0xe9, 0x6, 0x77, 0xc1, 0x70, 0x8d, 0x1, 0x3, 0x5f, 0xbe}, Changes: []types.KeyValueOption{{StorageKey: types.StorageKey{0xe, 0x49, 0x44, 0xcf, 0xd9, 0x8d, 0x6f, 0x4c, 0xc3, 0x74, 0xd1, 0x6f, 0x5a, 0x4e, 0x3f, 0x9c}, HasStorageData: true, StorageData: types.StorageDataRaw{0x88, 0x2, 0x66, 0x9f, 0x6e, 0x1, 0x0, 0x0}}}}, {Block: types.Hash{0x82, 0x14, 0xa1, 0x80, 0x8b, 0xd6, 0xb0, 0x46, 0xc8, 0x77, 0xa6, 0x4f, 0xce, 0xad, 0xb4, 0xa2, 0xa7, 0x3a, 0x65, 0x76, 0x9f, 0x61, 0x4, 0xc0, 0x20, 0xd7, 0x59, 0xad, 0x8f, 0x61, 0xc0, 0xd8}, Changes: []types.KeyValueOption{{StorageKey: types.StorageKey{0xe, 0x49, 0x44, 0xcf, 0xd9, 0x8d, 0x6f, 0x4c, 0xc3, 0x74, 0xd1, 0x6f, 0x5a, 0x4e, 0x3f, 0x9c}, HasStorageData: true, StorageData: types.StorageDataRaw{0x40, 0xe, 0x66, 0x9f, 0x6e, 0x1, 0x0, 0x0}}}}}, //nolint:lll
storageDataHex: "0xb82d895d00000000",
storageSize: 926778,
Expand Down

0 comments on commit b0e58dd

Please sign in to comment.