From 6912382065f3f4c4a60b10f09a625360aafb7bdf Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Tue, 16 Nov 2021 23:03:25 +0100 Subject: [PATCH 1/5] add configurable iavl cache size --- baseapp/baseapp.go | 7 +++++++ baseapp/options.go | 13 +++++++++---- server/config/config.go | 3 +++ server/config/toml.go | 4 ++++ server/mock/store.go | 3 +++ store/iavl/store.go | 10 +++++----- store/iavl/store_test.go | 6 +++--- store/rootmulti/proof_test.go | 2 +- store/rootmulti/store.go | 26 ++++++++++++++++---------- store/types/iterator_test.go | 2 +- store/types/store.go | 3 +++ 11 files changed, 55 insertions(+), 24 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 07713ef4fe24..057ad569fdfa 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -126,6 +126,9 @@ type BaseApp struct { // nolint: maligned // which informs Tendermint what to index. If empty, all events will be indexed. indexEvents map[string]struct{} + // IAVL cache size. Setting this value will set the desired cache size on the iavl tree + iavlCacheSize int + // abciListeners for hooking into the ABCI message processing of the BaseApp // and exposing the requests and responses to external consumers abciListeners []ABCIListener @@ -341,6 +344,10 @@ func (app *BaseApp) setIndexEvents(ie []string) { } } +func (app *BaseApp) setIAVLCacheSize(size int) { + app.iavlCacheSize = size +} + // QueryRouter returns the QueryRouter of a BaseApp. func (app *BaseApp) QueryRouter() sdk.QueryRouter { return app.queryRouter } diff --git a/baseapp/options.go b/baseapp/options.go index 1d74d1229c3f..1d92698d7fa9 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -18,7 +18,7 @@ import ( // SetPruning sets a pruning option on the multistore associated with the app func SetPruning(opts sdk.PruningOptions) func(*BaseApp) { - return func(bap *BaseApp) { bap.cms.SetPruning(opts) } + return func(bapp *BaseApp) { bapp.cms.SetPruning(opts) } } // SetMinGasPrices returns an option that sets the minimum gas prices on the app. @@ -28,17 +28,17 @@ func SetMinGasPrices(gasPricesStr string) func(*BaseApp) { panic(fmt.Sprintf("invalid minimum gas prices: %v", err)) } - return func(bap *BaseApp) { bap.setMinGasPrices(gasPrices) } + return func(bapp *BaseApp) { bapp.setMinGasPrices(gasPrices) } } // SetHaltHeight returns a BaseApp option function that sets the halt block height. func SetHaltHeight(blockHeight uint64) func(*BaseApp) { - return func(bap *BaseApp) { bap.setHaltHeight(blockHeight) } + return func(bapp *BaseApp) { bapp.setHaltHeight(blockHeight) } } // SetHaltTime returns a BaseApp option function that sets the halt block time. func SetHaltTime(haltTime uint64) func(*BaseApp) { - return func(bap *BaseApp) { bap.setHaltTime(haltTime) } + return func(bapp *BaseApp) { bapp.setHaltTime(haltTime) } } // SetMinRetainBlocks returns a BaseApp option function that sets the minimum @@ -58,6 +58,11 @@ func SetIndexEvents(ie []string) func(*BaseApp) { return func(app *BaseApp) { app.setIndexEvents(ie) } } +// SetIAVLCacheSize provides a BaseApp option function that sets the size of IAVL cache. +func SetIAVLCacheSize(size int) func(*BaseApp) { + return func(bapp *BaseApp) { bapp.cms.SetIAVLCacheSize(size) } +} + // SetInterBlockCache provides a BaseApp option function that sets the // inter-block cache. func SetInterBlockCache(cache sdk.MultiStorePersistentCache) func(*BaseApp) { diff --git a/server/config/config.go b/server/config/config.go index b3d8a99cf6fe..c24c677b80ee 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -69,6 +69,8 @@ type BaseConfig struct { // IndexEvents defines the set of events in the form {eventType}.{attributeKey}, // which informs Tendermint what to index. If empty, all events will be indexed. IndexEvents []string `mapstructure:"index-events"` + // IavlCacheSize set the size of the iavl tree cache. + IAVLCacheSize uint64 `mapstructure:"iavl-cache-size"` } // APIConfig defines the API listener configuration. @@ -209,6 +211,7 @@ func DefaultConfig() *Config { PruningInterval: "0", MinRetainBlocks: 0, IndexEvents: make([]string, 0), + IAVLCacheSize: 50000000, // 50 MB }, Telemetry: telemetry.Config{ Enabled: false, diff --git a/server/config/toml.go b/server/config/toml.go index 785eac72effd..9b4cbfc5ef12 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -72,6 +72,10 @@ inter-block-cache = {{ .BaseConfig.InterBlockCache }} # ["message.sender", "message.recipient"] index-events = [{{ range .BaseConfig.IndexEvents }}{{ printf "%q, " . }}{{end}}] +# IavlCacheSize set the size of the iavl tree cache. +# Default cache size is 50mb. +iavl-cache-size = {{ .BaseConfig.IavlCacheSize }} + ############################################################################### ### Telemetry Configuration ### ############################################################################### diff --git a/server/mock/store.go b/server/mock/store.go index 91596337f964..cf67e088fe77 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -114,6 +114,9 @@ func (ms multiStore) GetStoreType() storetypes.StoreType { func (ms multiStore) SetInterBlockCache(_ sdk.MultiStorePersistentCache) { panic("not implemented") } +func (ms multiStore) SetIAVLCacheSize(size int) { + panic("not implemented") +} func (ms multiStore) SetInitialVersion(version int64) error { panic("not implemented") diff --git a/store/iavl/store.go b/store/iavl/store.go index 79960d8b9866..df01d9750b18 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -22,7 +22,7 @@ import ( ) const ( - defaultIAVLCacheSize = 10000 + DefaultIAVLCacheSize = 10000 ) var ( @@ -41,16 +41,16 @@ type Store struct { // LoadStore returns an IAVL Store as a CommitKVStore. Internally, it will load the // store's version (id) from the provided DB. An error is returned if the version // fails to load, or if called with a positive version on an empty tree. -func LoadStore(db dbm.DB, id types.CommitID, lazyLoading bool) (types.CommitKVStore, error) { - return LoadStoreWithInitialVersion(db, id, lazyLoading, 0) +func LoadStore(db dbm.DB, id types.CommitID, lazyLoading bool, cacheSize int) (types.CommitKVStore, error) { + return LoadStoreWithInitialVersion(db, id, lazyLoading, 0, cacheSize) } // LoadStoreWithInitialVersion returns an IAVL Store as a CommitKVStore setting its initialVersion // to the one given. Internally, it will load the store's version (id) from the // provided DB. An error is returned if the version fails to load, or if called with a positive // version on an empty tree. -func LoadStoreWithInitialVersion(db dbm.DB, id types.CommitID, lazyLoading bool, initialVersion uint64) (types.CommitKVStore, error) { - tree, err := iavl.NewMutableTreeWithOpts(db, defaultIAVLCacheSize, &iavl.Options{InitialVersion: initialVersion}) +func LoadStoreWithInitialVersion(db dbm.DB, id types.CommitID, lazyLoading bool, initialVersion uint64, cacheSize int) (types.CommitKVStore, error) { + tree, err := iavl.NewMutableTreeWithOpts(db, cacheSize, &iavl.Options{InitialVersion: initialVersion}) if err != nil { return nil, err } diff --git a/store/iavl/store_test.go b/store/iavl/store_test.go index 26cf27db8bf0..b9c9e25ad43d 100644 --- a/store/iavl/store_test.go +++ b/store/iavl/store_test.go @@ -93,17 +93,17 @@ func TestLoadStore(t *testing.T) { require.Equal(t, string(hcStore.Get([]byte("hello"))), "ciao") // Querying a new store at some previous non-pruned height H - newHStore, err := LoadStore(db, cIDH, false) + newHStore, err := LoadStore(db, cIDH, false, DefaultIAVLCacheSize) require.NoError(t, err) require.Equal(t, string(newHStore.Get([]byte("hello"))), "hallo") // Querying a new store at some previous pruned height Hp - newHpStore, err := LoadStore(db, cIDHp, false) + newHpStore, err := LoadStore(db, cIDHp, false, DefaultIAVLCacheSize) require.NoError(t, err) require.Equal(t, string(newHpStore.Get([]byte("hello"))), "hola") // Querying a new store at current height H - newHcStore, err := LoadStore(db, cIDHc, false) + newHcStore, err := LoadStore(db, cIDHc, false, DefaultIAVLCacheSize) require.NoError(t, err) require.Equal(t, string(newHcStore.Get([]byte("hello"))), "ciao") } diff --git a/store/rootmulti/proof_test.go b/store/rootmulti/proof_test.go index f0bd29063ad1..10f8397e7284 100644 --- a/store/rootmulti/proof_test.go +++ b/store/rootmulti/proof_test.go @@ -14,7 +14,7 @@ import ( func TestVerifyIAVLStoreQueryProof(t *testing.T) { // Create main tree for testing. db := dbm.NewMemDB() - iStore, err := iavl.LoadStore(db, types.CommitID{}, false) + iStore, err := iavl.LoadStore(db, types.CommitID{}, false, iavl.DefaultIAVLCacheSize) store := iStore.(*iavl.Store) require.Nil(t, err) store.Set([]byte("MYKEY"), []byte("MYVALUE")) diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index a8b4b770c032..fd4bc84ac2aa 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -48,6 +48,7 @@ type Store struct { db dbm.DB lastCommitInfo *types.CommitInfo pruningOpts types.PruningOptions + iavlCacheSize int storesParams map[types.StoreKey]storeParams stores map[types.StoreKey]types.CommitKVStore keysByName map[string]types.StoreKey @@ -75,14 +76,15 @@ var ( // LoadVersion must be called. func NewStore(db dbm.DB) *Store { return &Store{ - db: db, - pruningOpts: types.PruneNothing, - storesParams: make(map[types.StoreKey]storeParams), - stores: make(map[types.StoreKey]types.CommitKVStore), - keysByName: make(map[string]types.StoreKey), - pruneHeights: make([]int64, 0), - listeners: make(map[types.StoreKey][]types.WriteListener), - removalMap: make(map[types.StoreKey]bool), + db: db, + pruningOpts: types.PruneNothing, + iavlCacheSize: iavl.DefaultIAVLCacheSize, + storesParams: make(map[types.StoreKey]storeParams), + stores: make(map[types.StoreKey]types.CommitKVStore), + keysByName: make(map[string]types.StoreKey), + pruneHeights: make([]int64, 0), + listeners: make(map[types.StoreKey][]types.WriteListener), + removalMap: make(map[types.StoreKey]bool), } } @@ -98,6 +100,10 @@ func (rs *Store) SetPruning(pruningOpts types.PruningOptions) { rs.pruningOpts = pruningOpts } +func (rs *Store) SetIAVLCacheSize(cacheSize int) { + rs.iavlCacheSize = cacheSize +} + // SetLazyLoading sets if the iavl store should be loaded lazily or not func (rs *Store) SetLazyLoading(lazyLoading bool) { rs.lazyLoading = lazyLoading @@ -895,9 +901,9 @@ func (rs *Store) loadCommitStoreFromParams(key types.StoreKey, id types.CommitID var err error if params.initialVersion == 0 { - store, err = iavl.LoadStore(db, id, rs.lazyLoading) + store, err = iavl.LoadStore(db, id, rs.lazyLoading, rs.iavlCacheSize) } else { - store, err = iavl.LoadStoreWithInitialVersion(db, id, rs.lazyLoading, params.initialVersion) + store, err = iavl.LoadStoreWithInitialVersion(db, id, rs.lazyLoading, params.initialVersion, rs.iavlCacheSize) } if err != nil { diff --git a/store/types/iterator_test.go b/store/types/iterator_test.go index 3086917b605b..686aa1123708 100644 --- a/store/types/iterator_test.go +++ b/store/types/iterator_test.go @@ -12,7 +12,7 @@ import ( func newMemTestKVStore(t *testing.T) types.KVStore { db := dbm.NewMemDB() - store, err := iavl.LoadStore(db, types.CommitID{}, false) + store, err := iavl.LoadStore(db, types.CommitID{}, false, iavl.DefaultIAVLCacheSize) require.NoError(t, err) return store } diff --git a/store/types/store.go b/store/types/store.go index aa04a2447579..7af13914bc89 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -181,6 +181,9 @@ type CommitMultiStore interface { // SetInitialVersion sets the initial version of the IAVL tree. It is used when // starting a new chain at an arbitrary height. SetInitialVersion(version int64) error + + // SetIAVLCacheSize sets the cache size of the IAVL tree. + SetIAVLCacheSize(size int) } //---------subsp------------------------------- From e9b728890bfe115b11a6950a534d98dbad49d9d2 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Tue, 16 Nov 2021 23:08:51 +0100 Subject: [PATCH 2/5] remove set on baseapp --- baseapp/baseapp.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 057ad569fdfa..2b7e80835a1f 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -344,10 +344,6 @@ func (app *BaseApp) setIndexEvents(ie []string) { } } -func (app *BaseApp) setIAVLCacheSize(size int) { - app.iavlCacheSize = size -} - // QueryRouter returns the QueryRouter of a BaseApp. func (app *BaseApp) QueryRouter() sdk.QueryRouter { return app.queryRouter } From 8527b77b382d4cbfc232d73fffaf2c809e4b981c Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Tue, 16 Nov 2021 23:13:51 +0100 Subject: [PATCH 3/5] remove unneeded field --- baseapp/baseapp.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 2b7e80835a1f..07713ef4fe24 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -126,9 +126,6 @@ type BaseApp struct { // nolint: maligned // which informs Tendermint what to index. If empty, all events will be indexed. indexEvents map[string]struct{} - // IAVL cache size. Setting this value will set the desired cache size on the iavl tree - iavlCacheSize int - // abciListeners for hooking into the ABCI message processing of the BaseApp // and exposing the requests and responses to external consumers abciListeners []ABCIListener From ade66f81832a21c216d71aff838c44d4ef89f6a9 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Wed, 17 Nov 2021 10:33:29 +0100 Subject: [PATCH 4/5] add changelog --- CHANGELOG.md | 1 + server/config/config.go | 2 +- store/iavl/store.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3e0868081a..e2f8d66961e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) Add `fee.{payer,granter}` and `tip` fields to StdSignDoc for signing tipped transactions. * [\#10208](https://github.com/cosmos/cosmos-sdk/pull/10208) Add `TipsTxMiddleware` for transferring tips. * [\#10379](https://github.com/cosmos/cosmos-sdk/pull/10379) Add validation to `x/upgrade` CLI `software-upgrade` command `--plan-info` value. +* [\#10561](https://github.com/cosmos/cosmos-sdk/pull/10561) Add configurable IAVL cache size to app.toml ### Improvements diff --git a/server/config/config.go b/server/config/config.go index c24c677b80ee..f5a395dce8e0 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -211,7 +211,7 @@ func DefaultConfig() *Config { PruningInterval: "0", MinRetainBlocks: 0, IndexEvents: make([]string, 0), - IAVLCacheSize: 50000000, // 50 MB + IAVLCacheSize: 781250, // 50 MB }, Telemetry: telemetry.Config{ Enabled: false, diff --git a/store/iavl/store.go b/store/iavl/store.go index df01d9750b18..50702da585c8 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -22,7 +22,7 @@ import ( ) const ( - DefaultIAVLCacheSize = 10000 + DefaultIAVLCacheSize = 500000 ) var ( From dc9994b638b53b3f9a16e2fdce5a91112518207a Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Wed, 17 Nov 2021 11:57:11 +0100 Subject: [PATCH 5/5] fix spelling --- server/config/toml.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/config/toml.go b/server/config/toml.go index 9b4cbfc5ef12..1fe85947049c 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -74,7 +74,7 @@ index-events = [{{ range .BaseConfig.IndexEvents }}{{ printf "%q, " . }}{{end}}] # IavlCacheSize set the size of the iavl tree cache. # Default cache size is 50mb. -iavl-cache-size = {{ .BaseConfig.IavlCacheSize }} +iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }} ############################################################################### ### Telemetry Configuration ###