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: configurable fastnode #13321

Merged
merged 11 commits into from Sep 20, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -87,6 +87,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#13233](https://github.com/cosmos/cosmos-sdk/pull/13233) Add `--append` to `add-genesis-account` sub-command to append new tokens after an account is already created.
* [#13236](https://github.com/cosmos/cosmos-sdk/pull/13236) Integrate Filter Logging
* [#13301](https://github.com/cosmos/cosmos-sdk/pull/13301) Keep the balance query endpoint compatible with legacy blocks
* [#13321](https://github.com/cosmos/cosmos-sdk/pull/13321) Add flag to disable fast node migration and usage.

### State Machine Breaking

Expand Down
5 changes: 5 additions & 0 deletions baseapp/options.go
Expand Up @@ -64,6 +64,11 @@ func SetIAVLCacheSize(size int) func(*BaseApp) {
return func(bapp *BaseApp) { bapp.cms.SetIAVLCacheSize(size) }
}

// SetIAVLDisableFastNode enables(false)/disables(true) fast node usage from the IAVL store.
func SetIAVLDisableFastNode(disable bool) func(*BaseApp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: godoc. What does true or false mean :p

return func(bapp *BaseApp) { bapp.cms.SetIAVLDisableFastNode(disable) }
}

// SetInterBlockCache provides a BaseApp option function that sets the
// inter-block cache.
func SetInterBlockCache(cache sdk.MultiStorePersistentCache) func(*BaseApp) {
Expand Down
Expand Up @@ -25,7 +25,7 @@ func FuzzStoreInternalProofsCreateNonmembershipProof(f *testing.F) {
if len(sz.Data) == 0 || len(sz.Key) == 0 {
return
}
tree, err := iavl.NewMutableTree(db.NewMemDB(), 0)
tree, err := iavl.NewMutableTree(db.NewMemDB(), 0, false)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -21,7 +21,7 @@ require (
github.com/cosmos/cosmos-sdk/store/tools/ics23 v0.0.0-20220820010601-dc361be9e3ff
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/gogoproto v1.4.2
github.com/cosmos/iavl v0.19.1
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313
github.com/cosmos/ledger-cosmos-go v0.11.1
github.com/gogo/gateway v1.1.0
github.com/golang/mock v1.6.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -194,8 +194,8 @@ github.com/cosmos/gogoproto v1.4.2 h1:UeGRcmFW41l0G0MiefWhkPEVEwvu78SZsHBvI78dAY
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y=
github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw=
github.com/cosmos/iavl v0.19.1 h1:3gaq9b6SjiB0KBTygRnAvEGml2pQlu1TH8uma5g63Ys=
github.com/cosmos/iavl v0.19.1/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313 h1:R7CnaI/0OLwOusy7n9750n8fqQ3yCQ8OJQI2L3ws9RA=
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo=
github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
Expand Down
46 changes: 26 additions & 20 deletions server/config/config.go
Expand Up @@ -81,9 +81,13 @@ 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"`

// IAVLDisableFastnNode enables or disables the fast sync node.
IAVLDisableFastnNode bool `mapstructure:"iavl-disable-fastnode"`

// AppDBBackend defines the type of Database to use for the application and snapshots databases.
// An empty string indicates that the Tendermint config's DBBackend value should be used.
AppDBBackend string `mapstructure:"app-db-backend"`
Expand Down Expand Up @@ -236,15 +240,16 @@ func (c *Config) GetMinGasPrices() sdk.DecCoins {
func DefaultConfig() *Config {
return &Config{
BaseConfig: BaseConfig{
MinGasPrices: defaultMinGasPrices,
InterBlockCache: true,
Pruning: pruningtypes.PruningOptionDefault,
PruningKeepRecent: "0",
PruningInterval: "0",
MinRetainBlocks: 0,
IndexEvents: make([]string, 0),
IAVLCacheSize: 781250, // 50 MB
AppDBBackend: "",
MinGasPrices: defaultMinGasPrices,
InterBlockCache: true,
Pruning: pruningtypes.PruningOptionDefault,
PruningKeepRecent: "0",
PruningInterval: "0",
MinRetainBlocks: 0,
IndexEvents: make([]string, 0),
IAVLCacheSize: 781250, // 50 MB
IAVLDisableFastnNode: false,
AppDBBackend: "",
},
Telemetry: telemetry.Config{
Enabled: false,
Expand Down Expand Up @@ -306,17 +311,18 @@ func GetConfig(v *viper.Viper) (Config, error) {

return Config{
BaseConfig: BaseConfig{
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
IndexEvents: v.GetStringSlice("index-events"),
MinRetainBlocks: v.GetUint64("min-retain-blocks"),
IAVLCacheSize: v.GetUint64("iavl-cache-size"),
AppDBBackend: v.GetString("app-db-backend"),
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
IndexEvents: v.GetStringSlice("index-events"),
MinRetainBlocks: v.GetUint64("min-retain-blocks"),
IAVLCacheSize: v.GetUint64("iavl-cache-size"),
IAVLDisableFastnNode: v.GetBool("iavl-disable-fastnode"),
AppDBBackend: v.GetString("app-db-backend"),
},
Telemetry: telemetry.Config{
ServiceName: v.GetString("telemetry.service-name"),
Expand Down
4 changes: 4 additions & 0 deletions server/config/toml.go
Expand Up @@ -74,6 +74,10 @@ index-events = [{{ range .BaseConfig.IndexEvents }}{{ printf "%q, " . }}{{end}}]
# Default cache size is 50mb.
iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }}

# IavlDisableFastnNode enables or disables the fast node feature of IAVL.
# Default is false.
iavl-disable-fastnode = {{ .BaseConfig.IAVLDisableFastnNode }}

# AppDBBackend defines the database backend type to use for the application and snapshots DBs.
# An empty string indicates that a fallback will be used.
# First fallback is the deprecated compile-time types.DBBackend value.
Expand Down
4 changes: 4 additions & 0 deletions server/mock/store.go
Expand Up @@ -130,6 +130,10 @@ func (ms multiStore) SetIAVLCacheSize(size int) {
panic("not implemented")
}

func (ms multiStore) SetIAVLDisableFastNode(disable bool) {
panic("not implemented")
}

func (ms multiStore) SetInitialVersion(version int64) error {
panic("not implemented")
}
Expand Down
1 change: 1 addition & 0 deletions server/start.go
Expand Up @@ -56,6 +56,7 @@ const (
FlagIndexEvents = "index-events"
FlagMinRetainBlocks = "min-retain-blocks"
FlagIAVLCacheSize = "iavl-cache-size"
FlagIAVLFastNode = "iavl-disable-fastnode"

// state sync-related flags
FlagStateSyncSnapshotInterval = "state-sync.snapshot-interval"
Expand Down
2 changes: 1 addition & 1 deletion simapp/go.mod
Expand Up @@ -45,7 +45,7 @@ require (
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogoproto v1.4.2 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/iavl v0.19.1 // indirect
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313 // indirect
github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect
github.com/creachadair/taskgroup v0.3.2 // indirect
Expand Down
4 changes: 2 additions & 2 deletions simapp/go.sum
Expand Up @@ -190,8 +190,8 @@ github.com/cosmos/gogoproto v1.4.2 h1:UeGRcmFW41l0G0MiefWhkPEVEwvu78SZsHBvI78dAY
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y=
github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw=
github.com/cosmos/iavl v0.19.1 h1:3gaq9b6SjiB0KBTygRnAvEGml2pQlu1TH8uma5g63Ys=
github.com/cosmos/iavl v0.19.1/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313 h1:R7CnaI/0OLwOusy7n9750n8fqQ3yCQ8OJQI2L3ws9RA=
github.com/cosmos/iavl v0.19.2-0.20220916140702-9b6be3095313/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo=
github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
Expand Down
2 changes: 2 additions & 0 deletions simapp/simd/cmd/root.go
Expand Up @@ -145,6 +145,7 @@ func initAppConfig() (string, interface{}) {
//
// In simapp, we set the min gas prices to 0.
srvCfg.MinGasPrices = "0stake"
// srvCfg.BaseConfig.IAVLDisableFastnNode = true // disable fastnode by default

customAppConfig := CustomAppConfig{
Config: *srvCfg,
Expand Down Expand Up @@ -304,6 +305,7 @@ func newApp(
baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))),
baseapp.SetSnapshot(snapshotStore, snapshotOptions),
baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))),
baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagIAVLFastNode))),
)
}

Expand Down
6 changes: 3 additions & 3 deletions store/cache/cache_test.go
Expand Up @@ -18,7 +18,7 @@ func TestGetOrSetStoreCache(t *testing.T) {
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)

sKey := types.NewKVStoreKey("test")
tree, err := iavl.NewMutableTree(db, 100)
tree, err := iavl.NewMutableTree(db, 100, false)
require.NoError(t, err)
store := iavlstore.UnsafeNewStore(tree)
store2 := mngr.GetStoreCache(sKey, store)
Expand All @@ -32,7 +32,7 @@ func TestUnwrap(t *testing.T) {
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)

sKey := types.NewKVStoreKey("test")
tree, err := iavl.NewMutableTree(db, 100)
tree, err := iavl.NewMutableTree(db, 100, false)
require.NoError(t, err)
store := iavlstore.UnsafeNewStore(tree)
_ = mngr.GetStoreCache(sKey, store)
Expand All @@ -46,7 +46,7 @@ func TestStoreCache(t *testing.T) {
mngr := cache.NewCommitKVStoreCacheManager(cache.DefaultCommitKVStoreCacheSize)

sKey := types.NewKVStoreKey("test")
tree, err := iavl.NewMutableTree(db, 100)
tree, err := iavl.NewMutableTree(db, 100, false)
require.NoError(t, err)
store := iavlstore.UnsafeNewStore(tree)
kvStore := mngr.GetStoreCache(sKey, store)
Expand Down
8 changes: 4 additions & 4 deletions store/iavl/store.go
Expand Up @@ -43,16 +43,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, logger log.Logger, key types.StoreKey, id types.CommitID, lazyLoading bool, cacheSize int) (types.CommitKVStore, error) {
return LoadStoreWithInitialVersion(db, logger, key, id, lazyLoading, 0, cacheSize)
func LoadStore(db dbm.DB, logger log.Logger, key types.StoreKey, id types.CommitID, lazyLoading bool, cacheSize int, disableFastNode bool) (types.CommitKVStore, error) {
return LoadStoreWithInitialVersion(db, logger, key, id, lazyLoading, 0, cacheSize, disableFastNode)
}

// 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, logger log.Logger, key types.StoreKey, id types.CommitID, lazyLoading bool, initialVersion uint64, cacheSize int) (types.CommitKVStore, error) {
tree, err := iavl.NewMutableTreeWithOpts(db, cacheSize, &iavl.Options{InitialVersion: initialVersion})
func LoadStoreWithInitialVersion(db dbm.DB, logger log.Logger, key types.StoreKey, id types.CommitID, lazyLoading bool, initialVersion uint64, cacheSize int, disableFastNode bool) (types.CommitKVStore, error) {
tree, err := iavl.NewMutableTreeWithOpts(db, cacheSize, &iavl.Options{InitialVersion: initialVersion}, disableFastNode)
if err != nil {
return nil, err
}
Expand Down
24 changes: 12 additions & 12 deletions store/iavl/store_test.go
Expand Up @@ -34,7 +34,7 @@ func randBytes(numBytes int) []byte {

// make a tree with data from above and save it
func newAlohaTree(t *testing.T, db dbm.DB) (*iavl.MutableTree, types.CommitID) {
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

for k, v := range treeData {
Expand Down Expand Up @@ -100,17 +100,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, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDH, false, DefaultIAVLCacheSize)
newHStore, err := LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDH, false, DefaultIAVLCacheSize, false)
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, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDHp, false, DefaultIAVLCacheSize)
newHpStore, err := LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDHp, false, DefaultIAVLCacheSize, false)
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, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDHc, false, DefaultIAVLCacheSize)
newHcStore, err := LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDHc, false, DefaultIAVLCacheSize, false)
require.NoError(t, err)
require.Equal(t, string(newHcStore.Get([]byte("hello"))), "ciao")
}
Expand Down Expand Up @@ -281,7 +281,7 @@ func TestIAVLIterator(t *testing.T) {
func TestIAVLReverseIterator(t *testing.T) {
db := dbm.NewMemDB()

tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
Expand Down Expand Up @@ -314,7 +314,7 @@ func TestIAVLReverseIterator(t *testing.T) {

func TestIAVLPrefixIterator(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
Expand Down Expand Up @@ -378,7 +378,7 @@ func TestIAVLPrefixIterator(t *testing.T) {

func TestIAVLReversePrefixIterator(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
Expand Down Expand Up @@ -446,7 +446,7 @@ func nextVersion(iavl *Store) {

func TestIAVLNoPrune(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
Expand All @@ -465,7 +465,7 @@ func TestIAVLNoPrune(t *testing.T) {

func TestIAVLStoreQuery(t *testing.T) {
db := dbm.NewMemDB()
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)

iavlStore := UnsafeNewStore(tree)
Expand Down Expand Up @@ -569,7 +569,7 @@ func BenchmarkIAVLIteratorNext(b *testing.B) {
b.ReportAllocs()
db := dbm.NewMemDB()
treeSize := 1000
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(b, err)

for i := 0; i < treeSize; i++ {
Expand Down Expand Up @@ -603,7 +603,7 @@ func TestSetInitialVersion(t *testing.T) {
{
"works with a mutable tree",
func(db *dbm.MemDB) *Store {
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)
store := UnsafeNewStore(tree)

Expand All @@ -613,7 +613,7 @@ func TestSetInitialVersion(t *testing.T) {
{
"throws error on immutable tree",
func(db *dbm.MemDB) *Store {
tree, err := iavl.NewMutableTree(db, cacheSize)
tree, err := iavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)
store := UnsafeNewStore(tree)
_, version, err := store.tree.SaveVersion()
Expand Down
2 changes: 1 addition & 1 deletion store/iavl/tree_test.go
Expand Up @@ -10,7 +10,7 @@ import (

func TestImmutableTreePanics(t *testing.T) {
t.Parallel()
immTree := iavl.NewImmutableTree(dbm.NewMemDB(), 100)
immTree := iavl.NewImmutableTree(dbm.NewMemDB(), 100, false)
it := &immutableTree{immTree}
require.Panics(t, func() { it.Set([]byte{}, []byte{}) })
require.Panics(t, func() { it.Remove([]byte{}) })
Expand Down
2 changes: 1 addition & 1 deletion store/prefix/store_test.go
Expand Up @@ -90,7 +90,7 @@ func testPrefixStore(t *testing.T, baseStore types.KVStore, prefix []byte) {

func TestIAVLStorePrefix(t *testing.T) {
db := dbm.NewMemDB()
tree, err := tiavl.NewMutableTree(db, cacheSize)
tree, err := tiavl.NewMutableTree(db, cacheSize, false)
require.NoError(t, err)
iavlStore := iavl.UnsafeNewStore(tree)

Expand Down
2 changes: 1 addition & 1 deletion store/rootmulti/proof_test.go
Expand Up @@ -15,7 +15,7 @@ import (
func TestVerifyIAVLStoreQueryProof(t *testing.T) {
// Create main tree for testing.
db := dbm.NewMemDB()
iStore, err := iavl.LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), types.CommitID{}, false, iavl.DefaultIAVLCacheSize)
iStore, err := iavl.LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), types.CommitID{}, false, iavl.DefaultIAVLCacheSize, false)
store := iStore.(*iavl.Store)
require.Nil(t, err)
store.Set([]byte("MYKEY"), []byte("MYVALUE"))
Expand Down