From 34615fb52fc1d2dc518549ff1ae7d650dac94e54 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 11:15:32 -0700 Subject: [PATCH 01/29] [10948]: Add changelog entry. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba46ff4f05c9..08efd2d3bdf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -164,6 +164,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (types/errors) [\#10779](https://github.com/cosmos/cosmos-sdk/pull/10779) Move most functionality in `types/errors` to a standalone `errors` go module, except the `RootCodespace` errors and ABCI response helpers. All functions and types that used to live in `types/errors` are now aliased so this is not a breaking change. * (gov) [\#10854](https://github.com/cosmos/cosmos-sdk/pull/10854) v1beta2's vote doesn't include the deprecate `option VoteOption` anymore. Instead, it only uses `WeightedVoteOption`. * (types) [\#11004](https://github.com/cosmos/cosmos-sdk/pull/11004) Added mutable versions of many of the sdk.Dec types operations. This improves performance when used by avoiding reallocating a new bigint for each operation. +* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Use Tendermint `db_backend` config value instead of compile-time `types.DBBackend` value. ### Bug Fixes From a51cbc23cb2c92bcc3f155824df31cf59bd07172 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 11:38:43 -0700 Subject: [PATCH 02/29] [10948]: Deprecate the types.DBBackend variable and the NewLevelDB function. Create a NewDB function to replace them. --- types/utils.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/types/utils.go b/types/utils.go index cca98edf0ab7..2925e5326c2b 100644 --- a/types/utils.go +++ b/types/utils.go @@ -11,13 +11,15 @@ import ( var ( // This is set at compile time. Could be cleveldb, defaults is goleveldb. - DBBackend = "" + DBBackend = "" // Deprecated: Use tendermint config's DBBackend value instead. backend = dbm.GoLevelDBBackend ) func init() { if len(DBBackend) != 0 { backend = dbm.BackendType(DBBackend) + } else { + DBBackend = string(backend) } } @@ -85,6 +87,8 @@ func ParseTimeBytes(bz []byte) (time.Time, error) { } // NewLevelDB instantiate a new LevelDB instance according to DBBackend. +// +// Deprecated: Use NewDB instead. Suggested backendType is tendermint config's DBBackend value. func NewLevelDB(name, dir string) (db dbm.DB, err error) { defer func() { if r := recover(); r != nil { @@ -95,6 +99,20 @@ func NewLevelDB(name, dir string) (db dbm.DB, err error) { return dbm.NewDB(name, backend, dir) } +// NewDB instantiate a new DB instance. +// This differs from the tendermint/tm-db.NewDB function in two ways: +// 1) Returns an error instead of panicking. +// 2) Takes in a string for the backend type. +func NewDB(name, backendType, dir string) (db dbm.DB, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("couldn't create db: %v", r) + } + }() + + return dbm.NewDB(name, dbm.BackendType(backendType), dir) +} + // copy bytes func CopyBytes(bz []byte) (ret []byte) { if bz == nil { From 533a317fd3a757731aab425f1e7c45178dc48e90 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 11:42:21 -0700 Subject: [PATCH 03/29] [10948]: Add a DBBackend string to the simulation config and a flag for setting it. Update the simulation setup to use that instead of the compile-time DBBackend variable. --- simapp/config.go | 3 +++ simapp/utils.go | 2 +- types/simulation/config.go | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/simapp/config.go b/simapp/config.go index 98df982bd304..48cc053f2533 100644 --- a/simapp/config.go +++ b/simapp/config.go @@ -22,6 +22,7 @@ var ( FlagCommitValue bool FlagOnOperationValue bool // TODO: Remove in favor of binary search for invariant violation FlagAllInvariantsValue bool + FlagDBBackendValue string FlagEnabledValue bool FlagVerboseValue bool @@ -46,6 +47,7 @@ func GetSimulatorFlags() { flag.BoolVar(&FlagCommitValue, "Commit", false, "have the simulation commit") flag.BoolVar(&FlagOnOperationValue, "SimulateEveryOperation", false, "run slow invariants every operation") flag.BoolVar(&FlagAllInvariantsValue, "PrintAllInvariants", false, "print all invariants if a broken invariant is found") + flag.StringVar(&FlagDBBackendValue, "DBBackend", "goleveldb", "custom db backend type") // simulation flags flag.BoolVar(&FlagEnabledValue, "Enabled", false, "enable the simulation") @@ -71,5 +73,6 @@ func NewConfigFromFlags() simulation.Config { Commit: FlagCommitValue, OnOperation: FlagOnOperationValue, AllInvariants: FlagAllInvariantsValue, + DBBackend: FlagDBBackendValue, } } diff --git a/simapp/utils.go b/simapp/utils.go index 51d8ef54020f..00862d52dbba 100644 --- a/simapp/utils.go +++ b/simapp/utils.go @@ -39,7 +39,7 @@ func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, return simtypes.Config{}, nil, "", nil, false, err } - db, err := sdk.NewLevelDB(dbName, dir) + db, err := sdk.NewDB(dbName, config.DBBackend, dir) if err != nil { return simtypes.Config{}, nil, "", nil, false, err } diff --git a/types/simulation/config.go b/types/simulation/config.go index 8bad709545c9..7f520004d478 100644 --- a/types/simulation/config.go +++ b/types/simulation/config.go @@ -21,4 +21,6 @@ type Config struct { OnOperation bool // run slow invariants every operation AllInvariants bool // print all failed invariants if a broken invariant is found + + DBBackend string // custom db backend type } From 53d766fa185eb820f89c34fdca10b1e6f0c1e1b6 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 11:58:34 -0700 Subject: [PATCH 04/29] [10948]: Update the mock app creator to use the NewDB function. Not sure what to do about the db backend in that case though. --- server/mock/app.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/mock/app.go b/server/mock/app.go index 8ef0ae405e51..b2bcfbac1a0c 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -34,7 +34,8 @@ func testTxHandler(options middleware.TxHandlerOptions) tx.Handler { // similar to a real app. Make sure rootDir is empty before running the test, // in order to guarantee consistent results func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { - db, err := sdk.NewLevelDB("mock", filepath.Join(rootDir, "data")) + // TODO: use something other than a hard-coded "goleveldb" here? + db, err := sdk.NewDB("mock", "goleveldb", filepath.Join(rootDir, "data")) if err != nil { return nil, err } From 63ddc2f835c52ba4bc64b7b416bb8c52d37e4a88 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 12:05:26 -0700 Subject: [PATCH 05/29] [10948]: Update changelog to reflect new db-backend field name. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08efd2d3bdf2..8cf77ff4dab0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -164,7 +164,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (types/errors) [\#10779](https://github.com/cosmos/cosmos-sdk/pull/10779) Move most functionality in `types/errors` to a standalone `errors` go module, except the `RootCodespace` errors and ABCI response helpers. All functions and types that used to live in `types/errors` are now aliased so this is not a breaking change. * (gov) [\#10854](https://github.com/cosmos/cosmos-sdk/pull/10854) v1beta2's vote doesn't include the deprecate `option VoteOption` anymore. Instead, it only uses `WeightedVoteOption`. * (types) [\#11004](https://github.com/cosmos/cosmos-sdk/pull/11004) Added mutable versions of many of the sdk.Dec types operations. This improves performance when used by avoiding reallocating a new bigint for each operation. -* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Use Tendermint `db_backend` config value instead of compile-time `types.DBBackend` value. +* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Use Tendermint `db-backend` config value instead of compile-time `types.DBBackend` value. ### Bug Fixes From d84ef9da59d76cfdd8c9a08c28630cfc2db8d9b7 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 12:13:57 -0700 Subject: [PATCH 06/29] [10948]: Use the tendermint db-backend type for the snapshot db. --- simapp/simd/cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index d1425eb8924c..84078ce765ae 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -261,7 +261,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a } snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") - snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) + snapshotDB, err := sdk.NewDB("metadata", cast.ToString(appOpts.Get("db-backend")), snapshotDir) if err != nil { panic(err) } From 37b3456d33f723ee5c7fc36d05ad0f52f575d853 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 12:26:33 -0700 Subject: [PATCH 07/29] [10948]: Update the last use of NewLevelDB by adding a parameter to openDB and uppdating calls to that to provide the db type to use. --- server/constructors_test.go | 2 +- server/export.go | 2 +- server/start.go | 4 ++-- server/util.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server/constructors_test.go b/server/constructors_test.go index c131c2c987de..e83900fd993a 100644 --- a/server/constructors_test.go +++ b/server/constructors_test.go @@ -9,7 +9,7 @@ import ( func Test_openDB(t *testing.T) { t.Parallel() - _, err := openDB(t.TempDir()) + _, err := openDB(t.TempDir(), "") require.NoError(t, err) } diff --git a/server/export.go b/server/export.go index 38938bcaeb6e..65b990b30f97 100644 --- a/server/export.go +++ b/server/export.go @@ -37,7 +37,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com return err } - db, err := openDB(config.RootDir) + db, err := openDB(config.RootDir, config.DBBackend) if err != nil { return err } diff --git a/server/start.go b/server/start.go index 45d7c920ea5d..413e91e72025 100644 --- a/server/start.go +++ b/server/start.go @@ -169,7 +169,7 @@ func startStandAlone(ctx *Context, appCreator types.AppCreator) error { transport := ctx.Viper.GetString(flagTransport) home := ctx.Viper.GetString(flags.FlagHome) - db, err := openDB(home) + db, err := openDB(home, ctx.Viper.GetString("db-backend")) if err != nil { return err } @@ -229,7 +229,7 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App } traceWriterFile := ctx.Viper.GetString(flagTraceStore) - db, err := openDB(home) + db, err := openDB(home, cfg.DBBackend) if err != nil { return err } diff --git a/server/util.go b/server/util.go index dcdeb3ff5818..8e1608661c97 100644 --- a/server/util.go +++ b/server/util.go @@ -371,9 +371,9 @@ func addrToIP(addr net.Addr) net.IP { return ip } -func openDB(rootDir string) (dbm.DB, error) { +func openDB(rootDir, backendType string) (dbm.DB, error) { dataDir := filepath.Join(rootDir, "data") - return sdk.NewLevelDB("application", dataDir) + return sdk.NewDB("application", backendType, dataDir) } func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { From 6411ab59a7d4bafcbf35fa9a9e665ff1c8828d63 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 12:28:06 -0700 Subject: [PATCH 08/29] [10948]: Upddate the NewDB function to also have a default db backend type if an empty string is provided there. --- server/mock/app.go | 4 ++-- types/utils.go | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/server/mock/app.go b/server/mock/app.go index b2bcfbac1a0c..81c41e2e5bea 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -34,8 +34,8 @@ func testTxHandler(options middleware.TxHandlerOptions) tx.Handler { // similar to a real app. Make sure rootDir is empty before running the test, // in order to guarantee consistent results func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { - // TODO: use something other than a hard-coded "goleveldb" here? - db, err := sdk.NewDB("mock", "goleveldb", filepath.Join(rootDir, "data")) + // TODO: provide something as the db backend here instead of using the default? + db, err := sdk.NewDB("mock", "", filepath.Join(rootDir, "data")) if err != nil { return nil, err } diff --git a/types/utils.go b/types/utils.go index 2925e5326c2b..a89d8805206e 100644 --- a/types/utils.go +++ b/types/utils.go @@ -100,16 +100,19 @@ func NewLevelDB(name, dir string) (db dbm.DB, err error) { } // NewDB instantiate a new DB instance. -// This differs from the tendermint/tm-db.NewDB function in two ways: +// This differs from the tendermint/tm-db.NewDB function in three ways: // 1) Returns an error instead of panicking. // 2) Takes in a string for the backend type. +// 3) If the backendType is an empty string, "goleveldb" is used. func NewDB(name, backendType, dir string) (db dbm.DB, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("couldn't create db: %v", r) } }() - + if len(backendType) == 0 { + backendType = string(dbm.GoLevelDBBackend) + } return dbm.NewDB(name, dbm.BackendType(backendType), dir) } From 33cf13fc7d213a14be424612356e258e4783ad27 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 12:32:41 -0700 Subject: [PATCH 09/29] [10948]: Remove the new TODO in mock.NewApp. After looking through it's uses, there doesn't seem to be any desire to change it, and there's no easy way to communicate it. --- server/mock/app.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/mock/app.go b/server/mock/app.go index 81c41e2e5bea..f7a0363f9653 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -34,7 +34,6 @@ func testTxHandler(options middleware.TxHandlerOptions) tx.Handler { // similar to a real app. Make sure rootDir is empty before running the test, // in order to guarantee consistent results func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { - // TODO: provide something as the db backend here instead of using the default? db, err := sdk.NewDB("mock", "", filepath.Join(rootDir, "data")) if err != nil { return nil, err From 9b81772e616263bfae1452b79194a57765e8177e Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 13:28:40 -0700 Subject: [PATCH 10/29] [10948]: Enhance the NewDB defer function to also add info to any err that is being returned. --- types/utils.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/types/utils.go b/types/utils.go index a89d8805206e..033e6eaf74bd 100644 --- a/types/utils.go +++ b/types/utils.go @@ -106,8 +106,12 @@ func NewLevelDB(name, dir string) (db dbm.DB, err error) { // 3) If the backendType is an empty string, "goleveldb" is used. func NewDB(name, backendType, dir string) (db dbm.DB, err error) { defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("couldn't create db: %v", r) + r := recover() + switch { + case r != nil: + err = fmt.Errorf("could not create %q db in %s with name %q: %v", backendType, dir, name, r) + case err != nil: + err = fmt.Errorf("could not create %q db in %s with name %q: %w", backendType, dir, name, err) } }() if len(backendType) == 0 { From ee2736c4c5f58c7bb3cad577e58057ab4aaf2944 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 13:29:57 -0700 Subject: [PATCH 11/29] [10948]: Add some unit tests for NewDB. --- types/utils_test.go | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/types/utils_test.go b/types/utils_test.go index c04c9c81f3e1..db840153b57d 100644 --- a/types/utils_test.go +++ b/types/utils_test.go @@ -5,9 +5,13 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" sdk "github.com/cosmos/cosmos-sdk/types" + + dbm "github.com/tendermint/tm-db" ) type utilsTestSuite struct { @@ -109,3 +113,66 @@ func (s *utilsTestSuite) TestParseTimeBytes() { _, err = sdk.ParseTimeBytes([]byte{}) s.Require().Error(err) } + +func (s *utilsTestSuite) TestNewDB() { + tests := []struct { + testName string + + name string + backendType string + + isGoLevelDB bool + isMemDB bool + errContains []string + }{ + { + testName: "unknown backendType gives error", + name: "test-unknown", + backendType: "baddbtype", + errContains: []string{"could not create", "test-unknown", "unknown", "baddbtype", "goleveldb"}, + }, + { + testName: "empty backendType defaults to goleveldb", + name: "test-empty", + backendType: "", + isGoLevelDB: true, + }, + { + testName: "goleveldb returns a GoLevelDB", + name: "test-goleveldb", + backendType: "goleveldb", + isGoLevelDB: true, + }, + { + testName: "memdb returns a MemDB", + name: "test-memdb", + backendType: "memdb", + isMemDB: true, + }, + } + + for _, tc := range tests { + s.T().Run(tc.testName, func(t *testing.T) { + dir := t.TempDir() + var db dbm.DB + var err error + require.NotPanics(t, func() { + db, err = sdk.NewDB(tc.name, tc.backendType, dir) + }, "calling NewDB") + if len(tc.errContains) != 0 { + require.Error(t, err, "err") + for _, exp := range tc.errContains { + assert.Contains(t, err.Error(), exp, "err.Error()") + } + } else { + require.NoError(t, err, "err") + require.NotNil(t, db, "db") + assert.NoError(t, db.Close(), "db.Close()") + _, isGoLevelDB := db.(*dbm.GoLevelDB) + assert.Equal(t, tc.isGoLevelDB, isGoLevelDB, "isGoLevelDB") + _, isMemDB := db.(*dbm.MemDB) + assert.Equal(t, tc.isMemDB, isMemDB, "isMemDB") + } + }) + } +} From 606c600f713aabc4878ebe9a19ff6582ea47510c Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 13:32:21 -0700 Subject: [PATCH 12/29] [10948]: Lint fixes. --- types/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/utils.go b/types/utils.go index 033e6eaf74bd..3cfe3cd5a509 100644 --- a/types/utils.go +++ b/types/utils.go @@ -117,7 +117,7 @@ func NewDB(name, backendType, dir string) (db dbm.DB, err error) { if len(backendType) == 0 { backendType = string(dbm.GoLevelDBBackend) } - return dbm.NewDB(name, dbm.BackendType(backendType), dir) + return dbm.NewDB(name, dbm.BackendType(backendType), dir) } // copy bytes From d596b603297c0eb3ccfe1dbc1d02fd80b6ce78d1 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 13:37:55 -0700 Subject: [PATCH 13/29] [10948]: Add a changelog entry to the deprecated section. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cf77ff4dab0..ca44124a76ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -218,6 +218,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Deprecated * (x/upgrade) [\#9906](https://github.com/cosmos/cosmos-sdk/pull/9906) Deprecate `UpgradeConsensusState` gRPC query since this functionality is only used for IBC, which now has its own [IBC replacement](https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) +* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Deprecate the types.DBBackend variable and types.NewLevelDB function in favor of the new types.NewDB function that takes in a db backend type. ## [v0.45.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.0) - 2022-01-18 From 6a40720a17a89a6a0b6c2c715526b05022b51e3e Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 14 Feb 2022 14:18:15 -0700 Subject: [PATCH 14/29] [10948]: Update the makefile to no longer set the types.DBBackend value. --- Makefile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 3ef8241658f6..977c94a27dc4 100644 --- a/Makefile +++ b/Makefile @@ -46,10 +46,6 @@ ifeq ($(LEDGER_ENABLED),true) endif endif -ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS))) - build_tags += gcc -endif - whitespace := whitespace += $(whitespace) comma := , @@ -73,10 +69,9 @@ endif # DB backend selection ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS))) - ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb + build_tags += gcc endif ifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS))) - ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=badgerdb BUILD_TAGS += badgerdb endif # handle rocksdb @@ -86,12 +81,10 @@ ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS))) endif CGO_ENABLED=1 BUILD_TAGS += rocksdb - ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb endif # handle boltdb ifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS))) BUILD_TAGS += boltdb - ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=boltdb endif ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS))) From e5a97ded2e7d182a1ee4baf9edd21a4f8170ced6 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 17 Feb 2022 10:15:18 -0700 Subject: [PATCH 15/29] [10948]: Use memdb for the mock app instead of goleveldb. I know it was a goleveldb before, but for a mock app, a memdb feels like a better choice (assuming 'mock' and 'mem' mean what I assume they mean). --- server/mock/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/mock/app.go b/server/mock/app.go index f7a0363f9653..1a2ac99e5bff 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -34,7 +34,7 @@ func testTxHandler(options middleware.TxHandlerOptions) tx.Handler { // similar to a real app. Make sure rootDir is empty before running the test, // in order to guarantee consistent results func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { - db, err := sdk.NewDB("mock", "", filepath.Join(rootDir, "data")) + db, err := sdk.NewDB("mock", "memdb", filepath.Join(rootDir, "data")) if err != nil { return nil, err } From 83d207475ac2506bddf5e69b341a6c3dbdb066f4 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 17 Feb 2022 11:45:19 -0700 Subject: [PATCH 16/29] [10948]: Fix the store benchmark tests (had some index-out-of-range issues). --- store/cachekv/store_bench_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/store/cachekv/store_bench_test.go b/store/cachekv/store_bench_test.go index 88c86eff564a..cb75326cad68 100644 --- a/store/cachekv/store_bench_test.go +++ b/store/cachekv/store_bench_test.go @@ -70,7 +70,8 @@ func benchmarkRandomSet(b *testing.B, keysize int) { // Use a singleton for value, to not waste time computing it value := randSlice(defaultValueSizeBz) - keys := generateRandomKeys(keysize, b.N) + // Add 1 to avoid issues when b.N = 1 + keys := generateRandomKeys(keysize, b.N+1) b.ReportAllocs() b.ResetTimer() @@ -100,7 +101,8 @@ func benchmarkIteratorOnParentWithManyDeletes(b *testing.B, numDeletes int) { // Use simple values for keys, pick a random start, // and take next D keys sequentially after. startKey := randSlice(32) - keys := generateSequentialKeys(startKey, numDeletes) + // Add 1 to avoid issues when numDeletes = 1 + keys := generateSequentialKeys(startKey, numDeletes+1) // setup parent db with D keys. for _, k := range keys { mem.Set(k, value) @@ -118,7 +120,7 @@ func benchmarkIteratorOnParentWithManyDeletes(b *testing.B, numDeletes int) { b.ReportAllocs() b.ResetTimer() - iter := kvstore.Iterator(keys[0], keys[b.N]) + iter := kvstore.Iterator(keys[0], keys[numDeletes]) defer iter.Close() for _ = iter.Key(); iter.Valid(); iter.Next() { From f08da2dcde3ecfe09c0f427c1864357211202033 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 17 Feb 2022 12:29:19 -0700 Subject: [PATCH 17/29] [10948]: Fix cachekv store bench test calling iter.Key() before checking iter.Valid(). --- store/cachekv/store_bench_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/store/cachekv/store_bench_test.go b/store/cachekv/store_bench_test.go index cb75326cad68..c5cb92f0ea98 100644 --- a/store/cachekv/store_bench_test.go +++ b/store/cachekv/store_bench_test.go @@ -35,7 +35,8 @@ func benchmarkBlankParentIteratorNext(b *testing.B, keysize int) { iter := kvstore.Iterator(keys[0], keys[b.N]) defer iter.Close() - for _ = iter.Key(); iter.Valid(); iter.Next() { + for ; iter.Valid(); iter.Next() { + _ = iter.Key() // deadcode elimination stub sink = iter } @@ -83,7 +84,8 @@ func benchmarkRandomSet(b *testing.B, keysize int) { iter := kvstore.Iterator(keys[0], keys[b.N]) defer iter.Close() - for _ = iter.Key(); iter.Valid(); iter.Next() { + for ; iter.Valid(); iter.Next() { + _ = iter.Key() // deadcode elimination stub sink = iter } @@ -123,7 +125,8 @@ func benchmarkIteratorOnParentWithManyDeletes(b *testing.B, numDeletes int) { iter := kvstore.Iterator(keys[0], keys[numDeletes]) defer iter.Close() - for _ = iter.Key(); iter.Valid(); iter.Next() { + for ; iter.Valid(); iter.Next() { + _ = iter.Key() // deadcode elimination stub sink = iter } From ff6d1ca7a844e8922aa4386494adf8f215cb3182 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Tue, 22 Feb 2022 10:40:59 -0700 Subject: [PATCH 18/29] [10948]: Remove the panic recovery from types.NewDB since dbm.NewDB returns an error now (it didn't originally, when NewLevelDB was first written). --- types/utils.go | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/types/utils.go b/types/utils.go index 3cfe3cd5a509..f90110810195 100644 --- a/types/utils.go +++ b/types/utils.go @@ -18,8 +18,6 @@ var ( func init() { if len(DBBackend) != 0 { backend = dbm.BackendType(DBBackend) - } else { - DBBackend = string(backend) } } @@ -104,20 +102,15 @@ func NewLevelDB(name, dir string) (db dbm.DB, err error) { // 1) Returns an error instead of panicking. // 2) Takes in a string for the backend type. // 3) If the backendType is an empty string, "goleveldb" is used. -func NewDB(name, backendType, dir string) (db dbm.DB, err error) { - defer func() { - r := recover() - switch { - case r != nil: - err = fmt.Errorf("could not create %q db in %s with name %q: %v", backendType, dir, name, r) - case err != nil: - err = fmt.Errorf("could not create %q db in %s with name %q: %w", backendType, dir, name, err) - } - }() +func NewDB(name, backendType, dir string) (dbm.DB, error) { if len(backendType) == 0 { backendType = string(dbm.GoLevelDBBackend) } - return dbm.NewDB(name, dbm.BackendType(backendType), dir) + db, err := dbm.NewDB(name, dbm.BackendType(backendType), dir) + if err != nil { + return nil, fmt.Errorf("could not create %q db in %s with type %q: %w", name, dir, backendType, err) + } + return db, nil } // copy bytes From 00e3615c935ebfa23c01ea56e856906f17b8e031 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Tue, 22 Feb 2022 10:42:30 -0700 Subject: [PATCH 19/29] [10948]: Add changlog entry indicationg an API breaking change due to the DBBackend change. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 732ef4026af0..6941a1dc1041 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -129,7 +129,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10868](https://github.com/cosmos/cosmos-sdk/pull/10868), [\#10989](https://github.com/cosmos/cosmos-sdk/pull/10989), [\#11093](https://github.com/cosmos/cosmos-sdk/pull/11093) The Gov keeper accepts now 2 more mandatory arguments, the ServiceMsgRouter and a gov Config including the max metadata length. * [\#11124](https://github.com/cosmos/cosmos-sdk/pull/11124) Add `GetAllVersions` to application store * (x/authz) [\#10447](https://github.com/cosmos/cosmos-sdk/pull/10447) authz `NewGrant` takes a new argument: block time, to correctly validate expire time. - +* (types) [\#11188](https://github.com/cosmos/cosmos-sdk/pull/11188) Nodes with a discrepancy between the `DBBackend` (provided at compile time) and `db-backend` from `config.toml` (or `db_backend` pre-Tendermint v0.35) values must migrate the Cosmos-SDK DBs to the backend type defined in `config.toml`. ### Client Breaking Changes From 3f57be7d714ef345f6e3e8c9c25afec15dafa108 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Tue, 22 Feb 2022 11:19:11 -0700 Subject: [PATCH 20/29] [10948]: Get rid of the types.NewDB function in favor of just using the tm-db version of it. --- server/constructors_test.go | 4 ++- server/mock/app.go | 3 +- server/util.go | 2 +- simapp/simd/cmd/root.go | 2 +- simapp/utils.go | 2 +- types/utils.go | 18 +--------- types/utils_test.go | 67 ------------------------------------- 7 files changed, 9 insertions(+), 89 deletions(-) diff --git a/server/constructors_test.go b/server/constructors_test.go index e83900fd993a..4f4990bf867a 100644 --- a/server/constructors_test.go +++ b/server/constructors_test.go @@ -5,11 +5,13 @@ import ( "testing" "github.com/stretchr/testify/require" + + dbm "github.com/tendermint/tm-db" ) func Test_openDB(t *testing.T) { t.Parallel() - _, err := openDB(t.TempDir(), "") + _, err := openDB(t.TempDir(), string(dbm.GoLevelDBBackend)) require.NoError(t, err) } diff --git a/server/mock/app.go b/server/mock/app.go index 1a2ac99e5bff..9fd4d72f480e 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -9,6 +9,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/tm-db" bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" @@ -34,7 +35,7 @@ func testTxHandler(options middleware.TxHandlerOptions) tx.Handler { // similar to a real app. Make sure rootDir is empty before running the test, // in order to guarantee consistent results func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { - db, err := sdk.NewDB("mock", "memdb", filepath.Join(rootDir, "data")) + db, err := dbm.NewDB("mock", dbm.MemDBBackend, filepath.Join(rootDir, "data")) if err != nil { return nil, err } diff --git a/server/util.go b/server/util.go index 8e1608661c97..856b32d1a382 100644 --- a/server/util.go +++ b/server/util.go @@ -373,7 +373,7 @@ func addrToIP(addr net.Addr) net.IP { func openDB(rootDir, backendType string) (dbm.DB, error) { dataDir := filepath.Join(rootDir, "data") - return sdk.NewDB("application", backendType, dataDir) + return dbm.NewDB("application", dbm.BackendType(backendType), dataDir) } func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 84078ce765ae..0a18b4516353 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -261,7 +261,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a } snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") - snapshotDB, err := sdk.NewDB("metadata", cast.ToString(appOpts.Get("db-backend")), snapshotDir) + snapshotDB, err := dbm.NewDB("metadata", dbm.BackendType(cast.ToString(appOpts.Get("db-backend"))), snapshotDir) if err != nil { panic(err) } diff --git a/simapp/utils.go b/simapp/utils.go index 00862d52dbba..1478104a5d8c 100644 --- a/simapp/utils.go +++ b/simapp/utils.go @@ -39,7 +39,7 @@ func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, return simtypes.Config{}, nil, "", nil, false, err } - db, err := sdk.NewDB(dbName, config.DBBackend, dir) + db, err := dbm.NewDB(dbName, dbm.BackendType(config.DBBackend), dir) if err != nil { return simtypes.Config{}, nil, "", nil, false, err } diff --git a/types/utils.go b/types/utils.go index f90110810195..dc13af6f9b21 100644 --- a/types/utils.go +++ b/types/utils.go @@ -86,7 +86,7 @@ func ParseTimeBytes(bz []byte) (time.Time, error) { // NewLevelDB instantiate a new LevelDB instance according to DBBackend. // -// Deprecated: Use NewDB instead. Suggested backendType is tendermint config's DBBackend value. +// Deprecated: Use NewDB (from "github.com/tendermint/tm-db") instead. Suggested backendType is tendermint config's DBBackend value. func NewLevelDB(name, dir string) (db dbm.DB, err error) { defer func() { if r := recover(); r != nil { @@ -97,22 +97,6 @@ func NewLevelDB(name, dir string) (db dbm.DB, err error) { return dbm.NewDB(name, backend, dir) } -// NewDB instantiate a new DB instance. -// This differs from the tendermint/tm-db.NewDB function in three ways: -// 1) Returns an error instead of panicking. -// 2) Takes in a string for the backend type. -// 3) If the backendType is an empty string, "goleveldb" is used. -func NewDB(name, backendType, dir string) (dbm.DB, error) { - if len(backendType) == 0 { - backendType = string(dbm.GoLevelDBBackend) - } - db, err := dbm.NewDB(name, dbm.BackendType(backendType), dir) - if err != nil { - return nil, fmt.Errorf("could not create %q db in %s with type %q: %w", name, dir, backendType, err) - } - return db, nil -} - // copy bytes func CopyBytes(bz []byte) (ret []byte) { if bz == nil { diff --git a/types/utils_test.go b/types/utils_test.go index db840153b57d..c04c9c81f3e1 100644 --- a/types/utils_test.go +++ b/types/utils_test.go @@ -5,13 +5,9 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" sdk "github.com/cosmos/cosmos-sdk/types" - - dbm "github.com/tendermint/tm-db" ) type utilsTestSuite struct { @@ -113,66 +109,3 @@ func (s *utilsTestSuite) TestParseTimeBytes() { _, err = sdk.ParseTimeBytes([]byte{}) s.Require().Error(err) } - -func (s *utilsTestSuite) TestNewDB() { - tests := []struct { - testName string - - name string - backendType string - - isGoLevelDB bool - isMemDB bool - errContains []string - }{ - { - testName: "unknown backendType gives error", - name: "test-unknown", - backendType: "baddbtype", - errContains: []string{"could not create", "test-unknown", "unknown", "baddbtype", "goleveldb"}, - }, - { - testName: "empty backendType defaults to goleveldb", - name: "test-empty", - backendType: "", - isGoLevelDB: true, - }, - { - testName: "goleveldb returns a GoLevelDB", - name: "test-goleveldb", - backendType: "goleveldb", - isGoLevelDB: true, - }, - { - testName: "memdb returns a MemDB", - name: "test-memdb", - backendType: "memdb", - isMemDB: true, - }, - } - - for _, tc := range tests { - s.T().Run(tc.testName, func(t *testing.T) { - dir := t.TempDir() - var db dbm.DB - var err error - require.NotPanics(t, func() { - db, err = sdk.NewDB(tc.name, tc.backendType, dir) - }, "calling NewDB") - if len(tc.errContains) != 0 { - require.Error(t, err, "err") - for _, exp := range tc.errContains { - assert.Contains(t, err.Error(), exp, "err.Error()") - } - } else { - require.NoError(t, err, "err") - require.NotNil(t, db, "db") - assert.NoError(t, db.Close(), "db.Close()") - _, isGoLevelDB := db.(*dbm.GoLevelDB) - assert.Equal(t, tc.isGoLevelDB, isGoLevelDB, "isGoLevelDB") - _, isMemDB := db.(*dbm.MemDB) - assert.Equal(t, tc.isMemDB, isMemDB, "isMemDB") - } - }) - } -} From 52ee92cfbcea69f3e220a286aaf5abfef2c1b64a Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Tue, 22 Feb 2022 12:04:57 -0700 Subject: [PATCH 21/29] [10948]: Fix Update the codeql-analysis github action to use go v1.17. --- .github/workflows/codeql-analysis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 99b58e9691cf..98d918ee479b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,6 +21,11 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2.3.5 + - uses: actions/setup-go@v2.2.0 + with: + go-version: 1.17 + - name: Display go version + run: go version # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From b035260dad17b2e29e1e94d7920b3c4baa046da8 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 28 Feb 2022 13:47:29 -0700 Subject: [PATCH 22/29] [10948]: Add config file option for the app db backend type. --- CHANGELOG.md | 8 ++-- server/config/config.go | 6 +++ server/config/toml.go | 4 ++ server/constructors_test.go | 2 +- server/export.go | 2 +- server/start.go | 6 +-- server/util.go | 17 +++++++- server/util_test.go | 85 +++++++++++++++++++++++++++++++++++++ simapp/simd/cmd/root.go | 2 +- 9 files changed, 120 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 202fbbe65925..4b8106a2a271 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/authz) [\#10714](https://github.com/cosmos/cosmos-sdk/pull/10714) Add support for pruning expired authorizations * [\#10015](https://github.com/cosmos/cosmos-sdk/pull/10015) ADR-040: ICS-23 proofs for SMT store * [\#11240](https://github.com/cosmos/cosmos-sdk/pull/11240) Replace various modules `ModuleCdc` with the global `legacy.Cdc` +* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Add `app-db-backend` to the `app.toml` config to replace the compile-time `types.DBbackend` variable. ### API Breaking Changes @@ -126,12 +127,12 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#10816](https://github.com/cosmos/cosmos-sdk/pull/10816) Reuse blocked addresses from the bank module. No need to pass them to distribution. * [\#10852](https://github.com/cosmos/cosmos-sdk/pull/10852) Move `x/gov/types` to `x/gov/types/v1beta2`. * [\#10922](https://github.com/cosmos/cosmos-sdk/pull/10922), [/#10957](https://github.com/cosmos/cosmos-sdk/pull/10957) Move key `server.Generate*` functions to testutil and support custom mnemonics in in-process testing network. Moved `TestMnemonic` from `testutil` package to `testdata`. -* (x/bank) [\#10771](https://github.com/cosmos/cosmos-sdk/pull/10771) Add safety check on bank module perms to allow module-specific mint restrictions (e.g. only minting a certain denom).* (x/bank) [\#10771](https://github.com/cosmos/cosmos-sdk/pull/10771) Add `bank.BaseKeeper.WithMintCoinsRestriction` function to restrict use of bank `MintCoins` usage. +* (x/bank) [\#10771](https://github.com/cosmos/cosmos-sdk/pull/10771) Add safety check on bank module perms to allow module-specific mint restrictions (e.g. only minting a certain denom). +* (x/bank) [\#10771](https://github.com/cosmos/cosmos-sdk/pull/10771) Add `bank.BaseKeeper.WithMintCoinsRestriction` function to restrict use of bank `MintCoins` usage. * [\#10868](https://github.com/cosmos/cosmos-sdk/pull/10868), [\#10989](https://github.com/cosmos/cosmos-sdk/pull/10989) The Gov keeper accepts now 2 more mandatory arguments, the ServiceMsgRouter and a maximum proposal metadata length. * [\#10868](https://github.com/cosmos/cosmos-sdk/pull/10868), [\#10989](https://github.com/cosmos/cosmos-sdk/pull/10989), [\#11093](https://github.com/cosmos/cosmos-sdk/pull/11093) The Gov keeper accepts now 2 more mandatory arguments, the ServiceMsgRouter and a gov Config including the max metadata length. * [\#11124](https://github.com/cosmos/cosmos-sdk/pull/11124) Add `GetAllVersions` to application store * (x/authz) [\#10447](https://github.com/cosmos/cosmos-sdk/pull/10447) authz `NewGrant` takes a new argument: block time, to correctly validate expire time. -* (types) [\#11188](https://github.com/cosmos/cosmos-sdk/pull/11188) Nodes with a discrepancy between the `DBBackend` (provided at compile time) and `db-backend` from `config.toml` (or `db_backend` pre-Tendermint v0.35) values must migrate the Cosmos-SDK DBs to the backend type defined in `config.toml`. ### Client Breaking Changes @@ -173,7 +174,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (types) [\#11004](https://github.com/cosmos/cosmos-sdk/pull/11004) Added mutable versions of many of the sdk.Dec types operations. This improves performance when used by avoiding reallocating a new bigint for each operation. * (x/auth) [\#10880](https://github.com/cosmos/cosmos-sdk/pull/10880) Added a new query to the tx query service that returns a block with transactions fully decoded. * (types) [\#11200](https://github.com/cosmos/cosmos-sdk/pull/11200) Added `Min()` and `Max()` operations on sdk.Coins. -* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Use Tendermint `db-backend` config value instead of compile-time `types.DBBackend` value. ### Bug Fixes @@ -235,7 +235,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Deprecated * (x/upgrade) [\#9906](https://github.com/cosmos/cosmos-sdk/pull/9906) Deprecate `UpgradeConsensusState` gRPC query since this functionality is only used for IBC, which now has its own [IBC replacement](https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) -* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Deprecate the types.DBBackend variable and types.NewLevelDB function in favor of the new types.NewDB function that takes in a db backend type. +* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Deprecate the types.DBBackend variable and types.NewLevelDB function. They are replaced by a new entry in `app.toml`: `app-db-backend` and `tendermint/tm-db`s NewDB function. If `app-db-backend` is defined, then it is used. Otherwise, if `types.DBBackend` is defined, it is used (until removed: [\#11241](https://github.com/cosmos/cosmos-sdk/issues/11241)). Otherwise, Tendermint config's `db-backend` is used. ## [v0.45.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.0) - 2022-01-18 diff --git a/server/config/config.go b/server/config/config.go index 64262c37ac47..c85b89fe4023 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -70,6 +70,10 @@ type BaseConfig struct { IndexEvents []string `mapstructure:"index-events"` // IavlCacheSize set the size of the iavl tree cache. IAVLCacheSize uint64 `mapstructure:"iavl-cache-size"` + + // 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"` } // APIConfig defines the API listener configuration. @@ -210,6 +214,7 @@ func DefaultConfig() *Config { MinRetainBlocks: 0, IndexEvents: make([]string, 0), IAVLCacheSize: 781250, // 50 MB + AppDBBackend: "", }, Telemetry: telemetry.Config{ Enabled: false, @@ -269,6 +274,7 @@ func GetConfig(v *viper.Viper) Config { IndexEvents: v.GetStringSlice("index-events"), MinRetainBlocks: v.GetUint64("min-retain-blocks"), IAVLCacheSize: v.GetUint64("iavl-cache-size"), + AppDBBackend: v.GetString("app-db-backend"), }, Telemetry: telemetry.Config{ ServiceName: v.GetString("telemetry.service-name"), diff --git a/server/config/toml.go b/server/config/toml.go index f0f4ce5c88d0..9f1abc7419a0 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -75,6 +75,10 @@ index-events = [{{ range .BaseConfig.IndexEvents }}{{ printf "%q, " . }}{{end}}] # Default cache size is 50mb. iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }} +# AppDBBackend defines the database backend type to use for the application and snapshots DBs. +# An empty string indicates that DBs will have the same type as defined the config.toml's db-backend value. +app-db-backend = {{ .BaseConfig.AppDBBackend }} + ############################################################################### ### Telemetry Configuration ### ############################################################################### diff --git a/server/constructors_test.go b/server/constructors_test.go index 4f4990bf867a..646311b45720 100644 --- a/server/constructors_test.go +++ b/server/constructors_test.go @@ -11,7 +11,7 @@ import ( func Test_openDB(t *testing.T) { t.Parallel() - _, err := openDB(t.TempDir(), string(dbm.GoLevelDBBackend)) + _, err := openDB(t.TempDir(), dbm.GoLevelDBBackend) require.NoError(t, err) } diff --git a/server/export.go b/server/export.go index 65b990b30f97..512c3d86d284 100644 --- a/server/export.go +++ b/server/export.go @@ -37,7 +37,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com return err } - db, err := openDB(config.RootDir, config.DBBackend) + db, err := openDB(config.RootDir, GetAppDBBackend(serverCtx.Viper)) if err != nil { return err } diff --git a/server/start.go b/server/start.go index e72940f7d159..f563d726b07e 100644 --- a/server/start.go +++ b/server/start.go @@ -169,7 +169,7 @@ func startStandAlone(ctx *Context, appCreator types.AppCreator) error { transport := ctx.Viper.GetString(flagTransport) home := ctx.Viper.GetString(flags.FlagHome) - db, err := openDB(home, ctx.Viper.GetString("db-backend")) + db, err := openDB(home, GetAppDBBackend(ctx.Viper)) if err != nil { return err } @@ -228,12 +228,12 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App } } - traceWriterFile := ctx.Viper.GetString(flagTraceStore) - db, err := openDB(home, cfg.DBBackend) + db, err := openDB(home, GetAppDBBackend(ctx.Viper)) if err != nil { return err } + traceWriterFile := ctx.Viper.GetString(flagTraceStore) traceWriter, err := openTraceWriter(traceWriterFile) if err != nil { return err diff --git a/server/util.go b/server/util.go index 856b32d1a382..2beb896c6b81 100644 --- a/server/util.go +++ b/server/util.go @@ -16,6 +16,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -347,6 +348,18 @@ func WaitForQuitSignals() ErrorCode { return ErrorCode{Code: int(sig.(syscall.Signal)) + 128} } +// GetAppDBBackend gets the backend type to use for the application DBs. +func GetAppDBBackend(opts types.AppOptions) dbm.BackendType { + rv := cast.ToString(opts.Get("app-db-backend")) + if len(rv) == 0 { + rv = sdk.DBBackend + } + if len(rv) == 0 { + rv = cast.ToString(opts.Get("db-backend")) + } + return dbm.BackendType(rv) +} + func skipInterface(iface net.Interface) bool { if iface.Flags&net.FlagUp == 0 { return true // interface down @@ -371,9 +384,9 @@ func addrToIP(addr net.Addr) net.IP { return ip } -func openDB(rootDir, backendType string) (dbm.DB, error) { +func openDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) { dataDir := filepath.Join(rootDir, "data") - return dbm.NewDB("application", dbm.BackendType(backendType), dataDir) + return dbm.NewDB("application", backendType, dataDir) } func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { diff --git a/server/util_test.go b/server/util_test.go index 4a297af46097..159ce6f63ce1 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -11,14 +11,18 @@ import ( "testing" "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tmcfg "github.com/tendermint/tendermint/config" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/config" + servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" ) @@ -438,3 +442,84 @@ func TestEmptyMinGasPrices(t *testing.T) { err = cmd.ExecuteContext(ctx) require.Errorf(t, err, sdkerrors.ErrAppConfig.Error()) } + +type mapGetter map[string]interface{} + +func (m mapGetter) Get(key string) interface{} { + return m[key] +} + +var _ servertypes.AppOptions = mapGetter{} + +func TestGetAppDBBackend(t *testing.T) { + origDBBackend := types.DBBackend + defer func() { + types.DBBackend = origDBBackend + }() + tests := []struct { + name string + dbBack string + opts mapGetter + exp dbm.BackendType + }{ + { + name: "nothing set", + dbBack: "", + opts: mapGetter{}, + exp: dbm.BackendType(""), + }, + + { + name: "only db-backend set", + dbBack: "", + opts: mapGetter{"db-backend": "db-backend value 1"}, + exp: dbm.BackendType("db-backend value 1"), + }, + { + name: "only DBBackend set", + dbBack: "DBBackend value 2", + opts: mapGetter{}, + exp: dbm.BackendType("DBBackend value 2"), + }, + { + name: "only app-db-backend set", + dbBack: "", + opts: mapGetter{"app-db-backend": "app-db-backend value 3"}, + exp: dbm.BackendType("app-db-backend value 3"), + }, + + { + name: "app-db-backend and db-backend set", + dbBack: "", + opts: mapGetter{"db-backend": "db-backend value 4", "app-db-backend": "app-db-backend value 5"}, + exp: dbm.BackendType("app-db-backend value 5"), + }, + { + name: "app-db-backend and DBBackend set", + dbBack: "DBBackend value 6", + opts: mapGetter{"app-db-backend": "app-db-backend value 7"}, + exp: dbm.BackendType("app-db-backend value 7"), + }, + { + name: "db-backend and DBBackend set", + dbBack: "DBBackend value 8", + opts: mapGetter{"db-backend": "db-backend value 9"}, + exp: dbm.BackendType("DBBackend value 8"), + }, + + { + name: "all of app-db-backend db-backend DBBackend set", + dbBack: "DBBackend value 10", + opts: mapGetter{"db-backend": "db-backend value 11", "app-db-backend": "app-db-backend value 12"}, + exp: dbm.BackendType("app-db-backend value 12"), + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(st *testing.T) { + types.DBBackend = tc.dbBack + act := server.GetAppDBBackend(tc.opts) + assert.Equal(st, tc.exp, act) + }) + } +} diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 0a18b4516353..9ae7f10a7b48 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -261,7 +261,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a } snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") - snapshotDB, err := dbm.NewDB("metadata", dbm.BackendType(cast.ToString(appOpts.Get("db-backend"))), snapshotDir) + snapshotDB, err := dbm.NewDB("metadata", server.GetAppDBBackend(appOpts), snapshotDir) if err != nil { panic(err) } From e9ee9b77db5f6277396d206ce9aa759e43c9e3f3 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 28 Feb 2022 14:23:40 -0700 Subject: [PATCH 23/29] [10948]: Adjust the comment on the app-db-backend config entry to clarify fallback behavior. --- server/config/toml.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/config/toml.go b/server/config/toml.go index 9f1abc7419a0..fcd633b9dccd 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -76,7 +76,9 @@ index-events = [{{ range .BaseConfig.IndexEvents }}{{ printf "%q, " . }}{{end}}] iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }} # AppDBBackend defines the database backend type to use for the application and snapshots DBs. -# An empty string indicates that DBs will have the same type as defined the config.toml's db-backend value. +# An empty string indicates that a fallback will be used. +# First fallback is the deprecated compile-time types.DBBackend value. +# Second fallback (if the types.DBBackend also isn't set), is the db-backend value set in Tendermint's config.toml. app-db-backend = {{ .BaseConfig.AppDBBackend }} ############################################################################### From 4705c1c31424fb0ac16320caa7490dab1f0548d1 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 28 Feb 2022 14:40:47 -0700 Subject: [PATCH 24/29] [10948]: Add a default of GoLevelDBBackend to GetAppDBBackend. The old DBBackend variable defaulted to that, and some unit tests assume that behavior still exists. --- server/util.go | 5 ++++- server/util_test.go | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/server/util.go b/server/util.go index 2beb896c6b81..8b26913c7515 100644 --- a/server/util.go +++ b/server/util.go @@ -357,7 +357,10 @@ func GetAppDBBackend(opts types.AppOptions) dbm.BackendType { if len(rv) == 0 { rv = cast.ToString(opts.Get("db-backend")) } - return dbm.BackendType(rv) + if len(rv) != 0 { + return dbm.BackendType(rv) + } + return dbm.GoLevelDBBackend } func skipInterface(iface net.Interface) bool { diff --git a/server/util_test.go b/server/util_test.go index 159ce6f63ce1..3a4cb8138c98 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -466,7 +466,7 @@ func TestGetAppDBBackend(t *testing.T) { name: "nothing set", dbBack: "", opts: mapGetter{}, - exp: dbm.BackendType(""), + exp: dbm.GoLevelDBBackend, }, { From c8001e0ec12a131ac21292c2081d91e82d157aaa Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Mon, 28 Feb 2022 14:42:22 -0700 Subject: [PATCH 25/29] [10948]: Add the missing quotes around the app-db-backend value. --- 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 fcd633b9dccd..4b574b5e7849 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -79,7 +79,7 @@ iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }} # An empty string indicates that a fallback will be used. # First fallback is the deprecated compile-time types.DBBackend value. # Second fallback (if the types.DBBackend also isn't set), is the db-backend value set in Tendermint's config.toml. -app-db-backend = {{ .BaseConfig.AppDBBackend }} +app-db-backend = "{{ .BaseConfig.AppDBBackend }}" ############################################################################### ### Telemetry Configuration ### From e49f6c5edaac8ee7b27700907330ea309557e6fd Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Wed, 2 Mar 2022 11:10:55 -0700 Subject: [PATCH 26/29] [10948]: Small tweak to the changelog's deprecated entry. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cda54b9e4f9..dc4d53b9ffd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -238,7 +238,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Deprecated * (x/upgrade) [\#9906](https://github.com/cosmos/cosmos-sdk/pull/9906) Deprecate `UpgradeConsensusState` gRPC query since this functionality is only used for IBC, which now has its own [IBC replacement](https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) -* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Deprecate the types.DBBackend variable and types.NewLevelDB function. They are replaced by a new entry in `app.toml`: `app-db-backend` and `tendermint/tm-db`s NewDB function. If `app-db-backend` is defined, then it is used. Otherwise, if `types.DBBackend` is defined, it is used (until removed: [\#11241](https://github.com/cosmos/cosmos-sdk/issues/11241)). Otherwise, Tendermint config's `db-backend` is used. +* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Deprecate the types.DBBackend variable and types.NewLevelDB function. They are replaced by a new entry in `app.toml`: `app-db-backend` and `tendermint/tm-db`s `NewDB` function. If `app-db-backend` is defined, then it is used. Otherwise, if `types.DBBackend` is defined, it is used (until removed: [\#11241](https://github.com/cosmos/cosmos-sdk/issues/11241)). Otherwise, Tendermint config's `db-backend` is used. ## [v0.45.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.0) - 2022-01-18 From de2cb9b47346cee27b8f48640547e1a7dc3743fc Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Wed, 2 Mar 2022 15:11:06 -0700 Subject: [PATCH 27/29] Add the go version declaration back into the codeql-analysis github action. --- .github/workflows/codeql-analysis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f644d710faf9..c0aaf0f24cc2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,6 +21,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.17 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 6c6e38f741aa23032fe4289bf8f5f430151c714b Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 10 Mar 2022 14:09:20 -0700 Subject: [PATCH 28/29] [10948]: Update new use of openDB. --- server/rollback.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/rollback.go b/server/rollback.go index f10bcaead505..1413967d54b7 100644 --- a/server/rollback.go +++ b/server/rollback.go @@ -26,7 +26,7 @@ application. ctx := GetServerContextFromCmd(cmd) cfg := ctx.Config home := cfg.RootDir - db, err := openDB(home) + db, err := openDB(home, GetAppDBBackend(ctx.Viper)) if err != nil { return err } From 32f758b194f156513a29c1ca22074070f53406a4 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Tue, 15 Mar 2022 16:52:37 -0600 Subject: [PATCH 29/29] [10948]: Put a brief delay after closing the test network. Hopefully that helps with address-in-use and non-empty directory errors. --- testutil/network/network.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/testutil/network/network.go b/testutil/network/network.go index 4de1c7288144..c21c78d54fd5 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -603,6 +603,10 @@ func (n *Network) Cleanup() { } } + // Give a brief pause for things to finish closing in other processes. Hopefully this helps with the address-in-use errors. + // 100ms chosen randomly. + time.Sleep(100 * time.Millisecond) + if n.Config.CleanupDir { _ = os.RemoveAll(n.BaseDir) }