diff --git a/CHANGELOG.md b/CHANGELOG.md index dcb30a298c56..6940a81dd72e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,14 +42,15 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#13369](https://github.com/cosmos/cosmos-sdk/pull/13369) Improve UX for `keyring.List` by returning all retrieved keys. * [#13323](https://github.com/cosmos/cosmos-sdk/pull/13323) Ensure `withdraw_rewards` rewards are emitted from all actions that result in rewards being withdrawn. * [#13321](https://github.com/cosmos/cosmos-sdk/pull/13321) Add flag to disable fast node migration and usage. +* (store) [#13326](https://github.com/cosmos/cosmos-sdk/pull/13326) Implementation of ADR-038 file StreamingService, backport #8664. ### API Breaking Changes - (cli) [#13089](https://github.com/cosmos/cosmos-sdk/pull/13089) Fix rollback command don't actually delete multistore versions, added method `RollbackToVersion` to interface `CommitMultiStore` and added method `CommitMultiStore` to `Application` interface. -### Improvements +### Bug Fixes -* (store) [\#13326](https://github.com/cosmos/cosmos-sdk/pull/13326) Implementation of ADR-038 file StreamingService, backport #8664 +* (store) [#13459](https://github.com/cosmos/cosmos-sdk/pull/13459) Don't let state listener observe the uncommitted writes. ## v0.45.8 - 2022-08-25 diff --git a/store/cachemulti/store.go b/store/cachemulti/store.go index 1a05a064536d..d64dc03aca12 100644 --- a/store/cachemulti/store.go +++ b/store/cachemulti/store.go @@ -41,6 +41,9 @@ func NewFromKVStore( keys map[string]types.StoreKey, traceWriter io.Writer, traceContext types.TraceContext, listeners map[types.StoreKey][]types.WriteListener, ) Store { + if listeners == nil { + listeners = make(map[types.StoreKey][]types.WriteListener) + } cms := Store{ db: cachekv.NewStore(store), stores: make(map[types.StoreKey]types.CacheWrap, len(stores)), @@ -78,7 +81,8 @@ func newCacheMultiStoreFromCMS(cms Store) Store { stores[k] = v } - return NewFromKVStore(cms.db, stores, nil, cms.traceWriter, cms.traceContext, cms.listeners) + // don't pass listeners to nested cache store. + return NewFromKVStore(cms.db, stores, nil, cms.traceWriter, cms.traceContext, nil) } // SetTracer sets the tracer for the MultiStore that the underlying diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index 428c243ab7a0..26f4e8a36cca 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -813,3 +813,52 @@ func hashStores(stores map[types.StoreKey]types.CommitKVStore) []byte { } return sdkmaps.HashFromMap(m) } + +type MockListener struct { + stateCache []types.StoreKVPair +} + +func (tl *MockListener) OnWrite(storeKey types.StoreKey, key []byte, value []byte, delete bool) error { + tl.stateCache = append(tl.stateCache, types.StoreKVPair{ + StoreKey: storeKey.Name(), + Key: key, + Value: value, + Delete: delete, + }) + return nil +} + +func TestStateListeners(t *testing.T) { + var db dbm.DB = dbm.NewMemDB() + ms := newMultiStoreWithMounts(db, types.NewPruningOptionsFromString(types.PruningOptionNothing)) + + listener := &MockListener{} + ms.AddListeners(testStoreKey1, []types.WriteListener{listener}) + + require.NoError(t, ms.LoadLatestVersion()) + cacheMulti := ms.CacheMultiStore() + + store1 := cacheMulti.GetKVStore(testStoreKey1) + store1.Set([]byte{1}, []byte{1}) + require.Empty(t, listener.stateCache) + + // writes are observed when cache store commit. + cacheMulti.Write() + require.Equal(t, 1, len(listener.stateCache)) + + // test nested cache store + listener.stateCache = []types.StoreKVPair{} + nested := cacheMulti.CacheMultiStore() + + store1 = nested.GetKVStore(testStoreKey1) + store1.Set([]byte{1}, []byte{1}) + require.Empty(t, listener.stateCache) + + // writes are not observed when nested cache store commit + nested.Write() + require.Empty(t, listener.stateCache) + + // writes are observed when inner cache store commit + cacheMulti.Write() + require.Equal(t, 1, len(listener.stateCache)) +} diff --git a/store/streaming/file/service_test.go b/store/streaming/file/service_test.go index 46f1434beeb2..6ecad254b5ce 100644 --- a/store/streaming/file/service_test.go +++ b/store/streaming/file/service_test.go @@ -127,7 +127,7 @@ func TestFileStreamingService(t *testing.T) { if os.Getenv("CI") != "" { t.Skip("Skipping TestFileStreamingService in CI environment") } - err := os.Mkdir(testDir, 0700) + err := os.Mkdir(testDir, 0o700) require.Nil(t, err) defer os.RemoveAll(testDir) diff --git a/types/tx/types.go b/types/tx/types.go index 804f70210bc7..8c10b5699281 100644 --- a/types/tx/types.go +++ b/types/tx/types.go @@ -13,8 +13,10 @@ import ( const MaxGasWanted = uint64((1 << 63) - 1) // Interface implementation checks. -var _, _, _, _ codectypes.UnpackInterfacesMessage = &Tx{}, &TxBody{}, &AuthInfo{}, &SignerInfo{} -var _ sdk.Tx = &Tx{} +var ( + _, _, _, _ codectypes.UnpackInterfacesMessage = &Tx{}, &TxBody{}, &AuthInfo{}, &SignerInfo{} + _ sdk.Tx = &Tx{} +) // GetMsgs implements the GetMsgs method on sdk.Tx. func (t *Tx) GetMsgs() []sdk.Msg {