Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pkg/trie): Add TrieCache for trie values and nodes #3895

Merged
merged 116 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
3aa9e4b
refactor(pkg/trie): Read only tries
dimartiro Apr 1, 2024
5df2660
feat(pkg/trie/triedb): (wip) add trieDB
dimartiro Apr 1, 2024
fb2edcb
feat(pkg/trie/triedb): (wip) add lookup
dimartiro Apr 2, 2024
9d826c7
refactor(pkg/trie/triedb): remove lookup struct
dimartiro Apr 3, 2024
5f51409
Merge branch 'development' of github.com:ChainSafe/gossamer into dieg…
dimartiro Apr 3, 2024
d42f293
Add lookup doc
dimartiro Apr 3, 2024
109d61d
Add missing license
dimartiro Apr 3, 2024
d07ac89
refactor(pkg/trie): wip
dimartiro Apr 5, 2024
726f5ec
feat(pkg/trie): Basic lazy loading working :D
dimartiro Apr 5, 2024
b023405
fix(pkg/trie): Fix v1 case
dimartiro Apr 5, 2024
7f72fe1
Add missing license
dimartiro Apr 5, 2024
65c1921
Add unit tests
dimartiro Apr 5, 2024
d32c69e
Merge branch 'development' of github.com:ChainSafe/gossamer into dieg…
dimartiro Apr 5, 2024
2004f61
Add more tests and comments
dimartiro Apr 5, 2024
af2929f
One more comment
dimartiro Apr 5, 2024
863f9d7
Linting
dimartiro Apr 5, 2024
7fa7dcf
Fix godoc
dimartiro Apr 5, 2024
84a9041
Add missing godoc
dimartiro Apr 5, 2024
fa0c201
Merge branch 'development' into diego/read-only-triedb
dimartiro Apr 9, 2024
ea2758f
wip
dimartiro Apr 9, 2024
962025d
Add missing godoc
dimartiro Apr 5, 2024
8ed1cc2
Update copyright
dimartiro Apr 9, 2024
606c066
refactor(pkg/trie): Rename interfaces
dimartiro Apr 9, 2024
d13ab41
Merge branch 'diego/read-only-triedb' of github.com:ChainSafe/gossame…
dimartiro Apr 9, 2024
45a1529
refactor(pkg/trie): Move error to top
dimartiro Apr 9, 2024
6bf80fc
Update copyright
dimartiro Apr 9, 2024
3124dd4
refactor(pkg/trie): Move error to top
dimartiro Apr 9, 2024
625b5d8
Update copyright
dimartiro Apr 9, 2024
938c4de
refactor(pkg/trie): Change method signature
dimartiro Apr 9, 2024
8f9748d
refactor(pkg/trie): Remove TrieDeltas from ReadOnlyTrie interface
dimartiro Apr 10, 2024
28d67ee
refactor(pkg/trie): Decode node key in main decode method
dimartiro Apr 10, 2024
0aea7fd
refactor(pkg/trie): Move error handling
dimartiro Apr 10, 2024
dff754b
refactor(pkg/trie): Simplify childrenBitmap decode and checks
dimartiro Apr 10, 2024
7f55d79
refactor(pkg/trie): Replace decimal to bits in tests
dimartiro Apr 10, 2024
30be47d
refactor(pkg/trie): Add childbitmap check comment
dimartiro Apr 10, 2024
cba53df
refactor(pkg/trie): Use built-in bytes methods
dimartiro Apr 11, 2024
15c5bdb
refactor(pkg/trie): Change enum method
dimartiro Apr 11, 2024
77d7918
chore(pkg/trie): Add comment to explain key decode
dimartiro Apr 11, 2024
c0e5c15
Merge branch 'diego/read-only-triedb' of github.com:ChainSafe/gossame…
dimartiro Apr 11, 2024
6c26387
chore(pkg/trie): Add TrieDBIterator to solve rest of read trie methods
dimartiro Apr 11, 2024
312e466
feat(pkg/trie/triedb): Implements Entries and GetKeysWithPrefix using…
dimartiro Apr 11, 2024
e548c75
refactor(pkg/trie/triedb): Improves GetKeysWithPrefix method
dimartiro Apr 11, 2024
93a40d0
refactor(pkg/trie/triedb): Remove unnecesary method
dimartiro Apr 11, 2024
1f19a9e
refactor(pkg/trie/triedb): Use triedb Entry
dimartiro Apr 11, 2024
8372b04
refactor(pkg/trie/triedb): Change error type
dimartiro Apr 11, 2024
8cbf9a0
refactor(pkg/trie/triedb): Merge PrefixTrieRead interface with TrieIt…
dimartiro Apr 11, 2024
c29b3b6
refactor(pkg/trie/triedb): Rename interfaces
dimartiro Apr 12, 2024
77161ee
refactor(pkg/trie/triedb): Remove comment
dimartiro Apr 12, 2024
882bda2
refactor(pkg/trie/triedb): Add missing empty node case
dimartiro Apr 15, 2024
35a8645
Merge branch 'development' into diego/read-only-triedb
dimartiro Apr 15, 2024
4c47c5d
Merge branch 'diego/read-only-triedb' of github.com:ChainSafe/gossame…
dimartiro Apr 15, 2024
427daf4
refactor(pkg/trie): Change receiver name to use the same
dimartiro Apr 16, 2024
441718d
feat(pkg/trie): Add TrieCache for trie values
dimartiro Apr 16, 2024
74a5fc5
Merge branch 'diego/read-only-triedb' of github.com:ChainSafe/gossame…
dimartiro Apr 16, 2024
09594d4
chore(pkg/trie): Add benchmarking
dimartiro Apr 16, 2024
6ea0572
chore(pkg/trie): Add testing
dimartiro Apr 16, 2024
c62b319
Merge branch 'development' of github.com:ChainSafe/gossamer into dieg…
dimartiro Apr 16, 2024
d3c4e8a
chore(pkg/trie): Add more tests
dimartiro Apr 16, 2024
8dc4958
Merge branch 'development' of github.com:ChainSafe/gossamer into dieg…
dimartiro Apr 16, 2024
a67b7e3
refactor(pkg/trie): Remove empty method from enum
dimartiro Apr 16, 2024
9bb0299
chore: Add missing license files
dimartiro Apr 16, 2024
f538e24
chore(pkg/trie): Add godocs
dimartiro Apr 16, 2024
cc4f429
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 16, 2024
5bb0f5a
chore(pkg/trie): Add missing license
dimartiro Apr 16, 2024
feadac0
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 16, 2024
dcbe26c
refactor(pkg/trie): Rename cache to LRU
dimartiro Apr 16, 2024
b38a2bf
feat(pkg/trie): Add nodes cache
dimartiro Apr 16, 2024
d7febfb
chore(pkg/trie): Add comment
dimartiro Apr 16, 2024
d80fdae
Merge branch 'development' into diego/triedb-iterator
dimartiro Apr 16, 2024
6e9e249
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 16, 2024
a247385
fix(pkg/trie): PR comments
dimartiro Apr 17, 2024
b24e767
Merge branch 'development' into diego/triedb-iterator
dimartiro Apr 17, 2024
02c4243
chore(pkg/trie): Add TODO comment
dimartiro Apr 17, 2024
49de9dc
fix(pkg/trie): Linting
dimartiro Apr 17, 2024
b134a0f
chore(pkg/trie): add TODOs as reminders for future optimizations
dimartiro Apr 17, 2024
b388b48
refactor(pkg/trie): Do not export trie entry struct
dimartiro Apr 18, 2024
d15a513
refactor(pkg/trie): Create TrieLookup structure
dimartiro Apr 22, 2024
b30747d
refactor(pkg/trie): Prefixed iterator to only iterate over prefixed keys
dimartiro Apr 22, 2024
a1d0781
chore(pkg/trie): add license
dimartiro Apr 22, 2024
ddb3a67
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 22, 2024
ae11fba
refactor(pkg/trie): Create DB wrapper with write through caching
dimartiro Apr 22, 2024
5eedb1b
chore(pkg/trie): add license
dimartiro Apr 22, 2024
b6056d6
Merge branch 'development' into diego/triedb-iterator
dimartiro Apr 22, 2024
1843e5b
fix(pkg/trie): Fix get value
dimartiro Apr 22, 2024
105e172
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 22, 2024
0e67412
fix(pkg/trie): Remove wrong test
dimartiro Apr 22, 2024
07345db
fix(pkg/trie): Instantiate independent lookups
dimartiro Apr 22, 2024
7ca654d
fix(pkg/trie): Improve values lookup
dimartiro Apr 22, 2024
c9cae6f
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 22, 2024
497c992
Merge branch 'development' into diego/triedb-iterator
dimartiro Apr 22, 2024
4287353
fix(pkg/trie): Improve iterator with cache performance
dimartiro Apr 22, 2024
0d532c8
Merge branch 'development' into diego/triedb-iterator
dimartiro Apr 23, 2024
8c99544
Merge branch 'development' into diego/triedb-iterator
dimartiro Apr 24, 2024
3ffbef0
fix(pkg/trie): Fix deepsource
dimartiro Apr 24, 2024
5ccc64a
Merge branch 'development' of github.com:ChainSafe/gossamer into dieg…
dimartiro Apr 24, 2024
0da71ec
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 24, 2024
8abb936
Merge branch 'diego/triedb-iterator' of github.com:ChainSafe/gossamer…
dimartiro Apr 24, 2024
d0d1536
Merge branch 'development' of github.com:ChainSafe/gossamer into dieg…
dimartiro May 8, 2024
991b71c
chore(pkg/trie): Remove TODO comment
dimartiro May 9, 2024
93606fb
chore(pkg/trie): Remove comment
dimartiro May 9, 2024
d0c380e
refactor(pkg/trie): Expose TrieInMemoryCache
dimartiro May 9, 2024
5d318df
feat(pkg/trie): Implements node caching
dimartiro May 9, 2024
339b73c
fix(pkg/trie): Cache usage
dimartiro May 9, 2024
0997bf9
chore(pkg/trie): Rename benchmarks
dimartiro May 9, 2024
aa9cf89
Merge branch 'development' into diego/triedb-cache
dimartiro May 13, 2024
8f185d9
Merge branch 'development' into diego/triedb-cache
dimartiro May 13, 2024
e38d90e
refactor(pkg/trie): Combine function parameters
dimartiro May 13, 2024
71d80fe
Merge branch 'development' into diego/triedb-cache
dimartiro May 13, 2024
26ede66
Merge branch 'development' into diego/triedb-cache
dimartiro May 14, 2024
becb48e
fix(pkg/trie): Set right cache when caching node values
dimartiro May 15, 2024
62c2b38
refactor(pkg/trie): Use cache with items limit for nodes
dimartiro May 15, 2024
cea2b9f
Merge branch 'development' into diego/triedb-cache
dimartiro May 15, 2024
6c7eb45
refactor(pkg/trie): Rename lruCache to maxBytesLruCache
dimartiro May 20, 2024
ddbe912
Merge branch 'development' into diego/triedb-cache
dimartiro May 20, 2024
a4534f2
Merge branch 'development' into diego/triedb-cache
dimartiro May 21, 2024
d04c392
Merge branch 'development' into diego/triedb-cache
dimartiro May 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/ipfs/go-ds-badger2 v0.1.3
github.com/jpillora/backoff v1.0.0
github.com/jpillora/ipfilter v1.2.9
github.com/karlseguin/ccache/v3 v3.0.5
github.com/klauspost/compress v1.17.8
github.com/libp2p/go-libp2p v0.33.2
github.com/libp2p/go-libp2p-kad-dht v0.25.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/UnevQ=
github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
Expand Down
49 changes: 49 additions & 0 deletions pkg/trie/cache/inmemory/maxbytes_lru_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2024 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package inmemory

import (
"github.com/karlseguin/ccache/v3"
)

// ccache uses 350 bytes of overhead per entry
const cacheValueOverheadSize = 350

// cacheValue is a helper alias over []byte to implement ccache.Sized
type cacheValue []byte

// Size returns the size of the cacheValue taking the overhead into account
func (cv cacheValue) Size() int64 {
return int64(len(cv) + cacheValueOverheadSize)
}

// maxBytesLRUCache is an in-memory lru cache
// consider that the values are deleted asyncronously so there is a chance that
// the maxSize can be exceeded
// we can use lru.GC() to force the deletion of the items that should be deleted
type maxBytesLRUCache struct {
lru *ccache.Cache[cacheValue]
}

// newlruCache creates a new lruCache
// maxSize is the cache max size in bytes
func newLruCache(maxSize int64) *maxBytesLRUCache {
cache := ccache.New(ccache.Configure[cacheValue]().MaxSize(maxSize))
return &maxBytesLRUCache{
lru: cache,
}
}

func (cache *maxBytesLRUCache) get(key string) []byte {
item := cache.lru.Get(key)
if item != nil {
return item.Value()

}
return nil
}

func (cache *maxBytesLRUCache) set(key string, value []byte) {
cache.lru.Set(key, cacheValue(value), 0)
}
56 changes: 56 additions & 0 deletions pkg/trie/cache/inmemory/maxbytes_lru_cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2024 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package inmemory

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_TrieValueCache_SetAndGet(t *testing.T) {
const maxCacheSize = 10
t.Run("set_and_get_value_successful", func(t *testing.T) {
cache := newLruCache(maxCacheSize)
key := "key"
value := []byte("value")

cache.set(key, value)
valueFromCache := cache.get(key)

assert.Equal(t, value, valueFromCache)
})

t.Run("get_value_not_found", func(t *testing.T) {
cache := newLruCache(maxCacheSize)
valueFromCache := cache.get("missing")
assert.Nil(t, valueFromCache)
})

t.Run("replace_value_when_size_exceeded", func(t *testing.T) {
cache := newLruCache(maxCacheSize)
key1 := "key1"
key2 := "key2"
value1 := make([]byte, maxCacheSize/2+1)
value2 := make([]byte, maxCacheSize/2+1)

// First value is inserted successfully
cache.set(key1, value1)
valueFromCache := cache.get(key1)

assert.Equal(t, value1, valueFromCache)

// Second value is inserted successfully
cache.set(key2, value2)
valueFromCache = cache.get(key2)

assert.Equal(t, value2, valueFromCache)

// First value has been removed
cache.lru.GC() // Force GC to remove items that should be deleted

valueFromCache = cache.get(key1)
assert.Nil(t, valueFromCache)
})
}
49 changes: 49 additions & 0 deletions pkg/trie/cache/inmemory/trie_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2024 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package inmemory

import (
lrucache "github.com/ChainSafe/gossamer/lib/utils/lru-cache"
"github.com/ChainSafe/gossamer/pkg/trie/cache"
)

// https://github.com/paritytech/polkadot-sdk/blob/a8f4f4f00f8fc0da512a09e1450bf4cda954d70d/substrate/primitives/trie/src/cache/mod.rs#L98
const defaultNodeCacheMaxElements = 10000
const defaultValueCacheMaxSize = 2 * 1024 * 1024 // 2MB

// TrieInMemoryCache is an in-memory cache for trie nodes
type TrieInMemoryCache struct {
nodeCache *lrucache.LRUCache[string, []byte]
valueCache *maxBytesLRUCache
}

// NewTrieInMemoryCache creates a new TrieInMemoryCache
func NewTrieInMemoryCache() *TrieInMemoryCache {
return &TrieInMemoryCache{
nodeCache: lrucache.NewLRUCache[string, []byte](defaultNodeCacheMaxElements),
valueCache: newLruCache(defaultValueCacheMaxSize),
}
}

// GetValue returns the value for the given key
func (tc *TrieInMemoryCache) GetValue(key []byte) []byte {
return tc.valueCache.get(string(key))
}

// SetValue sets the value for the given key
func (tc *TrieInMemoryCache) SetValue(key []byte, value []byte) {
tc.valueCache.set(string(key), value)
}

// GetNode returns the node for the given key
func (tc *TrieInMemoryCache) GetNode(key []byte) []byte {
return tc.nodeCache.Get(string(key))
}

// SetNode sets the node for the given key
func (tc *TrieInMemoryCache) SetNode(key, value []byte) {
tc.nodeCache.Put(string(key), value)
}

var _ cache.TrieCache = (*TrieInMemoryCache)(nil)
29 changes: 29 additions & 0 deletions pkg/trie/cache/inmemory/trie_cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package inmemory

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_TrieCache_SetAndGet(t *testing.T) {
t.Run("set_and_get_value_successful", func(t *testing.T) {
cache := NewTrieInMemoryCache()
key := []byte("key")
value := []byte("value")

cache.SetValue(key, value)
valueFromCache := cache.GetValue(key)

assert.Equal(t, value, valueFromCache)
})

t.Run("get_value_not_found", func(t *testing.T) {
cache := NewTrieInMemoryCache()
valueFromCache := cache.GetValue([]byte("missing"))
assert.Nil(t, valueFromCache)
})
}
11 changes: 11 additions & 0 deletions pkg/trie/cache/trie_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2024 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package cache

type TrieCache interface {
GetValue(key []byte) []byte
SetValue(key, value []byte)
GetNode(key []byte) []byte
SetNode(key, value []byte)
}
8 changes: 4 additions & 4 deletions pkg/trie/triedb/in_memory_to_triedb_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import (
"github.com/ChainSafe/gossamer/pkg/trie"
"github.com/ChainSafe/gossamer/pkg/trie/inmemory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func newTestDB(t *testing.T) database.Table {
func newTestDB(t assert.TestingT) database.Table {
db, err := database.NewPebble("", true)
require.NoError(t, err)
assert.NoError(t, err)
dimartiro marked this conversation as resolved.
Show resolved Hide resolved
return database.NewTable(db, "trie")
}

Expand Down Expand Up @@ -44,11 +43,12 @@ func TestTrieDB_Migration(t *testing.T) {

root, err := inMemoryTrie.Hash()
assert.NoError(t, err)
trieDB := NewTrieDB(root, db)
trieDB := NewTrieDB(root, db, nil)

t.Run("read_successful_from_db_created_using_v1_trie", func(t *testing.T) {
for k, v := range entries {
value := trieDB.Get([]byte(k))
assert.NotNil(t, value)
assert.Equal(t, v, value)
}

Expand Down
70 changes: 58 additions & 12 deletions pkg/trie/triedb/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,25 @@ import (
"bytes"

"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/trie/cache"
"github.com/ChainSafe/gossamer/pkg/trie/db"
"github.com/ChainSafe/gossamer/pkg/trie/triedb/codec"
)

type TrieLookup struct {
// Database to query from
// db to query from
db db.DBGetter
// Hash to start at
// hash to start at
hash common.Hash
// cache to speed up the db lookups
cache cache.TrieCache
}

func NewTrieLookup(db db.DBGetter, hash common.Hash) TrieLookup {
func NewTrieLookup(db db.DBGetter, hash common.Hash, cache cache.TrieCache) TrieLookup {
return TrieLookup{
db: db,
hash: hash,
db: db,
hash: hash,
cache: cache,
}
}

Expand All @@ -33,9 +37,21 @@ func (l *TrieLookup) lookupNode(keyNibbles []byte) (codec.Node, error) {
// Iterates through non inlined nodes
for {
// Get node from DB
nodeData, err := l.db.Get(hash)
if err != nil {
return nil, ErrIncompleteDB
var nodeData []byte
if l.cache != nil {
nodeData = l.cache.GetNode(hash)
}

if nodeData == nil {
var err error
nodeData, err = l.db.Get(hash)
if err != nil {
return nil, ErrIncompleteDB
}

if l.cache != nil {
l.cache.SetNode(hash, nodeData)
}
}

InlinedChildrenIterator:
Expand Down Expand Up @@ -103,14 +119,29 @@ func (l *TrieLookup) lookupNode(keyNibbles []byte) (codec.Node, error) {
}
}

func (l *TrieLookup) lookupValue(keyNibbles []byte) ([]byte, error) {
func (l *TrieLookup) lookupValue(keyNibbles []byte) (value []byte, err error) {
if l.cache != nil {
if value = l.cache.GetValue(keyNibbles); value != nil {
return value, nil
}
}

node, err := l.lookupNode(keyNibbles)
dimartiro marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

if value := node.GetValue(); value != nil {
return l.fetchValue(node.GetPartialKey(), value)
if nodeValue := node.GetValue(); nodeValue != nil {
value, err = l.fetchValue(node.GetPartialKey(), nodeValue)
if err != nil {
return nil, err
}

if l.cache != nil {
l.cache.SetValue(keyNibbles, value)
}

return value, nil
}

return nil, nil
Expand All @@ -124,7 +155,22 @@ func (l *TrieLookup) fetchValue(prefix []byte, value codec.NodeValue) ([]byte, e
return v.Data, nil
case codec.HashedValue:
prefixedKey := bytes.Join([][]byte{prefix, v.Data}, nil)
return l.db.Get(prefixedKey)
if l.cache != nil {
if value := l.cache.GetValue(prefixedKey); value != nil {
return value, nil
}
}

nodeData, err := l.db.Get(prefixedKey)
if err != nil {
return nil, err
}

if l.cache != nil {
l.cache.SetValue(prefixedKey, nodeData)
}

return nodeData, nil
default:
panic("unreachable")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/trie/triedb/lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
func TestTrieDB_Lookup(t *testing.T) {
t.Run("root_not_exists_in_db", func(t *testing.T) {
db := newTestDB(t)
lookup := NewTrieLookup(db, trie.EmptyHash)
lookup := NewTrieLookup(db, trie.EmptyHash, nil)

value, err := lookup.lookupValue([]byte("test"))
assert.Nil(t, value)
Expand Down
Loading
Loading