Skip to content

Commit a95b51a

Browse files
committed
Add debug output
1 parent 39f150d commit a95b51a

File tree

123 files changed

+22669
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+22669
-3
lines changed

cosmos-sdk-store/CHANGELOG.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<!--
2+
Guiding Principles:
3+
Changelogs are for humans, not machines.
4+
There should be an entry for every single version.
5+
The same types of changes should be grouped.
6+
Versions and sections should be linkable.
7+
The latest version comes first.
8+
The release date of each version is displayed.
9+
Mention whether you follow Semantic Versioning.
10+
Usage:
11+
Change log entries are to be added to the Unreleased section under the
12+
appropriate stanza (see below). Each entry should ideally include a tag and
13+
the Github issue reference in the following format:
14+
* (<tag>) [#<issue-number>] Changelog message.
15+
Types of changes (Stanzas):
16+
"Features" for new features.
17+
"Improvements" for changes in existing functionality.
18+
"Deprecated" for soon-to-be removed features.
19+
"Bug Fixes" for any bug fixes.
20+
"API Breaking" for breaking exported APIs used by developers building on SDK.
21+
Ref: https://keepachangelog.com/en/1.0.0/
22+
-->
23+
24+
# Changelog
25+
26+
## v1.1.0 (March 20, 2024)
27+
28+
### Improvements
29+
30+
* [#19770](https://github.com/cosmos/cosmos-sdk/pull/19770) Upgrade IAVL to IAVL v1.1.1.
31+
32+
## v1.0.2 (January 10, 2024)
33+
34+
### Bug Fixes
35+
36+
* [#18897](https://github.com/cosmos/cosmos-sdk/pull/18897) Replace panic in pruning to avoid consensus halting.
37+
38+
## v1.0.1 (November 28, 2023)
39+
40+
### Bug Fixes
41+
42+
* [#18563](https://github.com/cosmos/cosmos-sdk/pull/18563) `LastCommitID().Hash` will always return `sha256([]byte{})` if the store is empty.
43+
44+
## v1.0.0 (October 31, 2023)
45+
46+
### Features
47+
48+
* [#17294](https://github.com/cosmos/cosmos-sdk/pull/17294) Add snapshot manager Close method.
49+
* [#15568](https://github.com/cosmos/cosmos-sdk/pull/15568) Migrate the `iavl` to the new key format.
50+
* Remove `DeleteVersion`, `DeleteVersions`, `LazyLoadVersionForOverwriting` from `iavl` tree API.
51+
* Add `DeleteVersionsTo` and `SaveChangeSet`, since it will keep versions sequentially like `fromVersion` to `toVersion`.
52+
* Refactor the pruning manager to use `DeleteVersionsTo`.
53+
* [#15712](https://github.com/cosmos/cosmos-sdk/pull/15712) Add `WorkingHash` function to the store interface to get the current app hash before commit.
54+
* [#14645](https://github.com/cosmos/cosmos-sdk/pull/14645) Add limit to the length of key and value.
55+
* [#15683](https://github.com/cosmos/cosmos-sdk/pull/15683) `rootmulti.Store.CacheMultiStoreWithVersion` now can handle loading archival states that don't persist any of the module stores the current state has.
56+
* [#16060](https://github.com/cosmos/cosmos-sdk/pull/16060) Support saving restoring snapshot locally.
57+
* [#14746](https://github.com/cosmos/cosmos-sdk/pull/14746) The `store` module is extracted to have a separate go.mod file which allows it be a standalone module.
58+
* [#14410](https://github.com/cosmos/cosmos-sdk/pull/14410) `rootmulti.Store.loadVersion` has validation to check if all the module stores' height is correct, it will error if any module store has incorrect height.
59+
60+
### Improvements
61+
62+
* [#17158](https://github.com/cosmos/cosmos-sdk/pull/17158) Start the goroutine after need to create a snapshot.
63+
64+
### API Breaking Changes
65+
66+
* [#16321](https://github.com/cosmos/cosmos-sdk/pull/16321) QueryInterface defines its own request and response types instead of relying on comet/abci & returns an error

cosmos-sdk-store/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Cosmos-sdk -> cosmossdk.io/store@v1.0.2
2+
## cosmossdk.io/store@v1.0.2
3+
The version of cosmossdk.io/store@v1.0.2 has an issue we have come across during the upgrade to Cosmoms-sdk 0.50.x
4+
This issue is based on the fact that during the store __Write__ operation not every store gets updated.
5+
As a result when we call
6+
```
7+
func (rs *Store) CacheMultiStoreWithVersion(version int64) (types.CacheMultiStore, error)
8+
```
9+
a call to retrieve __cacheStore__ here:
10+
```
11+
cacheStore, err = store.(*iavl.Store).GetImmutable(version)
12+
```
13+
fails and we cannot process **multistore** queries because they fail with an error:
14+
```
15+
ERR [*] Cache for error="version does not exist" module=server module store=evidence
16+
ERR [*] Cache for error="version does not exist" module=server module store=feegrant
17+
ERR [*] Cache for error="version does not exist" module=server module store=hooks-for-ibc
18+
ERR [*] Cache for error="version does not exist" module=server module store=feeibc
19+
ERR [*] Cache for error="version does not exist" module=server module store=authz
20+
ERR [*] Cache for error="version does not exist" module=server module store=emergencybutton
21+
22+
```
23+
We introduced a fix for __CacheMultiStoreWithVersion__ where we bypass errors for certain modules.
24+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package cache
2+
3+
import (
4+
"testing"
5+
6+
"cosmossdk.io/store/types"
7+
)
8+
9+
func freshMgr() *CommitKVStoreCacheManager {
10+
return &CommitKVStoreCacheManager{
11+
caches: map[string]types.CommitKVStore{
12+
"a1": nil,
13+
"alalalalalal": nil,
14+
},
15+
}
16+
}
17+
18+
func populate(mgr *CommitKVStoreCacheManager) {
19+
mgr.caches["this one"] = (types.CommitKVStore)(nil)
20+
mgr.caches["those ones are the ones"] = (types.CommitKVStore)(nil)
21+
mgr.caches["very huge key right here and there are we going to ones are the ones"] = (types.CommitKVStore)(nil)
22+
}
23+
24+
func BenchmarkReset(b *testing.B) {
25+
b.ReportAllocs()
26+
mgr := freshMgr()
27+
28+
b.ResetTimer()
29+
b.ReportAllocs()
30+
31+
for i := 0; i < b.N; i++ {
32+
mgr.Reset()
33+
if len(mgr.caches) != 0 {
34+
b.Fatal("Reset failed")
35+
}
36+
populate(mgr)
37+
if len(mgr.caches) == 0 {
38+
b.Fatal("populate failed")
39+
}
40+
mgr.Reset()
41+
if len(mgr.caches) != 0 {
42+
b.Fatal("Reset failed")
43+
}
44+
}
45+
46+
if mgr == nil {
47+
b.Fatal("Impossible condition")
48+
}
49+
}

cosmos-sdk-store/cache/cache.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package cache
2+
3+
import (
4+
"fmt"
5+
6+
lru "github.com/hashicorp/golang-lru"
7+
8+
"cosmossdk.io/store/cachekv"
9+
"cosmossdk.io/store/types"
10+
)
11+
12+
var (
13+
_ types.CommitKVStore = (*CommitKVStoreCache)(nil)
14+
_ types.MultiStorePersistentCache = (*CommitKVStoreCacheManager)(nil)
15+
16+
// DefaultCommitKVStoreCacheSize defines the persistent ARC cache size for a
17+
// CommitKVStoreCache.
18+
DefaultCommitKVStoreCacheSize uint = 1000
19+
)
20+
21+
type (
22+
// CommitKVStoreCache implements an inter-block (persistent) cache that wraps a
23+
// CommitKVStore. Reads first hit the internal ARC (Adaptive Replacement Cache).
24+
// During a cache miss, the read is delegated to the underlying CommitKVStore
25+
// and cached. Deletes and writes always happen to both the cache and the
26+
// CommitKVStore in a write-through manner. Caching performed in the
27+
// CommitKVStore and below is completely irrelevant to this layer.
28+
CommitKVStoreCache struct {
29+
types.CommitKVStore
30+
cache *lru.ARCCache
31+
}
32+
33+
// CommitKVStoreCacheManager maintains a mapping from a StoreKey to a
34+
// CommitKVStoreCache. Each CommitKVStore, per StoreKey, is meant to be used
35+
// in an inter-block (persistent) manner and typically provided by a
36+
// CommitMultiStore.
37+
CommitKVStoreCacheManager struct {
38+
cacheSize uint
39+
caches map[string]types.CommitKVStore
40+
}
41+
)
42+
43+
func NewCommitKVStoreCache(store types.CommitKVStore, size uint) *CommitKVStoreCache {
44+
cache, err := lru.NewARC(int(size))
45+
if err != nil {
46+
panic(fmt.Errorf("failed to create KVStore cache: %s", err))
47+
}
48+
49+
return &CommitKVStoreCache{
50+
CommitKVStore: store,
51+
cache: cache,
52+
}
53+
}
54+
55+
func NewCommitKVStoreCacheManager(size uint) *CommitKVStoreCacheManager {
56+
return &CommitKVStoreCacheManager{
57+
cacheSize: size,
58+
caches: make(map[string]types.CommitKVStore),
59+
}
60+
}
61+
62+
// GetStoreCache returns a Cache from the CommitStoreCacheManager for a given
63+
// StoreKey. If no Cache exists for the StoreKey, then one is created and set.
64+
// The returned Cache is meant to be used in a persistent manner.
65+
func (cmgr *CommitKVStoreCacheManager) GetStoreCache(key types.StoreKey, store types.CommitKVStore) types.CommitKVStore {
66+
if cmgr.caches[key.Name()] == nil {
67+
cmgr.caches[key.Name()] = NewCommitKVStoreCache(store, cmgr.cacheSize)
68+
}
69+
70+
return cmgr.caches[key.Name()]
71+
}
72+
73+
// Unwrap returns the underlying CommitKVStore for a given StoreKey.
74+
func (cmgr *CommitKVStoreCacheManager) Unwrap(key types.StoreKey) types.CommitKVStore {
75+
if ckv, ok := cmgr.caches[key.Name()]; ok {
76+
return ckv.(*CommitKVStoreCache).CommitKVStore
77+
}
78+
79+
return nil
80+
}
81+
82+
// Reset resets in the internal caches.
83+
func (cmgr *CommitKVStoreCacheManager) Reset() {
84+
// Clear the map.
85+
// Please note that we are purposefully using the map clearing idiom.
86+
// See https://github.com/cosmos/cosmos-sdk/issues/6681.
87+
for key := range cmgr.caches {
88+
delete(cmgr.caches, key)
89+
}
90+
}
91+
92+
// CacheWrap implements the CacheWrapper interface
93+
func (ckv *CommitKVStoreCache) CacheWrap() types.CacheWrap {
94+
return cachekv.NewStore(ckv)
95+
}
96+
97+
// Get retrieves a value by key. It will first look in the write-through cache.
98+
// If the value doesn't exist in the write-through cache, the query is delegated
99+
// to the underlying CommitKVStore.
100+
func (ckv *CommitKVStoreCache) Get(key []byte) []byte {
101+
types.AssertValidKey(key)
102+
103+
keyStr := string(key)
104+
valueI, ok := ckv.cache.Get(keyStr)
105+
if ok {
106+
// cache hit
107+
return valueI.([]byte)
108+
}
109+
110+
// cache miss; write to cache
111+
value := ckv.CommitKVStore.Get(key)
112+
ckv.cache.Add(keyStr, value)
113+
114+
return value
115+
}
116+
117+
// Set inserts a key/value pair into both the write-through cache and the
118+
// underlying CommitKVStore.
119+
func (ckv *CommitKVStoreCache) Set(key, value []byte) {
120+
types.AssertValidKey(key)
121+
types.AssertValidValue(value)
122+
123+
ckv.cache.Add(string(key), value)
124+
ckv.CommitKVStore.Set(key, value)
125+
}
126+
127+
// Delete removes a key/value pair from both the write-through cache and the
128+
// underlying CommitKVStore.
129+
func (ckv *CommitKVStoreCache) Delete(key []byte) {
130+
ckv.cache.Remove(string(key))
131+
ckv.CommitKVStore.Delete(key)
132+
}

cosmos-sdk-store/cache/cache_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package cache_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
dbm "github.com/cosmos/cosmos-db"
8+
"github.com/cosmos/iavl"
9+
"github.com/stretchr/testify/require"
10+
11+
"cosmossdk.io/log"
12+
"cosmossdk.io/store/cache"
13+
"cosmossdk.io/store/cachekv"
14+
iavlstore "cosmossdk.io/store/iavl"
15+
"cosmossdk.io/store/types"
16+
"cosmossdk.io/store/wrapper"
17+
)
18+
19+
func TestGetOrSetStoreCache(t *testing.T) {
20+
db := wrapper.NewDBWrapper(dbm.NewMemDB())
21+
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)
22+
23+
sKey := types.NewKVStoreKey("test")
24+
tree := iavl.NewMutableTree(db, 100, false, log.NewNopLogger())
25+
store := iavlstore.UnsafeNewStore(tree)
26+
store2 := mngr.GetStoreCache(sKey, store)
27+
28+
require.NotNil(t, store2)
29+
require.Equal(t, store2, mngr.GetStoreCache(sKey, store))
30+
}
31+
32+
func TestUnwrap(t *testing.T) {
33+
db := wrapper.NewDBWrapper(dbm.NewMemDB())
34+
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)
35+
36+
sKey := types.NewKVStoreKey("test")
37+
tree := iavl.NewMutableTree(db, 100, false, log.NewNopLogger())
38+
store := iavlstore.UnsafeNewStore(tree)
39+
_ = mngr.GetStoreCache(sKey, store)
40+
41+
require.Equal(t, store, mngr.Unwrap(sKey))
42+
require.Nil(t, mngr.Unwrap(types.NewKVStoreKey("test2")))
43+
}
44+
45+
func TestStoreCache(t *testing.T) {
46+
db := wrapper.NewDBWrapper(dbm.NewMemDB())
47+
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)
48+
49+
sKey := types.NewKVStoreKey("test")
50+
tree := iavl.NewMutableTree(db, 100, false, log.NewNopLogger())
51+
store := iavlstore.UnsafeNewStore(tree)
52+
kvStore := mngr.GetStoreCache(sKey, store)
53+
54+
for i := uint(0); i < cache.DefaultCommitKVStoreCacheSize*2; i++ {
55+
key := []byte(fmt.Sprintf("key_%d", i))
56+
value := []byte(fmt.Sprintf("value_%d", i))
57+
58+
kvStore.Set(key, value)
59+
60+
res := kvStore.Get(key)
61+
require.Equal(t, res, value)
62+
require.Equal(t, res, store.Get(key))
63+
64+
kvStore.Delete(key)
65+
66+
require.Nil(t, kvStore.Get(key))
67+
require.Nil(t, store.Get(key))
68+
}
69+
}
70+
71+
func TestReset(t *testing.T) {
72+
db := wrapper.NewDBWrapper(dbm.NewMemDB())
73+
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)
74+
75+
sKey := types.NewKVStoreKey("test")
76+
tree := iavl.NewMutableTree(db, 100, false, log.NewNopLogger())
77+
store := iavlstore.UnsafeNewStore(tree)
78+
store2 := mngr.GetStoreCache(sKey, store)
79+
80+
require.NotNil(t, store2)
81+
require.Equal(t, store2, mngr.GetStoreCache(sKey, store))
82+
83+
// reset and check if the cache is gone
84+
mngr.Reset()
85+
require.Nil(t, mngr.Unwrap(sKey))
86+
87+
// check if the cache is recreated
88+
require.Equal(t, store2, mngr.GetStoreCache(sKey, store))
89+
}
90+
91+
func TestCacheWrap(t *testing.T) {
92+
db := wrapper.NewDBWrapper(dbm.NewMemDB())
93+
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)
94+
95+
sKey := types.NewKVStoreKey("test")
96+
tree := iavl.NewMutableTree(db, 100, false, log.NewNopLogger())
97+
store := iavlstore.UnsafeNewStore(tree)
98+
99+
cacheWrapper := mngr.GetStoreCache(sKey, store).CacheWrap()
100+
require.IsType(t, &cachekv.Store{}, cacheWrapper)
101+
}

0 commit comments

Comments
 (0)