From 222de6fd16512bc95f2ebde13d786d4bb16fb7bc Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Wed, 17 Apr 2024 16:37:47 +0200 Subject: [PATCH 01/14] Change default chain directory --- .dockerignore | 2 +- .gitignore | 2 +- .../getting-started/local-setup/premining-balances.md | 2 +- .../local-setup/setting-up-a-local-chain.md | 4 ++-- docs/gno-tooling/cli/gnoland.md | 4 ++-- gno.land/Makefile | 2 +- gno.land/cmd/gnoland/start.go | 11 +---------- gnovm/pkg/doc/dirs_test.go | 2 +- misc/deployments/staging.gno.land/Makefile | 2 +- misc/deployments/staging.gno.land/docker-compose.yml | 2 +- misc/docker-compose/docker-compose.yml | 2 +- misc/loop/cmd/snapshotter.go | 2 +- misc/loop/scripts/start.sh | 10 +++++----- 13 files changed, 19 insertions(+), 28 deletions(-) diff --git a/.dockerignore b/.dockerignore index caecb619cd6..3f0865397bd 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,7 +12,7 @@ unsorted.* .DS_Store data/* proto/* -testdir/ +gno-chain/ pkgs/sdk/vm/_testdata build/* *.tx diff --git a/.gitignore b/.gitignore index d7e6d7eb9a4..b843674df97 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ cmd/foo.go unsorted.* .DS_Store data/* -testdir +gno-chain pkgs/sdk/vm/_testdata build *.tx diff --git a/docs/getting-started/local-setup/premining-balances.md b/docs/getting-started/local-setup/premining-balances.md index e7c0d6606ec..79e61032bb3 100644 --- a/docs/getting-started/local-setup/premining-balances.md +++ b/docs/getting-started/local-setup/premining-balances.md @@ -24,7 +24,7 @@ In order for us to premine funds on a fresh chain, we need to make sure we do no from previous chain runs. The blockchain node, when it runs, works with an embedded DB locally on disk to store execution data (such as -configuration files, or the state DB). For Gno blockchain nodes, this working directory is labeled as `testdir` by +configuration files, or the state DB). For Gno blockchain nodes, this working directory is labeled as `gno-chain` by default. To clean out old blockchain data, navigate to the `gno.land` folder and run the appropriate make command: diff --git a/docs/getting-started/local-setup/setting-up-a-local-chain.md b/docs/getting-started/local-setup/setting-up-a-local-chain.md index e999071a589..23b4e110820 100644 --- a/docs/getting-started/local-setup/setting-up-a-local-chain.md +++ b/docs/getting-started/local-setup/setting-up-a-local-chain.md @@ -42,11 +42,11 @@ Let's break down the most important default settings: - `genesis-balances-file` - the initial premine balances file, which contains initial native currency allocations for the chain. By default, the genesis balances file is located in `gno.land/genesis/genesis_balances.txt`, this is also the reason why we need to navigate to the `gno.land` sub-folder to run the command with default settings -- `root-dir` - the working directory for the node configuration and node data (state DB) +- `data-dir` - the working directory for the node configuration and node data (state DB) :::info Resetting the chain -As mentioned, the working directory for the node is located in `root-dir`. To reset the chain, you need +As mentioned, the working directory for the node is located in `data-dir`. To reset the chain, you need to delete this directory and start the node up again. If you are using the default node configuration, you can run `make fclean` from the `gno.land` sub-folder to delete the `tempdir` working directory. diff --git a/docs/gno-tooling/cli/gnoland.md b/docs/gno-tooling/cli/gnoland.md index 9dbb22cd9c5..f5320f2d9e9 100644 --- a/docs/gno-tooling/cli/gnoland.md +++ b/docs/gno-tooling/cli/gnoland.md @@ -21,11 +21,11 @@ gnoland ### **Options** | Name | Type | Description | -| -------------------------- | ------- | --------------------------------------------------------------------------------------- | +|----------------------------| ------- | --------------------------------------------------------------------------------------- | | `chainid` | String | The id of the chain (default: `dev`). | | `genesis-balances-file` | String | The initial GNOT distribution file (default: `./gnoland/genesis/genesis_balances.txt`). | | `genesis-remote` | String | Replacement '%%REMOTE%%' in genesis (default: `"localhost:26657"`). | | `genesis-txs-file` | String | Initial txs to be executed (default: `"./gnoland/genesis/genesis_txs.jsonl"`). | -| `root-dir` | String | directory for config and data (default: `testdir`). | +| `data-dir` | String | directory for config and data (default: `gno-chain`). | | `skip-failing-genesis-txs` | Boolean | Skips transactions that fail from the `genesis-txs-file` | | `skip-start` | Boolean | Quits after initialization without starting the node. | diff --git a/gno.land/Makefile b/gno.land/Makefile index ce19471ec50..5486ef04bc4 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -53,7 +53,7 @@ install.genesis:; go install ./cmd/genesis .PHONY: fclean fclean: clean - rm -rf testdir + rm -rf gno-chain .PHONY: clean clean: diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index a991e2e0dc0..8489f4f533d 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -121,11 +121,10 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { "the root directory of the gno repository", ) - // XXX: Use home directory for this fs.StringVar( &c.dataDir, "data-dir", - "testdir", + "gno-chain", "directory for config and data", ) @@ -193,14 +192,6 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { log.ConsoleFormat.String(), "log format for the gnoland node", ) - - // XXX(deprecated): use data-dir instead - fs.StringVar( - &c.dataDir, - "root-dir", - "testdir", - "deprecated: use data-dir instead - directory for config and data", - ) } func execStart(c *startCfg, io commands.IO) error { diff --git a/gnovm/pkg/doc/dirs_test.go b/gnovm/pkg/doc/dirs_test.go index 41f3409a08b..f65e1282f2d 100644 --- a/gnovm/pkg/doc/dirs_test.go +++ b/gnovm/pkg/doc/dirs_test.go @@ -100,7 +100,7 @@ func TestDirs_findPackage(t *testing.T) { }}, {"alpha", []bfsDir{ {importPath: "dirs.mod/dep/alpha", dir: filepath.Join(td, "dirsdep/pkg/mod/dirs.mod/dep/alpha")}, - // no testdir/module/alpha as it is inside a module + // no gno-chain/module/alpha as it is inside a module }}, {"math", []bfsDir{ {importPath: "math", dir: filepath.Join(td, "dirs/math")}, diff --git a/misc/deployments/staging.gno.land/Makefile b/misc/deployments/staging.gno.land/Makefile index 516be6dfc0e..9c712a32bb7 100644 --- a/misc/deployments/staging.gno.land/Makefile +++ b/misc/deployments/staging.gno.land/Makefile @@ -11,7 +11,7 @@ logs: down: docker compose down docker volume rm -f staginggnoland_gnonode - docker compose run gnoland rm -rf /opt/gno/src/gno.land/testdir/data /opt/gno/src/gno.land/testdir/config + docker compose run gnoland rm -rf /opt/gno/src/gno.land/gno-chain/data /opt/gno/src/gno.land/gno-chain/config pull: git pull diff --git a/misc/deployments/staging.gno.land/docker-compose.yml b/misc/deployments/staging.gno.land/docker-compose.yml index bf825b54536..0297597dcaa 100644 --- a/misc/deployments/staging.gno.land/docker-compose.yml +++ b/misc/deployments/staging.gno.land/docker-compose.yml @@ -17,7 +17,7 @@ services: - --chainid=staging - --genesis-remote=staging.gno.land:36657 volumes: - - "./data/gnoland:/opt/gno/src/gno.land/testdir" + - "./data/gnoland:/opt/gno/src/gno.land/gno-chain" ports: - 36656:36656 - 36657:36657 diff --git a/misc/docker-compose/docker-compose.yml b/misc/docker-compose/docker-compose.yml index 26ef50913ff..1185e10760f 100644 --- a/misc/docker-compose/docker-compose.yml +++ b/misc/docker-compose/docker-compose.yml @@ -9,7 +9,7 @@ services: - LOG_LEVEL=4 command: [ "gnoland", "start" ] volumes: - - "gnonode:/opt/gno/src/testdir" + - "gnonode:/opt/gno/src/gno-chain" networks: - gnonode restart: on-failure diff --git a/misc/loop/cmd/snapshotter.go b/misc/loop/cmd/snapshotter.go index 2de28906e7e..e57a5c12b02 100644 --- a/misc/loop/cmd/snapshotter.go +++ b/misc/loop/cmd/snapshotter.go @@ -162,7 +162,7 @@ func (s snapshotter) startPortalLoopContainer(ctx context.Context) (*types.Conta Binds: []string{ fmt.Sprintf("%s/scripts:/scripts", s.cfg.hostPWD), fmt.Sprintf("%s/backups:/backups", s.cfg.hostPWD), - fmt.Sprintf("%s:/opt/gno/src/testdir", s.containerName), + fmt.Sprintf("%s:/opt/gno/src/gno-chain", s.containerName), }, }, nil, nil, s.containerName) if err != nil { diff --git a/misc/loop/scripts/start.sh b/misc/loop/scripts/start.sh index d50b3175932..cdf34e2d6e1 100755 --- a/misc/loop/scripts/start.sh +++ b/misc/loop/scripts/start.sh @@ -19,11 +19,11 @@ gnoland start \ --skip-start=true \ --skip-failing-genesis-txs -sed -i "s#^moniker = \".*\"#moniker = \"${MONIKER}\"#" ./testdir/config/config.toml -sed -i "s#laddr = \".*:26656\"#laddr = \"${P2P_LADDR}\"#" ./testdir/config/config.toml -sed -i "s#laddr = \".*:26657\"#laddr = \"${RPC_LADDR}\"#" ./testdir/config/config.toml +sed -i "s#^moniker = \".*\"#moniker = \"${MONIKER}\"#" ./gno-chain/config/config.toml +sed -i "s#laddr = \".*:26656\"#laddr = \"${P2P_LADDR}\"#" ./gno-chain/config/config.toml +sed -i "s#laddr = \".*:26657\"#laddr = \"${RPC_LADDR}\"#" ./gno-chain/config/config.toml -sed -i "s#seeds = \".*\"#seeds = \"${SEEDS}\"#" ./testdir/config/config.toml -sed -i "s#persistent_peers = \".*\"#persistent_peers = \"${PERSISTENT_PEERS}\"#" ./testdir/config/config.toml +sed -i "s#seeds = \".*\"#seeds = \"${SEEDS}\"#" ./gno-chain/config/config.toml +sed -i "s#persistent_peers = \".*\"#persistent_peers = \"${PERSISTENT_PEERS}\"#" ./gno-chain/config/config.toml exec gnoland start --skip-failing-genesis-txs From fe77f99f83c765894d280a4ca9e9fa5f39695bb0 Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Wed, 17 Apr 2024 20:31:13 +0200 Subject: [PATCH 02/14] Utilize absolute paths for critical node files, standardize the directory structure --- .dockerignore | 33 ++++++++++++------ .gitignore | 19 +++++++---- gno.land/Makefile | 2 +- gno.land/cmd/gnoland/start.go | 16 ++++++--- gno.land/pkg/gnoland/node_inmemory.go | 28 --------------- tm2/pkg/bft/config/config.go | 47 ++++++++++++++++---------- tm2/pkg/bft/config/config_test.go | 7 ++-- tm2/pkg/bft/config/toml.go | 18 ++++++---- tm2/pkg/bft/config/toml_test.go | 36 ++++++++++++-------- tm2/pkg/bft/config/utils.go | 11 ------ tm2/pkg/bft/consensus/config/config.go | 3 +- tm2/pkg/bft/consensus/config/utils.go | 11 ------ 12 files changed, 115 insertions(+), 116 deletions(-) delete mode 100644 tm2/pkg/bft/config/utils.go delete mode 100644 tm2/pkg/bft/consensus/config/utils.go diff --git a/.dockerignore b/.dockerignore index 3f0865397bd..82fd51cd5a5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,22 +5,33 @@ misc/ docker-compose.yml tests/docker-integration/ -# gitignore -*.sw[pon] -cmd/foo.go -unsorted.* +# Copied from .gitignore + +# Editor Leftovers .DS_Store -data/* -proto/* -gno-chain/ -pkgs/sdk/vm/_testdata -build/* +.vscode +.idea + +# Default node data +gno-chain +genesis.json + +# Build leftovers +build + +# Log + generation leftovers *.tx *.log.* *.log *.gno.gen.go *.gno.gen_test.go -.vscode -.idea *.pb.go pbbindings.go +*~ +.#* +*# + +# Test coverage leftovers +cover.out +coverage.out + diff --git a/.gitignore b/.gitignore index b843674df97..77e90213581 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,27 @@ -*.sw[pon] -cmd/foo.go -unsorted.* +# Editor Leftovers .DS_Store -data/* +.vscode +.idea + +# Default node data gno-chain -pkgs/sdk/vm/_testdata +genesis.json + +# Build leftovers build + +# Log + generation leftovers *.tx *.log.* *.log *.gno.gen.go *.gno.gen_test.go -.vscode -.idea *.pb.go pbbindings.go *~ .#* *# + +# Test coverage leftovers cover.out coverage.out diff --git a/gno.land/Makefile b/gno.land/Makefile index 5486ef04bc4..a76c8441efa 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -53,7 +53,7 @@ install.genesis:; go install ./cmd/genesis .PHONY: fclean fclean: clean - rm -rf gno-chain + rm -rf gno-chain genesis.json .PHONY: clean clean: diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 8489f4f533d..06e7c8d82c7 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -125,7 +125,7 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { &c.dataDir, "data-dir", "gno-chain", - "directory for config and data", + "the path to the node's data directory", ) fs.StringVar( @@ -195,7 +195,11 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { } func execStart(c *startCfg, io commands.IO) error { - dataDir := c.dataDir + // Get the absolute path to the node's data directory + nodeDir, err := filepath.Abs(c.dataDir) + if err != nil { + return fmt.Errorf("unable to get absolute path for data directory, %w", err) + } var ( cfg *config.Config @@ -215,7 +219,7 @@ func execStart(c *startCfg, io commands.IO) error { cfg, loadCfgErr = config.LoadConfigFile(c.nodeConfigPath) } else { // Load the default node configuration - cfg, loadCfgErr = config.LoadOrMakeConfigWithOptions(dataDir) + cfg, loadCfgErr = config.LoadOrMakeConfigWithOptions(nodeDir) } if loadCfgErr != nil { @@ -238,7 +242,9 @@ func execStart(c *startCfg, io commands.IO) error { logger := log.ZapLoggerToSlog(zapLogger) // Write genesis file if missing. - genesisFilePath := filepath.Join(dataDir, cfg.Genesis) + // NOTE: this will be dropped in a PR that resolves issue #1883: + // https://github.com/gnolang/gno/issues/1883 + genesisFilePath := filepath.Join(nodeDir, "../", cfg.Genesis) if !osm.FileExists(genesisFilePath) { // Create priv validator first. @@ -262,7 +268,7 @@ func execStart(c *startCfg, io commands.IO) error { cfg.TxEventStore = txEventStoreCfg // Create application and node. - gnoApp, err := gnoland.NewApp(dataDir, c.skipFailingGenesisTxs, logger, c.genesisMaxVMCycles) + gnoApp, err := gnoland.NewApp(nodeDir, c.skipFailingGenesisTxs, logger, c.genesisMaxVMCycles) if err != nil { return fmt.Errorf("error in creating new app: %w", err) } diff --git a/gno.land/pkg/gnoland/node_inmemory.go b/gno.land/pkg/gnoland/node_inmemory.go index d48d0e2ab47..05ed59ee491 100644 --- a/gno.land/pkg/gnoland/node_inmemory.go +++ b/gno.land/pkg/gnoland/node_inmemory.go @@ -59,34 +59,6 @@ func NewDefaultTMConfig(rootdir string) *tmcfg.Config { return tmcfg.TestConfig().SetRootDir(rootdir) } -// NewInMemoryNodeConfig creates a default configuration for an in-memory node. -func NewDefaultInMemoryNodeConfig(rootdir string) *InMemoryNodeConfig { - tm := NewDefaultTMConfig(rootdir) - - // Create Mocked Identity - pv := NewMockedPrivValidator() - genesis := NewDefaultGenesisConfig(pv.GetPubKey(), tm.ChainID()) - - // Add self as validator - self := pv.GetPubKey() - genesis.Validators = []bft.GenesisValidator{ - { - Address: self.Address(), - PubKey: self, - Power: 10, - Name: "self", - }, - } - - return &InMemoryNodeConfig{ - PrivValidator: pv, - TMConfig: tm, - Genesis: genesis, - GenesisTxHandler: PanicOnFailingTxHandler, - GenesisMaxVMCycles: 10_000_000, - } -} - func (cfg *InMemoryNodeConfig) validate() error { if cfg.PrivValidator == nil { return fmt.Errorf("`PrivValidator` is required but not provided") diff --git a/tm2/pkg/bft/config/config.go b/tm2/pkg/bft/config/config.go index 85db5ecc3ae..6bf94e2d605 100644 --- a/tm2/pkg/bft/config/config.go +++ b/tm2/pkg/bft/config/config.go @@ -77,7 +77,7 @@ func LoadOrMakeConfigWithOptions(root string, opts ...Option) (*Config, error) { // Initialize the config as default var ( cfg = DefaultConfig() - configPath = join(root, defaultConfigFilePath) + configPath = filepath.Join(root, defaultConfigFileName) ) // Config doesn't exist, create it @@ -161,7 +161,7 @@ func (cfg *Config) EnsureDirs() error { return fmt.Errorf("no root directory, %w", err) } - if err := osm.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { + if err := osm.EnsureDir(filepath.Join(rootDir, defaultSecretsDir), DefaultDirPerm); err != nil { return fmt.Errorf("no config directory, %w", err) } @@ -196,9 +196,24 @@ func (cfg *Config) ValidateBasic() error { // ----------------------------------------------------------------------------- // BaseConfig +// Base node data structure: +// . +// ├── genesis.json (required) +// └── my-node-dir/ +// ├── data/ +// │ ├── blockstore.db (folder) +// │ ├── gnolang.db (folder) +// │ ├── state.db (folder) +// │ └── cs.wal +// ├── secrets/ +// │ ├── priv_validator_state.json +// │ ├── node_key.json +// │ └── priv_validator_key.json +// └── config.toml (optional) + var ( - defaultConfigDir = "config" - defaultDataDir = "data" + defaultDataDir = "data" + defaultSecretsDir = "secrets" defaultConfigFileName = "config.toml" defaultGenesisJSONName = "genesis.json" @@ -206,11 +221,9 @@ var ( defaultPrivValKeyName = "priv_validator_key.json" defaultPrivValStateName = "priv_validator_state.json" - defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) - defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) - defaultPrivValKeyPath = filepath.Join(defaultConfigDir, defaultPrivValKeyName) - defaultPrivValStatePath = filepath.Join(defaultDataDir, defaultPrivValStateName) - defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) + defaultPrivValKeyPath = filepath.Join(defaultSecretsDir, defaultPrivValKeyName) + defaultPrivValStatePath = filepath.Join(defaultSecretsDir, defaultPrivValStateName) + defaultNodeKeyPath = filepath.Join(defaultSecretsDir, defaultNodeKeyName) ) // BaseConfig defines the base configuration for a Tendermint node @@ -285,7 +298,7 @@ type BaseConfig struct { // DefaultBaseConfig returns a default base configuration for a Tendermint node func DefaultBaseConfig() BaseConfig { return BaseConfig{ - Genesis: defaultGenesisJSONPath, + Genesis: defaultGenesisJSONName, PrivValidatorKey: defaultPrivValKeyPath, PrivValidatorState: defaultPrivValStatePath, NodeKey: defaultNodeKeyPath, @@ -296,7 +309,7 @@ func DefaultBaseConfig() BaseConfig { FastSyncMode: true, FilterPeers: false, DBBackend: db.GoLevelDBBackend.String(), - DBPath: "data", + DBPath: defaultDataDir, } } @@ -316,27 +329,27 @@ func (cfg BaseConfig) ChainID() string { // GenesisFile returns the full path to the genesis.json file func (cfg BaseConfig) GenesisFile() string { - return join(cfg.RootDir, cfg.Genesis) + return filepath.Join(cfg.RootDir, "../", defaultGenesisJSONName) } // PrivValidatorKeyFile returns the full path to the priv_validator_key.json file func (cfg BaseConfig) PrivValidatorKeyFile() string { - return join(cfg.RootDir, cfg.PrivValidatorKey) + return filepath.Join(cfg.RootDir, cfg.PrivValidatorKey) } -// PrivValidatorFile returns the full path to the priv_validator_state.json file +// PrivValidatorStateFile returns the full path to the priv_validator_state.json file func (cfg BaseConfig) PrivValidatorStateFile() string { - return join(cfg.RootDir, cfg.PrivValidatorState) + return filepath.Join(cfg.RootDir, cfg.PrivValidatorState) } // NodeKeyFile returns the full path to the node_key.json file func (cfg BaseConfig) NodeKeyFile() string { - return join(cfg.RootDir, cfg.NodeKey) + return filepath.Join(cfg.RootDir, cfg.NodeKey) } // DBDir returns the full path to the database directory func (cfg BaseConfig) DBDir() string { - return join(cfg.RootDir, cfg.DBPath) + return filepath.Join(cfg.RootDir, cfg.DBPath) } var defaultMoniker = getDefaultMoniker() diff --git a/tm2/pkg/bft/config/config_test.go b/tm2/pkg/bft/config/config_test.go index adeeade26b3..501d87431b7 100644 --- a/tm2/pkg/bft/config/config_test.go +++ b/tm2/pkg/bft/config/config_test.go @@ -1,6 +1,7 @@ package config import ( + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -15,7 +16,7 @@ func TestConfig_LoadOrMakeConfigWithOptions(t *testing.T) { // Provide an empty directory cfgDir := t.TempDir() - cfgPath := join(cfgDir, defaultConfigFilePath) + cfgPath := filepath.Join(cfgDir, defaultConfigFileName) // Create a default config cfg := DefaultConfig() @@ -42,7 +43,7 @@ func TestConfig_LoadOrMakeConfigWithOptions(t *testing.T) { // Provide an empty directory cfgDir := t.TempDir() - cfgPath := join(cfgDir, defaultConfigFilePath) + cfgPath := filepath.Join(cfgDir, defaultConfigFileName) cfg, err := LoadOrMakeConfigWithOptions(cfgDir) require.NoError(t, err) @@ -69,7 +70,7 @@ func TestConfig_LoadOrMakeConfigWithOptions(t *testing.T) { // Provide an empty directory cfgDir := t.TempDir() - cfgPath := join(cfgDir, defaultConfigFilePath) + cfgPath := filepath.Join(cfgDir, defaultConfigFileName) cfg, err := LoadOrMakeConfigWithOptions( cfgDir, diff --git a/tm2/pkg/bft/config/toml.go b/tm2/pkg/bft/config/toml.go index f813d23b8fb..e2dbf6597f1 100644 --- a/tm2/pkg/bft/config/toml.go +++ b/tm2/pkg/bft/config/toml.go @@ -55,17 +55,21 @@ func WriteConfigFile(configFilePath string, config *Config) error { /****** these are for test settings ***********/ func ResetTestRoot(testName string) *Config { - return ResetTestRootWithChainID(testName, "") -} + chainID := "test-chain" -func ResetTestRootWithChainID(testName string, chainID string) *Config { // create a unique, concurrency-safe test directory under os.TempDir() - rootDir, err := os.MkdirTemp("", fmt.Sprintf("%s-%s_", chainID, testName)) + testDir, err := os.MkdirTemp("", "") + if err != nil { + panic(err) + } + + rootDir, err := os.MkdirTemp(testDir, fmt.Sprintf("%s-%s_", chainID, testName)) if err != nil { panic(err) } + // ensure config and data subdirs are created - if err := osm.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { + if err := osm.EnsureDir(filepath.Join(rootDir, defaultSecretsDir), DefaultDirPerm); err != nil { panic(err) } if err := osm.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { @@ -73,8 +77,8 @@ func ResetTestRootWithChainID(testName string, chainID string) *Config { } baseConfig := DefaultBaseConfig() - configFilePath := filepath.Join(rootDir, defaultConfigFilePath) - genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) + configFilePath := filepath.Join(rootDir, defaultConfigFileName) + genesisFilePath := filepath.Join(rootDir, "../", baseConfig.Genesis) privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey) privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState) diff --git a/tm2/pkg/bft/config/toml_test.go b/tm2/pkg/bft/config/toml_test.go index b75057a52dd..a95fbfa4351 100644 --- a/tm2/pkg/bft/config/toml_test.go +++ b/tm2/pkg/bft/config/toml_test.go @@ -3,6 +3,7 @@ package config import ( "io" "os" + "path/filepath" "reflect" "strings" "testing" @@ -17,7 +18,7 @@ func ensureFiles(t *testing.T, rootDir string, files ...string) { t.Helper() for _, f := range files { - p := join(f, rootDir) + p := filepath.Join(rootDir, f) _, err := os.Stat(p) assert.Nil(t, err, p) } @@ -33,16 +34,15 @@ func TestEnsureRoot(t *testing.T) { throwaway := DefaultConfig() throwaway.SetRootDir(tmpDir) require.NoError(t, throwaway.EnsureDirs()) - configPath := join(tmpDir, defaultConfigFilePath) + + configPath := filepath.Join(tmpDir, defaultConfigFileName) require.NoError(t, WriteConfigFile(configPath, throwaway)) // make sure config is set properly - data, err := os.ReadFile(join(tmpDir, defaultConfigFilePath)) + data, err := os.ReadFile(filepath.Join(tmpDir, defaultConfigFileName)) require.Nil(t, err) - if !checkConfig(string(data)) { - t.Fatalf("config file missing some information") - } + require.True(t, checkConfig(string(data))) ensureFiles(t, tmpDir, "data") } @@ -50,8 +50,6 @@ func TestEnsureRoot(t *testing.T) { func TestEnsureTestRoot(t *testing.T) { t.Parallel() - require := require.New(t) - testName := "ensureTestRoot" // create root dir @@ -60,16 +58,26 @@ func TestEnsureTestRoot(t *testing.T) { rootDir := cfg.RootDir // make sure config is set properly - data, err := os.ReadFile(join(rootDir, defaultConfigFilePath)) - require.Nil(err) + data, err := os.ReadFile(filepath.Join(rootDir, defaultConfigFileName)) + require.Nil(t, err) - if !checkConfig(string(data)) { - t.Fatalf("config file missing some information") - } + require.True(t, checkConfig(string(data))) // TODO: make sure the cfg returned and testconfig are the same! baseConfig := DefaultBaseConfig() - ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidatorKey, baseConfig.PrivValidatorState) + ensureFiles( + t, + rootDir, + defaultDataDir, + baseConfig.PrivValidatorKey, + baseConfig.PrivValidatorState, + ) + + ensureFiles( + t, + filepath.Join(rootDir, ".."), + baseConfig.Genesis, + ) } func checkConfig(configFile string) bool { diff --git a/tm2/pkg/bft/config/utils.go b/tm2/pkg/bft/config/utils.go deleted file mode 100644 index 5a6eec09e43..00000000000 --- a/tm2/pkg/bft/config/utils.go +++ /dev/null @@ -1,11 +0,0 @@ -package config - -import "path/filepath" - -// helper function to make config creation independent of root dir -func join(root, path string) string { - if filepath.IsAbs(path) { - return path - } - return filepath.Join(root, path) -} diff --git a/tm2/pkg/bft/consensus/config/config.go b/tm2/pkg/bft/consensus/config/config.go index cda4c63ae28..aacb63c2c92 100644 --- a/tm2/pkg/bft/consensus/config/config.go +++ b/tm2/pkg/bft/consensus/config/config.go @@ -112,7 +112,8 @@ func (cfg *ConsensusConfig) WalFile() string { if cfg.walFile != "" { return cfg.walFile } - return join(cfg.RootDir, cfg.WALPath) + + return filepath.Join(cfg.RootDir, cfg.WALPath) } // SetWalFile sets the path to the write-ahead log file diff --git a/tm2/pkg/bft/consensus/config/utils.go b/tm2/pkg/bft/consensus/config/utils.go deleted file mode 100644 index 5ba8c40b082..00000000000 --- a/tm2/pkg/bft/consensus/config/utils.go +++ /dev/null @@ -1,11 +0,0 @@ -package config - -import "path/filepath" - -// join path to root unless path is already absolute. -func join(root, path string) string { - if filepath.IsAbs(path) { - return path - } - return filepath.Join(root, path) -} From 57984e4202ac452e6f1058194c1ec0daff793166 Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Fri, 19 Apr 2024 15:35:56 +0200 Subject: [PATCH 03/14] Return back the legacy gitignore options --- .dockerignore | 5 ++++- .gitignore | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 82fd51cd5a5..bdc5a52139a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,6 +19,10 @@ genesis.json # Build leftovers build +# Legacy .gitignore +data/* +testdir + # Log + generation leftovers *.tx *.log.* @@ -34,4 +38,3 @@ pbbindings.go # Test coverage leftovers cover.out coverage.out - diff --git a/.gitignore b/.gitignore index 77e90213581..219d2b6c346 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,10 @@ genesis.json # Build leftovers build +# Legacy .gitignore +data/* +testdir + # Log + generation leftovers *.tx *.log.* From 8d2bca4ce2974820f9f283c596df30113a56dc60 Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Fri, 19 Apr 2024 15:50:16 +0200 Subject: [PATCH 04/14] Move directory comment --- tm2/pkg/bft/config/config.go | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/tm2/pkg/bft/config/config.go b/tm2/pkg/bft/config/config.go index 6bf94e2d605..356a70eeb25 100644 --- a/tm2/pkg/bft/config/config.go +++ b/tm2/pkg/bft/config/config.go @@ -194,22 +194,6 @@ func (cfg *Config) ValidateBasic() error { } // ----------------------------------------------------------------------------- -// BaseConfig - -// Base node data structure: -// . -// ├── genesis.json (required) -// └── my-node-dir/ -// ├── data/ -// │ ├── blockstore.db (folder) -// │ ├── gnolang.db (folder) -// │ ├── state.db (folder) -// │ └── cs.wal -// ├── secrets/ -// │ ├── priv_validator_state.json -// │ ├── node_key.json -// │ └── priv_validator_key.json -// └── config.toml (optional) var ( defaultDataDir = "data" @@ -226,13 +210,24 @@ var ( defaultNodeKeyPath = filepath.Join(defaultSecretsDir, defaultNodeKeyName) ) -// BaseConfig defines the base configuration for a Tendermint node +// BaseConfig defines the base configuration for a Tendermint node. type BaseConfig struct { // chainID is unexposed and immutable but here for convenience chainID string // The root directory for all data. - // This should be set in viper so it can unmarshal into this struct + // The node directory contains: + // + // ┌── db/ + // │ ├── blockstore.db (folder) + // │ ├── gnolang.db (folder) + // │ ├── state.db (folder) + // │ └── cs.wal + // ├── secrets/ + // │ ├── priv_validator_state.json + // │ ├── node_key.json + // │ └── priv_validator_key.json + // └── config.toml (optional) RootDir string `toml:"home"` // TCP or UNIX socket address of the ABCI application, From fc5f30a28ed06adc96f5aba1353b4528bfc8a3be Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Fri, 19 Apr 2024 16:17:36 +0200 Subject: [PATCH 05/14] Change data to db, separate out WAL, change default name to gnoland-data --- .dockerignore | 2 +- .gitignore | 2 +- .../getting-started/local-setup/premining-balances.md | 2 +- docs/gno-tooling/cli/gnoland.md | 2 +- gno.land/Makefile | 2 +- gno.land/cmd/gnoland/start.go | 2 +- gno.land/pkg/gnoland/app.go | 3 ++- gnovm/pkg/doc/dirs_test.go | 2 +- misc/deployments/staging.gno.land/Makefile | 2 +- misc/deployments/staging.gno.land/docker-compose.yml | 2 +- misc/docker-compose/docker-compose.yml | 2 +- misc/loop/cmd/snapshotter.go | 2 +- misc/loop/scripts/start.sh | 10 +++++----- tm2/pkg/bft/config/config.go | 11 ++++++----- tm2/pkg/bft/config/toml.go | 2 +- tm2/pkg/bft/config/toml_test.go | 4 ++-- tm2/pkg/bft/consensus/config/config.go | 4 ++-- tm2/pkg/crypto/keys/utils.go | 4 +++- 18 files changed, 32 insertions(+), 28 deletions(-) diff --git a/.dockerignore b/.dockerignore index bdc5a52139a..a45b7bafa98 100644 --- a/.dockerignore +++ b/.dockerignore @@ -13,7 +13,7 @@ tests/docker-integration/ .idea # Default node data -gno-chain +gnoland-data genesis.json # Build leftovers diff --git a/.gitignore b/.gitignore index 219d2b6c346..0a06c2cf055 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ .idea # Default node data -gno-chain +gnoland-data genesis.json # Build leftovers diff --git a/docs/getting-started/local-setup/premining-balances.md b/docs/getting-started/local-setup/premining-balances.md index 79e61032bb3..7117f8d5cdd 100644 --- a/docs/getting-started/local-setup/premining-balances.md +++ b/docs/getting-started/local-setup/premining-balances.md @@ -24,7 +24,7 @@ In order for us to premine funds on a fresh chain, we need to make sure we do no from previous chain runs. The blockchain node, when it runs, works with an embedded DB locally on disk to store execution data (such as -configuration files, or the state DB). For Gno blockchain nodes, this working directory is labeled as `gno-chain` by +configuration files, or the state DB). For Gno blockchain nodes, this working directory is labeled as `gnoland-data` by default. To clean out old blockchain data, navigate to the `gno.land` folder and run the appropriate make command: diff --git a/docs/gno-tooling/cli/gnoland.md b/docs/gno-tooling/cli/gnoland.md index f5320f2d9e9..9bd722b0f2c 100644 --- a/docs/gno-tooling/cli/gnoland.md +++ b/docs/gno-tooling/cli/gnoland.md @@ -26,6 +26,6 @@ gnoland | `genesis-balances-file` | String | The initial GNOT distribution file (default: `./gnoland/genesis/genesis_balances.txt`). | | `genesis-remote` | String | Replacement '%%REMOTE%%' in genesis (default: `"localhost:26657"`). | | `genesis-txs-file` | String | Initial txs to be executed (default: `"./gnoland/genesis/genesis_txs.jsonl"`). | -| `data-dir` | String | directory for config and data (default: `gno-chain`). | +| `data-dir` | String | directory for config and data (default: `gnoland-data`). | | `skip-failing-genesis-txs` | Boolean | Skips transactions that fail from the `genesis-txs-file` | | `skip-start` | Boolean | Quits after initialization without starting the node. | diff --git a/gno.land/Makefile b/gno.land/Makefile index bad6d5df77b..88fe3b396c0 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -49,7 +49,7 @@ install.gnokey:; go install ./cmd/gnokey .PHONY: fclean fclean: clean - rm -rf gno-chain genesis.json + rm -rf gnoland-data genesis.json .PHONY: clean clean: diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 06e7c8d82c7..f330b828da6 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -124,7 +124,7 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { fs.StringVar( &c.dataDir, "data-dir", - "gno-chain", + "gnoland-data", "the path to the node's data directory", ) diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index d1978e76563..ee007c058a1 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -8,6 +8,7 @@ import ( "github.com/gnolang/gno/gno.land/pkg/sdk/vm" "github.com/gnolang/gno/gnovm/pkg/gnoenv" abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" + "github.com/gnolang/gno/tm2/pkg/bft/config" dbm "github.com/gnolang/gno/tm2/pkg/db" "github.com/gnolang/gno/tm2/pkg/log" "github.com/gnolang/gno/tm2/pkg/sdk" @@ -132,7 +133,7 @@ func NewApp(dataRootDir string, skipFailingGenesisTxs bool, logger *slog.Logger, } // Get main DB. - cfg.DB, err = dbm.NewDB("gnolang", dbm.GoLevelDBBackend, filepath.Join(dataRootDir, "data")) + cfg.DB, err = dbm.NewDB("gnolang", dbm.GoLevelDBBackend, filepath.Join(dataRootDir, config.DefaultDBDir)) if err != nil { return nil, fmt.Errorf("error initializing database %q using path %q: %w", dbm.GoLevelDBBackend, dataRootDir, err) } diff --git a/gnovm/pkg/doc/dirs_test.go b/gnovm/pkg/doc/dirs_test.go index f65e1282f2d..8659f3cbfcb 100644 --- a/gnovm/pkg/doc/dirs_test.go +++ b/gnovm/pkg/doc/dirs_test.go @@ -100,7 +100,7 @@ func TestDirs_findPackage(t *testing.T) { }}, {"alpha", []bfsDir{ {importPath: "dirs.mod/dep/alpha", dir: filepath.Join(td, "dirsdep/pkg/mod/dirs.mod/dep/alpha")}, - // no gno-chain/module/alpha as it is inside a module + // no gnoland-data/module/alpha as it is inside a module }}, {"math", []bfsDir{ {importPath: "math", dir: filepath.Join(td, "dirs/math")}, diff --git a/misc/deployments/staging.gno.land/Makefile b/misc/deployments/staging.gno.land/Makefile index 9c712a32bb7..6ad76a0480a 100644 --- a/misc/deployments/staging.gno.land/Makefile +++ b/misc/deployments/staging.gno.land/Makefile @@ -11,7 +11,7 @@ logs: down: docker compose down docker volume rm -f staginggnoland_gnonode - docker compose run gnoland rm -rf /opt/gno/src/gno.land/gno-chain/data /opt/gno/src/gno.land/gno-chain/config + docker compose run gnoland rm -rf /opt/gno/src/gno.land/gnoland-data/data /opt/gno/src/gno.land/gnoland-data/config pull: git pull diff --git a/misc/deployments/staging.gno.land/docker-compose.yml b/misc/deployments/staging.gno.land/docker-compose.yml index 0297597dcaa..991a102b691 100644 --- a/misc/deployments/staging.gno.land/docker-compose.yml +++ b/misc/deployments/staging.gno.land/docker-compose.yml @@ -17,7 +17,7 @@ services: - --chainid=staging - --genesis-remote=staging.gno.land:36657 volumes: - - "./data/gnoland:/opt/gno/src/gno.land/gno-chain" + - "./data/gnoland:/opt/gno/src/gno.land/gnoland-data" ports: - 36656:36656 - 36657:36657 diff --git a/misc/docker-compose/docker-compose.yml b/misc/docker-compose/docker-compose.yml index 1185e10760f..470aeaf3127 100644 --- a/misc/docker-compose/docker-compose.yml +++ b/misc/docker-compose/docker-compose.yml @@ -9,7 +9,7 @@ services: - LOG_LEVEL=4 command: [ "gnoland", "start" ] volumes: - - "gnonode:/opt/gno/src/gno-chain" + - "gnonode:/opt/gno/src/gnoland-data" networks: - gnonode restart: on-failure diff --git a/misc/loop/cmd/snapshotter.go b/misc/loop/cmd/snapshotter.go index e57a5c12b02..b501a3116f1 100644 --- a/misc/loop/cmd/snapshotter.go +++ b/misc/loop/cmd/snapshotter.go @@ -162,7 +162,7 @@ func (s snapshotter) startPortalLoopContainer(ctx context.Context) (*types.Conta Binds: []string{ fmt.Sprintf("%s/scripts:/scripts", s.cfg.hostPWD), fmt.Sprintf("%s/backups:/backups", s.cfg.hostPWD), - fmt.Sprintf("%s:/opt/gno/src/gno-chain", s.containerName), + fmt.Sprintf("%s:/opt/gno/src/gnoland-data", s.containerName), }, }, nil, nil, s.containerName) if err != nil { diff --git a/misc/loop/scripts/start.sh b/misc/loop/scripts/start.sh index cdf34e2d6e1..1b52f6f03f5 100755 --- a/misc/loop/scripts/start.sh +++ b/misc/loop/scripts/start.sh @@ -19,11 +19,11 @@ gnoland start \ --skip-start=true \ --skip-failing-genesis-txs -sed -i "s#^moniker = \".*\"#moniker = \"${MONIKER}\"#" ./gno-chain/config/config.toml -sed -i "s#laddr = \".*:26656\"#laddr = \"${P2P_LADDR}\"#" ./gno-chain/config/config.toml -sed -i "s#laddr = \".*:26657\"#laddr = \"${RPC_LADDR}\"#" ./gno-chain/config/config.toml +sed -i "s#^moniker = \".*\"#moniker = \"${MONIKER}\"#" ./gnoland-data/config/config.toml +sed -i "s#laddr = \".*:26656\"#laddr = \"${P2P_LADDR}\"#" ./gnoland-data/config/config.toml +sed -i "s#laddr = \".*:26657\"#laddr = \"${RPC_LADDR}\"#" ./gnoland-data/config/config.toml -sed -i "s#seeds = \".*\"#seeds = \"${SEEDS}\"#" ./gno-chain/config/config.toml -sed -i "s#persistent_peers = \".*\"#persistent_peers = \"${PERSISTENT_PEERS}\"#" ./gno-chain/config/config.toml +sed -i "s#seeds = \".*\"#seeds = \"${SEEDS}\"#" ./gnoland-data/config/config.toml +sed -i "s#persistent_peers = \".*\"#persistent_peers = \"${PERSISTENT_PEERS}\"#" ./gnoland-data/config/config.toml exec gnoland start --skip-failing-genesis-txs diff --git a/tm2/pkg/bft/config/config.go b/tm2/pkg/bft/config/config.go index 356a70eeb25..bfe3fbafce3 100644 --- a/tm2/pkg/bft/config/config.go +++ b/tm2/pkg/bft/config/config.go @@ -165,7 +165,7 @@ func (cfg *Config) EnsureDirs() error { return fmt.Errorf("no config directory, %w", err) } - if err := osm.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { + if err := osm.EnsureDir(filepath.Join(rootDir, DefaultDBDir), DefaultDirPerm); err != nil { return fmt.Errorf("no data directory, %w", err) } @@ -196,7 +196,7 @@ func (cfg *Config) ValidateBasic() error { // ----------------------------------------------------------------------------- var ( - defaultDataDir = "data" + DefaultDBDir = "db" defaultSecretsDir = "secrets" defaultConfigFileName = "config.toml" @@ -221,8 +221,9 @@ type BaseConfig struct { // ┌── db/ // │ ├── blockstore.db (folder) // │ ├── gnolang.db (folder) - // │ ├── state.db (folder) - // │ └── cs.wal + // │ └── state.db (folder) + // ├── wal/ + // │ └── cs.wal (folder) // ├── secrets/ // │ ├── priv_validator_state.json // │ ├── node_key.json @@ -304,7 +305,7 @@ func DefaultBaseConfig() BaseConfig { FastSyncMode: true, FilterPeers: false, DBBackend: db.GoLevelDBBackend.String(), - DBPath: defaultDataDir, + DBPath: DefaultDBDir, } } diff --git a/tm2/pkg/bft/config/toml.go b/tm2/pkg/bft/config/toml.go index e2dbf6597f1..2da0adcfb21 100644 --- a/tm2/pkg/bft/config/toml.go +++ b/tm2/pkg/bft/config/toml.go @@ -72,7 +72,7 @@ func ResetTestRoot(testName string) *Config { if err := osm.EnsureDir(filepath.Join(rootDir, defaultSecretsDir), DefaultDirPerm); err != nil { panic(err) } - if err := osm.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { + if err := osm.EnsureDir(filepath.Join(rootDir, DefaultDBDir), DefaultDirPerm); err != nil { panic(err) } diff --git a/tm2/pkg/bft/config/toml_test.go b/tm2/pkg/bft/config/toml_test.go index a95fbfa4351..1e83db0f9f7 100644 --- a/tm2/pkg/bft/config/toml_test.go +++ b/tm2/pkg/bft/config/toml_test.go @@ -44,7 +44,7 @@ func TestEnsureRoot(t *testing.T) { require.True(t, checkConfig(string(data))) - ensureFiles(t, tmpDir, "data") + ensureFiles(t, tmpDir, DefaultDBDir) } func TestEnsureTestRoot(t *testing.T) { @@ -68,7 +68,7 @@ func TestEnsureTestRoot(t *testing.T) { ensureFiles( t, rootDir, - defaultDataDir, + DefaultDBDir, baseConfig.PrivValidatorKey, baseConfig.PrivValidatorState, ) diff --git a/tm2/pkg/bft/consensus/config/config.go b/tm2/pkg/bft/consensus/config/config.go index aacb63c2c92..4a350ff3976 100644 --- a/tm2/pkg/bft/consensus/config/config.go +++ b/tm2/pkg/bft/consensus/config/config.go @@ -10,7 +10,7 @@ import ( // ConsensusConfig const ( - defaultDataDir = "data" + defaultWALDir = "wal" ) // ConsensusConfig defines the configuration for the Tendermint consensus service, @@ -44,7 +44,7 @@ type ConsensusConfig struct { // DefaultConsensusConfig returns a default configuration for the consensus service func DefaultConsensusConfig() *ConsensusConfig { return &ConsensusConfig{ - WALPath: filepath.Join(defaultDataDir, "cs.wal", "wal"), + WALPath: filepath.Join(defaultWALDir, "cs.wal", "wal"), TimeoutPropose: 3000 * time.Millisecond, TimeoutProposeDelta: 500 * time.Millisecond, TimeoutPrevote: 1000 * time.Millisecond, diff --git a/tm2/pkg/crypto/keys/utils.go b/tm2/pkg/crypto/keys/utils.go index 623d3094005..0545c322e64 100644 --- a/tm2/pkg/crypto/keys/utils.go +++ b/tm2/pkg/crypto/keys/utils.go @@ -3,13 +3,15 @@ package keys import ( "fmt" "path/filepath" + + "github.com/gnolang/gno/tm2/pkg/bft/config" ) const defaultKeyDBName = "keys" // NewKeyBaseFromDir initializes a keybase at a particular dir. func NewKeyBaseFromDir(rootDir string) (Keybase, error) { - return NewLazyDBKeybase(defaultKeyDBName, filepath.Join(rootDir, "data")), nil + return NewLazyDBKeybase(defaultKeyDBName, filepath.Join(rootDir, config.DefaultDBDir)), nil } // NewInMemoryKeyBase returns a storage-less keybase. From 3b2926aa3dd49655469f58d9ad8485c9542879c3 Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Mon, 22 Apr 2024 10:44:48 +0200 Subject: [PATCH 06/14] Tidy go mods --- contribs/gnokeykc/go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/contribs/gnokeykc/go.mod b/contribs/gnokeykc/go.mod index c0b4a874576..06e4db7a355 100644 --- a/contribs/gnokeykc/go.mod +++ b/contribs/gnokeykc/go.mod @@ -10,6 +10,7 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect From 533cae2fe7423fa2e7993f162145878f52444dc7 Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Mon, 22 Apr 2024 13:40:31 +0200 Subject: [PATCH 07/14] Update Portal Loop sed --- misc/loop/scripts/start.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/misc/loop/scripts/start.sh b/misc/loop/scripts/start.sh index 1b52f6f03f5..858b85af861 100755 --- a/misc/loop/scripts/start.sh +++ b/misc/loop/scripts/start.sh @@ -19,11 +19,11 @@ gnoland start \ --skip-start=true \ --skip-failing-genesis-txs -sed -i "s#^moniker = \".*\"#moniker = \"${MONIKER}\"#" ./gnoland-data/config/config.toml -sed -i "s#laddr = \".*:26656\"#laddr = \"${P2P_LADDR}\"#" ./gnoland-data/config/config.toml -sed -i "s#laddr = \".*:26657\"#laddr = \"${RPC_LADDR}\"#" ./gnoland-data/config/config.toml +sed -i "s#^moniker = \".*\"#moniker = \"${MONIKER}\"#" ./gnoland-data/config.toml +sed -i "s#laddr = \".*:26656\"#laddr = \"${P2P_LADDR}\"#" ./gnoland-data/config.toml +sed -i "s#laddr = \".*:26657\"#laddr = \"${RPC_LADDR}\"#" ./gnoland-data/config.toml -sed -i "s#seeds = \".*\"#seeds = \"${SEEDS}\"#" ./gnoland-data/config/config.toml -sed -i "s#persistent_peers = \".*\"#persistent_peers = \"${PERSISTENT_PEERS}\"#" ./gnoland-data/config/config.toml +sed -i "s#seeds = \".*\"#seeds = \"${SEEDS}\"#" ./gnoland-data/config.toml +sed -i "s#persistent_peers = \".*\"#persistent_peers = \"${PERSISTENT_PEERS}\"#" ./gnoland-data/config.toml exec gnoland start --skip-failing-genesis-txs From 202198f02504c82ac548176814eca8f5a4aaca7d Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Tue, 23 Apr 2024 16:44:28 +0200 Subject: [PATCH 08/14] feat(gnoland): pass genesis file as a flag --- gno.land/cmd/gnoland/config_get_test.go | 7 ------- gno.land/cmd/gnoland/config_set_test.go | 10 ---------- gno.land/cmd/gnoland/start.go | 20 +++++++++++++------- tm2/pkg/bft/config/config.go | 15 --------------- tm2/pkg/bft/config/toml.go | 2 +- tm2/pkg/bft/consensus/replay_file.go | 8 ++++---- tm2/pkg/bft/node/node.go | 8 ++++---- tm2/pkg/bft/rpc/test/helpers.go | 22 ++++++++++++++++++---- 8 files changed, 40 insertions(+), 52 deletions(-) diff --git a/gno.land/cmd/gnoland/config_get_test.go b/gno.land/cmd/gnoland/config_get_test.go index 940842516d0..e8c27045205 100644 --- a/gno.land/cmd/gnoland/config_get_test.go +++ b/gno.land/cmd/gnoland/config_get_test.go @@ -129,13 +129,6 @@ func TestConfig_Get_Base(t *testing.T) { assert.Equal(t, loadedCfg.DBPath, value) }, }, - { - "genesis path fetched", - "genesis_file", - func(loadedCfg *config.Config, value string) { - assert.Equal(t, loadedCfg.Genesis, value) - }, - }, { "validator key fetched", "priv_validator_key_file", diff --git a/gno.land/cmd/gnoland/config_set_test.go b/gno.land/cmd/gnoland/config_set_test.go index 87cfbfdfc4a..b0898194d64 100644 --- a/gno.land/cmd/gnoland/config_set_test.go +++ b/gno.land/cmd/gnoland/config_set_test.go @@ -184,16 +184,6 @@ func TestConfig_Set_Base(t *testing.T) { assert.Equal(t, value, loadedCfg.DBPath) }, }, - { - "genesis path updated", - []string{ - "genesis_file", - "example path", - }, - func(loadedCfg *config.Config, value string) { - assert.Equal(t, value, loadedCfg.Genesis) - }, - }, { "validator key updated", []string{ diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index cc1030a33b9..b0afa402078 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -43,6 +43,7 @@ type startCfg struct { skipStart bool genesisBalancesFile string genesisTxsFile string + genesisFile string chainID string genesisRemote string dataDir string @@ -106,6 +107,13 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { "initial txs to replay", ) + fs.StringVar( + &c.genesisFile, + "genesis", + "genesis.json", + "path to genesis file", + ) + fs.StringVar( &c.chainID, "chainid", @@ -241,11 +249,9 @@ func execStart(c *startCfg, io commands.IO) error { logger := log.ZapLoggerToSlog(zapLogger) // Write genesis file if missing. - // NOTE: this will be dropped in a PR that resolves issue #1883: - // https://github.com/gnolang/gno/issues/1883 - genesisFilePath := filepath.Join(nodeDir, "../", cfg.Genesis) - - if !osm.FileExists(genesisFilePath) { + // NOTE: this will be dropped in a PR that resolves issue #1886: + // https://github.com/gnolang/gno/issues/1886 + if !osm.FileExists(c.genesisFile) { // Create priv validator first. // Need it to generate genesis.json newPrivValKey := cfg.PrivValidatorKeyFile() @@ -254,7 +260,7 @@ func execStart(c *startCfg, io commands.IO) error { pk := priv.GetPubKey() // Generate genesis.json file - if err := generateGenesisFile(genesisFilePath, pk, c); err != nil { + if err := generateGenesisFile(c.genesisFile, pk, c); err != nil { return fmt.Errorf("unable to generate genesis file: %w", err) } } @@ -277,7 +283,7 @@ func execStart(c *startCfg, io commands.IO) error { io.Println(startGraphic) } - gnoNode, err := node.DefaultNewNode(cfg, logger) + gnoNode, err := node.DefaultNewNode(cfg, c.genesisFile, logger) if err != nil { return fmt.Errorf("error in creating node: %w", err) } diff --git a/tm2/pkg/bft/config/config.go b/tm2/pkg/bft/config/config.go index bfe3fbafce3..a3135420af2 100644 --- a/tm2/pkg/bft/config/config.go +++ b/tm2/pkg/bft/config/config.go @@ -200,7 +200,6 @@ var ( defaultSecretsDir = "secrets" defaultConfigFileName = "config.toml" - defaultGenesisJSONName = "genesis.json" defaultNodeKeyName = "node_key.json" defaultPrivValKeyName = "priv_validator_key.json" defaultPrivValStateName = "priv_validator_state.json" @@ -264,9 +263,6 @@ type BaseConfig struct { // Database directory DBPath string `toml:"db_dir" comment:"Database directory"` - // Path to the JSON file containing the initial validator set and other meta data - Genesis string `toml:"genesis_file" comment:"Path to the JSON file containing the initial validator set and other meta data"` - // Path to the JSON file containing the private key to use as a validator in the consensus protocol PrivValidatorKey string `toml:"priv_validator_key_file" comment:"Path to the JSON file containing the private key to use as a validator in the consensus protocol"` @@ -294,7 +290,6 @@ type BaseConfig struct { // DefaultBaseConfig returns a default base configuration for a Tendermint node func DefaultBaseConfig() BaseConfig { return BaseConfig{ - Genesis: defaultGenesisJSONName, PrivValidatorKey: defaultPrivValKeyPath, PrivValidatorState: defaultPrivValStatePath, NodeKey: defaultNodeKeyPath, @@ -323,11 +318,6 @@ func (cfg BaseConfig) ChainID() string { return cfg.chainID } -// GenesisFile returns the full path to the genesis.json file -func (cfg BaseConfig) GenesisFile() string { - return filepath.Join(cfg.RootDir, "../", defaultGenesisJSONName) -} - // PrivValidatorKeyFile returns the full path to the priv_validator_key.json file func (cfg BaseConfig) PrivValidatorKeyFile() string { return filepath.Join(cfg.RootDir, cfg.PrivValidatorKey) @@ -380,11 +370,6 @@ func (cfg BaseConfig) ValidateBasic() error { return errInvalidDBPath } - // Verify the genesis path is set - if cfg.Genesis == "" { - return errInvalidGenesisPath - } - // Verify the validator private key path is set if cfg.PrivValidatorKey == "" { return errInvalidPrivValidatorKeyPath diff --git a/tm2/pkg/bft/config/toml.go b/tm2/pkg/bft/config/toml.go index 2da0adcfb21..9bba3612c2a 100644 --- a/tm2/pkg/bft/config/toml.go +++ b/tm2/pkg/bft/config/toml.go @@ -78,7 +78,7 @@ func ResetTestRoot(testName string) *Config { baseConfig := DefaultBaseConfig() configFilePath := filepath.Join(rootDir, defaultConfigFileName) - genesisFilePath := filepath.Join(rootDir, "../", baseConfig.Genesis) + genesisFilePath := filepath.Join(rootDir, "../config.json") privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey) privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState) diff --git a/tm2/pkg/bft/consensus/replay_file.go b/tm2/pkg/bft/consensus/replay_file.go index bddc6b429be..f233816e9a6 100644 --- a/tm2/pkg/bft/consensus/replay_file.go +++ b/tm2/pkg/bft/consensus/replay_file.go @@ -34,8 +34,8 @@ const ( // replay messages interactively or all at once // replay the wal file -func RunReplayFile(config cfg.BaseConfig, csConfig *cnscfg.ConsensusConfig, console bool) { - consensusState := newConsensusStateForReplay(config, csConfig) +func RunReplayFile(config cfg.BaseConfig, genesisFile string, csConfig *cnscfg.ConsensusConfig, console bool) { + consensusState := newConsensusStateForReplay(config, genesisFile, csConfig) if err := consensusState.ReplayFile(csConfig.WalFile(), console); err != nil { osm.Exit(fmt.Sprintf("Error during consensus replay: %v", err)) @@ -270,7 +270,7 @@ func (pb *playback) replayConsoleLoop() int { // -------------------------------------------------------------------------------- // convenience for replay mode -func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cnscfg.ConsensusConfig) *ConsensusState { +func newConsensusStateForReplay(config cfg.BaseConfig, genesisFile string, csConfig *cnscfg.ConsensusConfig) *ConsensusState { dbType := dbm.BackendType(config.DBBackend) // Get BlockStore blockStoreDB, err := dbm.NewDB("blockstore", dbType, config.DBDir()) @@ -286,7 +286,7 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cnscfg.Consensu osm.Exit(err.Error()) } - gdoc, err := sm.MakeGenesisDocFromFile(config.GenesisFile()) + gdoc, err := sm.MakeGenesisDocFromFile(genesisFile) if err != nil { osm.Exit(err.Error()) } diff --git a/tm2/pkg/bft/node/node.go b/tm2/pkg/bft/node/node.go index 5fe47bb8893..209b59f1223 100644 --- a/tm2/pkg/bft/node/node.go +++ b/tm2/pkg/bft/node/node.go @@ -68,9 +68,9 @@ type GenesisDocProvider func() (*types.GenesisDoc, error) // DefaultGenesisDocProviderFunc returns a GenesisDocProvider that loads // the GenesisDoc from the config.GenesisFile() on the filesystem. -func DefaultGenesisDocProviderFunc(config *cfg.Config) GenesisDocProvider { +func DefaultGenesisDocProviderFunc(genesisFile string) GenesisDocProvider { return func() (*types.GenesisDoc, error) { - return types.GenesisDocFromFile(config.GenesisFile()) + return types.GenesisDocFromFile(genesisFile) } } @@ -80,7 +80,7 @@ type NodeProvider func(*cfg.Config, *slog.Logger) (*Node, error) // DefaultNewNode returns a Tendermint node with default settings for the // PrivValidator, ClientCreator, GenesisDoc, and DBProvider. // It implements NodeProvider. -func DefaultNewNode(config *cfg.Config, logger *slog.Logger) (*Node, error) { +func DefaultNewNode(config *cfg.Config, genesisFile string, logger *slog.Logger) (*Node, error) { // Generate node PrivKey nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) if err != nil { @@ -103,7 +103,7 @@ func DefaultNewNode(config *cfg.Config, logger *slog.Logger) (*Node, error) { privval.LoadOrGenFilePV(newPrivValKey, newPrivValState), nodeKey, appClientCreator, - DefaultGenesisDocProviderFunc(config), + DefaultGenesisDocProviderFunc(genesisFile), DefaultDBProvider, logger, ) diff --git a/tm2/pkg/bft/rpc/test/helpers.go b/tm2/pkg/bft/rpc/test/helpers.go index 0b6d39c6839..4be9a12055b 100644 --- a/tm2/pkg/bft/rpc/test/helpers.go +++ b/tm2/pkg/bft/rpc/test/helpers.go @@ -23,12 +23,14 @@ import ( type Options struct { suppressStdout bool recreateConfig bool + genesisPath string } var ( globalConfig *cfg.Config defaultOptions = Options{ recreateConfig: false, + genesisPath: "genesis.json", } ) @@ -85,7 +87,7 @@ func StartTendermint(app abci.Application, opts ...func(*Options)) *nm.Node { for _, opt := range opts { opt(&nodeOpts) } - node := NewTendermint(app, &nodeOpts) + node := newTendermint(app, &nodeOpts) err := node.Start() if err != nil { panic(err) @@ -109,8 +111,8 @@ func StopTendermint(node *nm.Node) { os.RemoveAll(node.Config().RootDir) } -// NewTendermint creates a new tendermint server and sleeps forever -func NewTendermint(app abci.Application, opts *Options) *nm.Node { +// newTendermint creates a new tendermint server and sleeps forever +func newTendermint(app abci.Application, opts *Options) *nm.Node { // Create & start node config := GetConfig(opts.recreateConfig) @@ -122,8 +124,12 @@ func NewTendermint(app abci.Application, opts *Options) *nm.Node { if err != nil { panic(err) } + genesisPath, err := filepath.Abs(opts.genesisPath) + if err != nil { + panic(err) + } node, err := nm.NewNode(config, pv, nodeKey, papp, - nm.DefaultGenesisDocProviderFunc(config), + nm.DefaultGenesisDocProviderFunc(genesisPath), nm.DefaultDBProvider, log.NewNoopLogger()) if err != nil { @@ -143,3 +149,11 @@ func SuppressStdout(o *Options) { func RecreateConfig(o *Options) { o.recreateConfig = true } + +// WithGenesisPath sets the given path to the genesis file. +// The default is "genesis.json". +func WithGenesisPath(genesisPath string) func(o *Options) { + return func(o *Options) { + o.genesisPath = genesisPath + } +} From 93fcc313e824311ed71323b1d7947ecc8a6c6901 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Tue, 23 Apr 2024 17:53:49 +0200 Subject: [PATCH 09/14] fixup usages --- tm2/pkg/bft/blockchain/reactor_test.go | 4 +- tm2/pkg/bft/config/config.go | 1 - tm2/pkg/bft/config/config_test.go | 9 ---- tm2/pkg/bft/config/toml.go | 10 ++-- tm2/pkg/bft/config/toml_test.go | 4 +- tm2/pkg/bft/consensus/common_test.go | 8 +-- tm2/pkg/bft/consensus/mempool_test.go | 6 +-- tm2/pkg/bft/consensus/replay_test.go | 54 ++++++++++--------- .../consensus/types/height_vote_set_test.go | 2 +- tm2/pkg/bft/consensus/wal_generator.go | 8 +-- tm2/pkg/bft/consensus/wal_test.go | 4 +- tm2/pkg/bft/node/node_test.go | 34 ++++++------ tm2/pkg/bft/rpc/test/helpers.go | 2 +- tm2/pkg/bft/state/state_test.go | 4 +- tm2/pkg/bft/state/store_test.go | 4 +- tm2/pkg/bft/store/store_test.go | 6 +-- 16 files changed, 80 insertions(+), 80 deletions(-) diff --git a/tm2/pkg/bft/blockchain/reactor_test.go b/tm2/pkg/bft/blockchain/reactor_test.go index 7f96cdefc97..a40dbc6376b 100644 --- a/tm2/pkg/bft/blockchain/reactor_test.go +++ b/tm2/pkg/bft/blockchain/reactor_test.go @@ -119,7 +119,7 @@ func newBlockchainReactor(logger *slog.Logger, genDoc *types.GenesisDoc, privVal func TestNoBlockResponse(t *testing.T) { t.Parallel() - config = cfg.ResetTestRoot("blockchain_reactor_test") + config, _ = cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) genDoc, privVals := randGenesisDoc(1, false, 30) @@ -182,7 +182,7 @@ func TestFlappyBadBlockStopsPeer(t *testing.T) { testutils.FilterStability(t, testutils.Flappy) - config = cfg.ResetTestRoot("blockchain_reactor_test") + config, _ = cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) genDoc, privVals := randGenesisDoc(1, false, 30) diff --git a/tm2/pkg/bft/config/config.go b/tm2/pkg/bft/config/config.go index a3135420af2..f2cd40ca7b4 100644 --- a/tm2/pkg/bft/config/config.go +++ b/tm2/pkg/bft/config/config.go @@ -22,7 +22,6 @@ var ( errInvalidMoniker = errors.New("moniker not set") errInvalidDBBackend = errors.New("invalid DB backend") errInvalidDBPath = errors.New("invalid DB path") - errInvalidGenesisPath = errors.New("invalid genesis path") errInvalidPrivValidatorKeyPath = errors.New("invalid private validator key path") errInvalidPrivValidatorStatePath = errors.New("invalid private validator state file path") errInvalidABCIMechanism = errors.New("invalid ABCI mechanism") diff --git a/tm2/pkg/bft/config/config_test.go b/tm2/pkg/bft/config/config_test.go index 501d87431b7..7bff8765a4a 100644 --- a/tm2/pkg/bft/config/config_test.go +++ b/tm2/pkg/bft/config/config_test.go @@ -128,15 +128,6 @@ func TestConfig_ValidateBaseConfig(t *testing.T) { assert.ErrorIs(t, c.BaseConfig.ValidateBasic(), errInvalidDBPath) }) - t.Run("genesis path not set", func(t *testing.T) { - t.Parallel() - - c := DefaultConfig() - c.Genesis = "" - - assert.ErrorIs(t, c.BaseConfig.ValidateBasic(), errInvalidGenesisPath) - }) - t.Run("priv validator key path not set", func(t *testing.T) { t.Parallel() diff --git a/tm2/pkg/bft/config/toml.go b/tm2/pkg/bft/config/toml.go index 9bba3612c2a..371925a84c3 100644 --- a/tm2/pkg/bft/config/toml.go +++ b/tm2/pkg/bft/config/toml.go @@ -54,7 +54,7 @@ func WriteConfigFile(configFilePath string, config *Config) error { /****** these are for test settings ***********/ -func ResetTestRoot(testName string) *Config { +func ResetTestRoot(testName string) (cfg *Config, genesisFile string) { chainID := "test-chain" // create a unique, concurrency-safe test directory under os.TempDir() @@ -78,7 +78,11 @@ func ResetTestRoot(testName string) *Config { baseConfig := DefaultBaseConfig() configFilePath := filepath.Join(rootDir, defaultConfigFileName) - genesisFilePath := filepath.Join(rootDir, "../config.json") + // NOTE: this does not match the behaviour of the TM2 node. + // However, many tests rely on the fact that they can cleanup the directory + // by doing RemoveAll on the rootDir; so to keep compatibility with that + // behaviour, we place genesis.json in the rootDir. + genesisFilePath := filepath.Join(rootDir, "genesis.json") privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey) privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState) @@ -98,7 +102,7 @@ func ResetTestRoot(testName string) *Config { osm.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0o644) config := TestConfig().SetRootDir(rootDir) - return config + return config, genesisFilePath } var testGenesisFmt = `{ diff --git a/tm2/pkg/bft/config/toml_test.go b/tm2/pkg/bft/config/toml_test.go index 1e83db0f9f7..b486ef65f0b 100644 --- a/tm2/pkg/bft/config/toml_test.go +++ b/tm2/pkg/bft/config/toml_test.go @@ -53,7 +53,7 @@ func TestEnsureTestRoot(t *testing.T) { testName := "ensureTestRoot" // create root dir - cfg := ResetTestRoot(testName) + cfg, genesisFile := ResetTestRoot(testName) defer os.RemoveAll(cfg.RootDir) rootDir := cfg.RootDir @@ -76,7 +76,7 @@ func TestEnsureTestRoot(t *testing.T) { ensureFiles( t, filepath.Join(rootDir, ".."), - baseConfig.Genesis, + genesisFile, ) } diff --git a/tm2/pkg/bft/consensus/common_test.go b/tm2/pkg/bft/consensus/common_test.go index cace1aac43a..d4c572c6bda 100644 --- a/tm2/pkg/bft/consensus/common_test.go +++ b/tm2/pkg/bft/consensus/common_test.go @@ -53,7 +53,7 @@ func ensureDir(dir string, mode os.FileMode) { } } -func ResetConfig(name string) *cfg.Config { +func ResetConfig(name string) (*cfg.Config, string) { return cfg.ResetTestRoot(name) } @@ -261,7 +261,7 @@ func subscribeToVoter(cs *ConsensusState, addr crypto.Address) <-chan events.Eve // consensus states func newConsensusState(state sm.State, pv types.PrivValidator, app abci.Application) *ConsensusState { - config := cfg.ResetTestRoot("consensus_state_test") + config, _ := cfg.ResetTestRoot("consensus_state_test") return newConsensusStateWithConfig(config, state, pv, app) } @@ -578,7 +578,7 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou for i := 0; i < nValidators; i++ { stateDB := memdb.NewMemDB() // each state needs its own db state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) - thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) + thisConfig, _ := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) configRootDirs = append(configRootDirs, thisConfig.RootDir) for _, opt := range configOpts { opt(thisConfig) @@ -618,7 +618,7 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF for i := 0; i < nPeers; i++ { stateDB := memdb.NewMemDB() // each state needs its own db state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) - thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) + thisConfig, _ := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) configRootDirs = append(configRootDirs, thisConfig.RootDir) ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0o700) // dir for wal if i == 0 { diff --git a/tm2/pkg/bft/consensus/mempool_test.go b/tm2/pkg/bft/consensus/mempool_test.go index f425a161e90..b61f0e44245 100644 --- a/tm2/pkg/bft/consensus/mempool_test.go +++ b/tm2/pkg/bft/consensus/mempool_test.go @@ -26,7 +26,7 @@ func assertMempool(txn txNotifier) mempl.Mempool { func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { t.Parallel() - config := ResetConfig("consensus_mempool_no_progress_until_txs_available") + config, _ := ResetConfig("consensus_mempool_no_progress_until_txs_available") defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocks = false state, privVals := randGenesisState(1, false, 10) @@ -51,7 +51,7 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { } func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { - config := ResetConfig("consensus_mempool_progress_after_create_empty_blocks_interval") + config, _ := ResetConfig("consensus_mempool_progress_after_create_empty_blocks_interval") defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocksInterval = ensureTimeout state, privVals := randGenesisState(1, false, 10) @@ -75,7 +75,7 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { func TestMempoolProgressInHigherRound(t *testing.T) { t.Parallel() - config := ResetConfig("consensus_mempool_progress_in_higher_round") + config, _ := ResetConfig("consensus_mempool_progress_in_higher_round") defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocks = false state, privVals := randGenesisState(1, false, 10) diff --git a/tm2/pkg/bft/consensus/replay_test.go b/tm2/pkg/bft/consensus/replay_test.go index 6f138cd03e1..8291f2d56b9 100644 --- a/tm2/pkg/bft/consensus/replay_test.go +++ b/tm2/pkg/bft/consensus/replay_test.go @@ -39,11 +39,11 @@ import ( ) func TestMain(m *testing.M) { - config = ResetConfig("consensus_reactor_test") - consensusReplayConfig = ResetConfig("consensus_replay_test") - configStateTest := ResetConfig("consensus_state_test") - configMempoolTest := ResetConfig("consensus_mempool_test") - configByzantineTest := ResetConfig("consensus_byzantine_test") + config, _ = ResetConfig("consensus_reactor_test") + consensusReplayConfig, _ = ResetConfig("consensus_replay_test") + configStateTest, _ := ResetConfig("consensus_state_test") + configMempoolTest, _ := ResetConfig("consensus_mempool_test") + configByzantineTest, _ := ResetConfig("consensus_byzantine_test") code := m.Run() os.RemoveAll(config.RootDir) os.RemoveAll(consensusReplayConfig.RootDir) @@ -68,13 +68,14 @@ func TestMain(m *testing.M) { // and which ones we need the wal for - then we'd also be able to only flush the // wal writer when we need to, instead of with every message. -func startNewConsensusStateAndWaitForBlock(t *testing.T, consensusReplayConfig *cfg.Config, +func startNewConsensusStateAndWaitForBlock(t *testing.T, + consensusReplayConfig *cfg.Config, consensusReplayGenesisFile string, lastBlockHeight int64, blockDB dbm.DB, stateDB dbm.DB, ) { t.Helper() logger := log.NewTestingLogger(t) - state, _ := sm.LoadStateFromDBOrGenesisFile(stateDB, consensusReplayConfig.GenesisFile()) + state, _ := sm.LoadStateFromDBOrGenesisFile(stateDB, consensusReplayGenesisFile) privValidator := loadPrivValidator(consensusReplayConfig) cs := newConsensusStateWithConfigAndBlockStore(consensusReplayConfig, state, privValidator, kvstore.NewKVStoreApplication(), blockDB) cs.SetLogger(logger) @@ -149,16 +150,18 @@ func TestWALCrash(t *testing.T) { for i, tc := range testCases { tc := tc - consensusReplayConfig := ResetConfig(fmt.Sprintf("%s_%d", t.Name(), i)) + consensusReplayConfig, consensusReplayGenesisFile := ResetConfig(fmt.Sprintf("%s_%d", t.Name(), i)) t.Run(tc.name, func(t *testing.T) { t.Parallel() - crashWALandCheckLiveness(t, consensusReplayConfig, tc.initFn, tc.lastBlockHeight) + crashWALandCheckLiveness(t, consensusReplayConfig, consensusReplayGenesisFile, + tc.initFn, tc.lastBlockHeight) }) } } -func crashWALandCheckLiveness(t *testing.T, consensusReplayConfig *cfg.Config, +func crashWALandCheckLiveness(t *testing.T, + consensusReplayConfig *cfg.Config, consensusReplayGenesisFile string, initFn func(dbm.DB, *ConsensusState, context.Context), lastBlockHeight int64, ) { t.Helper() @@ -175,7 +178,7 @@ LOOP: logger := log.NewTestingLogger(t) blockDB := memdb.NewMemDB() stateDB := blockDB - state, _ := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile()) + state, _ := sm.MakeGenesisStateFromFile(consensusReplayGenesisFile) privValidator := loadPrivValidator(consensusReplayConfig) cs := newConsensusStateWithConfigAndBlockStore(consensusReplayConfig, state, privValidator, kvstore.NewKVStoreApplication(), blockDB) cs.SetLogger(logger) @@ -207,7 +210,7 @@ LOOP: t.Logf("WAL crashed: %v", err) // make sure we can make blocks after a crash - startNewConsensusStateAndWaitForBlock(t, consensusReplayConfig, cs.Height, blockDB, stateDB) + startNewConsensusStateAndWaitForBlock(t, consensusReplayConfig, consensusReplayGenesisFile, cs.Height, blockDB, stateDB) // stop consensus state and transactions sender (initFn) cs.Stop() @@ -643,8 +646,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin var store *mockBlockStore var stateDB dbm.DB var genesisState sm.State + var genesisFile string if sim != nil { - testConfig := ResetConfig(fmt.Sprintf("%s_%v_m", t.Name(), mode)) + testConfig, gf := ResetConfig(fmt.Sprintf("%s_%v_m", t.Name(), mode)) defer os.RemoveAll(testConfig.RootDir) stateDB = memdb.NewMemDB() defer stateDB.Close() @@ -653,8 +657,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin chain = sim.Chain commits = sim.Commits store = newMockBlockStore(config, genesisState.ConsensusParams) + genesisFile = gf } else { // test single node - testConfig := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode)) + testConfig, gf := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode)) defer os.RemoveAll(testConfig.RootDir) walBody, err := WALWithNBlocks(t, numBlocks) require.NoError(t, err) @@ -672,8 +677,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin chain, commits, err = makeBlockchainFromWAL(wal) require.NoError(t, err) - stateDB, genesisState, store = makeStateAndStore(config, privVal.GetPubKey(), kvstore.AppVersion) + stateDB, genesisState, store = makeStateAndStore(config, gf, privVal.GetPubKey(), kvstore.AppVersion) defer stateDB.Close() + genesisFile = gf } store.chain = chain store.commits = commits @@ -699,7 +705,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin // now start the app using the handshake - it should sync evsw := events.NewEventSwitch() - genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile()) + genDoc, _ := sm.MakeGenesisDocFromFile(genesisFile) handshaker := NewHandshaker(stateDB, state, store, genDoc) handshaker.SetEventSwitch(evsw) proxyApp := appconn.NewAppConns(clientCreator2) @@ -833,12 +839,12 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) { // - 0x01 // - 0x02 // - 0x03 - config := ResetConfig("handshake_test_") + config, genesisFile := ResetConfig("handshake_test_") defer os.RemoveAll(config.RootDir) privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()) const appVersion = "v0.0.0-test" - stateDB, state, store := makeStateAndStore(config, privVal.GetPubKey(), appVersion) - genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile()) + stateDB, state, store := makeStateAndStore(config, genesisFile, privVal.GetPubKey(), appVersion) + genDoc, _ := sm.MakeGenesisDocFromFile(genesisFile) state.LastValidators = state.Validators.Copy() // mode = 0 for committing all the blocks blocks := makeBlocks(3, &state, privVal) @@ -1059,9 +1065,9 @@ func readPieceFromWAL(msg *walm.TimedWALMessage) interface{} { } // fresh state and mock store -func makeStateAndStore(config *cfg.Config, pubKey crypto.PubKey, appVersion string) (dbm.DB, sm.State, *mockBlockStore) { +func makeStateAndStore(config *cfg.Config, genesisFile string, pubKey crypto.PubKey, appVersion string) (dbm.DB, sm.State, *mockBlockStore) { stateDB := memdb.NewMemDB() - state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile()) + state, _ := sm.MakeGenesisStateFromFile(genesisFile) state.AppVersion = appVersion store := newMockBlockStore(config, state.ConsensusParams) sm.SaveState(stateDB, state) @@ -1115,15 +1121,15 @@ func TestHandshakeUpdatesValidators(t *testing.T) { app := &initChainApp{vals: vals.ABCIValidatorUpdates()} clientCreator := proxy.NewLocalClientCreator(app) - config := ResetConfig("handshake_test_") + config, genesisFile := ResetConfig("handshake_test_") defer os.RemoveAll(config.RootDir) privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()) - stateDB, state, store := makeStateAndStore(config, privVal.GetPubKey(), "v0.0.0-test") + stateDB, state, store := makeStateAndStore(config, genesisFile, privVal.GetPubKey(), "v0.0.0-test") oldValAddr := state.Validators.Validators[0].Address // now start the app using the handshake - it should sync - genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile()) + genDoc, _ := sm.MakeGenesisDocFromFile(genesisFile) handshaker := NewHandshaker(stateDB, state, store, genDoc) proxyApp := appconn.NewAppConns(clientCreator) if err := proxyApp.Start(); err != nil { diff --git a/tm2/pkg/bft/consensus/types/height_vote_set_test.go b/tm2/pkg/bft/consensus/types/height_vote_set_test.go index 4c315585daa..60cac5831a6 100644 --- a/tm2/pkg/bft/consensus/types/height_vote_set_test.go +++ b/tm2/pkg/bft/consensus/types/height_vote_set_test.go @@ -14,7 +14,7 @@ import ( var config *cfg.Config // NOTE: must be reset for each _test.go file func TestMain(m *testing.M) { - config = cfg.ResetTestRoot("consensus_height_vote_set_test") + config, _ = cfg.ResetTestRoot("consensus_height_vote_set_test") code := m.Run() os.RemoveAll(config.RootDir) os.Exit(code) diff --git a/tm2/pkg/bft/consensus/wal_generator.go b/tm2/pkg/bft/consensus/wal_generator.go index 175771f50ed..3b4aa1073d3 100644 --- a/tm2/pkg/bft/consensus/wal_generator.go +++ b/tm2/pkg/bft/consensus/wal_generator.go @@ -25,18 +25,18 @@ func makeAddrs() (string, string, string) { fmt.Sprintf("tcp://0.0.0.0:%d", start+2) } -// getConfig returns a config for test cases -func getConfig(t *testing.T) *cfg.Config { +// getConfig returns a config and genesis file for test cases +func getConfig(t *testing.T) (*cfg.Config, string) { t.Helper() - c := cfg.ResetTestRoot(t.Name()) + c, genesisFile := cfg.ResetTestRoot(t.Name()) // and we use random ports to run in parallel tm, rpc, grpc := makeAddrs() c.P2P.ListenAddress = tm c.RPC.ListenAddress = rpc c.RPC.GRPCListenAddress = grpc - return c + return c, genesisFile } // heightStopWAL is a WAL which writes all msgs to underlying WALWriter. diff --git a/tm2/pkg/bft/consensus/wal_test.go b/tm2/pkg/bft/consensus/wal_test.go index 42651c0727d..b3ed662b968 100644 --- a/tm2/pkg/bft/consensus/wal_test.go +++ b/tm2/pkg/bft/consensus/wal_test.go @@ -111,7 +111,7 @@ func TestWALTruncate(t *testing.T) { func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { t.Helper() - config := getConfig(t) + config, genesisFile := getConfig(t) app := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), "wal_generator")) defer app.Close() @@ -126,7 +126,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { privValidatorKeyFile := config.PrivValidatorKeyFile() privValidatorStateFile := config.PrivValidatorStateFile() privValidator := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile) - genDoc, err := types.GenesisDocFromFile(config.GenesisFile()) + genDoc, err := types.GenesisDocFromFile(genesisFile) if err != nil { return errors.Wrap(err, "failed to read genesis file") } diff --git a/tm2/pkg/bft/node/node_test.go b/tm2/pkg/bft/node/node_test.go index c8e83b4963a..28ab95e0064 100644 --- a/tm2/pkg/bft/node/node_test.go +++ b/tm2/pkg/bft/node/node_test.go @@ -31,11 +31,11 @@ import ( ) func TestNodeStartStop(t *testing.T) { - config := cfg.ResetTestRoot("node_node_test") + config, genesisFile := cfg.ResetTestRoot("node_node_test") defer os.RemoveAll(config.RootDir) // create & start node - n, err := DefaultNewNode(config, log.NewNoopLogger()) + n, err := DefaultNewNode(config, genesisFile, log.NewNoopLogger()) require.NoError(t, err) err = n.Start() require.NoError(t, err) @@ -93,12 +93,12 @@ func TestSplitAndTrimEmpty(t *testing.T) { } func TestNodeDelayedStart(t *testing.T) { - config := cfg.ResetTestRoot("node_delayed_start_test") + config, genesisFile := cfg.ResetTestRoot("node_delayed_start_test") defer os.RemoveAll(config.RootDir) now := tmtime.Now() // create & start node - n, err := DefaultNewNode(config, log.NewTestingLogger(t)) + n, err := DefaultNewNode(config, genesisFile, log.NewTestingLogger(t)) n.GenesisDoc().GenesisTime = now.Add(2 * time.Second) require.NoError(t, err) @@ -111,11 +111,11 @@ func TestNodeDelayedStart(t *testing.T) { } func TestNodeReady(t *testing.T) { - config := cfg.ResetTestRoot("node_node_test") + config, genesisFile := cfg.ResetTestRoot("node_node_test") defer os.RemoveAll(config.RootDir) // Create & start node - n, err := DefaultNewNode(config, log.NewTestingLogger(t)) + n, err := DefaultNewNode(config, genesisFile, log.NewTestingLogger(t)) require.NoError(t, err) // Assert that blockstore has zero block before waiting for the first block @@ -144,11 +144,11 @@ func TestNodeReady(t *testing.T) { } func TestNodeSetAppVersion(t *testing.T) { - config := cfg.ResetTestRoot("node_app_version_test") + config, genesisFile := cfg.ResetTestRoot("node_app_version_test") defer os.RemoveAll(config.RootDir) // create & start node - n, err := DefaultNewNode(config, log.NewTestingLogger(t)) + n, err := DefaultNewNode(config, genesisFile, log.NewTestingLogger(t)) require.NoError(t, err) // default config uses the kvstore app @@ -167,7 +167,7 @@ func TestNodeSetAppVersion(t *testing.T) { func TestNodeSetPrivValTCP(t *testing.T) { addr := "tcp://" + testFreeAddr(t) - config := cfg.ResetTestRoot("node_priv_val_tcp_test") + config, genesisFile := cfg.ResetTestRoot("node_priv_val_tcp_test") defer os.RemoveAll(config.RootDir) config.BaseConfig.PrivValidatorListenAddr = addr @@ -192,7 +192,7 @@ func TestNodeSetPrivValTCP(t *testing.T) { }() defer signerServer.Stop() - n, err := DefaultNewNode(config, log.NewTestingLogger(t)) + n, err := DefaultNewNode(config, genesisFile, log.NewTestingLogger(t)) require.NoError(t, err) assert.IsType(t, &privval.SignerClient{}, n.PrivValidator()) } @@ -201,11 +201,11 @@ func TestNodeSetPrivValTCP(t *testing.T) { func TestPrivValidatorListenAddrNoProtocol(t *testing.T) { addrNoPrefix := testFreeAddr(t) - config := cfg.ResetTestRoot("node_priv_val_tcp_test") + config, genesisFile := cfg.ResetTestRoot("node_priv_val_tcp_test") defer os.RemoveAll(config.RootDir) config.BaseConfig.PrivValidatorListenAddr = addrNoPrefix - _, err := DefaultNewNode(config, log.NewTestingLogger(t)) + _, err := DefaultNewNode(config, genesisFile, log.NewTestingLogger(t)) assert.Error(t, err) } @@ -213,7 +213,7 @@ func TestNodeSetPrivValIPC(t *testing.T) { tmpfile := "/tmp/kms." + random.RandStr(6) + ".sock" defer os.Remove(tmpfile) // clean up - config := cfg.ResetTestRoot("node_priv_val_tcp_test") + config, genesisFile := cfg.ResetTestRoot("node_priv_val_tcp_test") defer os.RemoveAll(config.RootDir) config.BaseConfig.PrivValidatorListenAddr = "unix://" + tmpfile @@ -236,7 +236,7 @@ func TestNodeSetPrivValIPC(t *testing.T) { }() defer pvsc.Stop() - n, err := DefaultNewNode(config, log.NewTestingLogger(t)) + n, err := DefaultNewNode(config, genesisFile, log.NewTestingLogger(t)) require.NoError(t, err) assert.IsType(t, &privval.SignerClient{}, n.PrivValidator()) } @@ -255,7 +255,7 @@ func testFreeAddr(t *testing.T) string { // create a proposal block using real and full // mempool pool and validate it. func TestCreateProposalBlock(t *testing.T) { - config := cfg.ResetTestRoot("node_create_proposal") + config, _ := cfg.ResetTestRoot("node_create_proposal") defer os.RemoveAll(config.RootDir) cc := proxy.NewLocalClientCreator(kvstore.NewKVStoreApplication()) proxyApp := appconn.NewAppConns(cc) @@ -309,7 +309,7 @@ func TestCreateProposalBlock(t *testing.T) { } func TestNodeNewNodeCustomReactors(t *testing.T) { - config := cfg.ResetTestRoot("node_new_node_custom_reactors_test") + config, genesisFile := cfg.ResetTestRoot("node_new_node_custom_reactors_test") defer os.RemoveAll(config.RootDir) cr := p2pmock.NewReactor() @@ -322,7 +322,7 @@ func TestNodeNewNodeCustomReactors(t *testing.T) { privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()), nodeKey, proxy.DefaultClientCreator(nil, config.ProxyApp, config.ABCI, config.DBDir()), - DefaultGenesisDocProviderFunc(config), + DefaultGenesisDocProviderFunc(genesisFile), DefaultDBProvider, log.NewTestingLogger(t), CustomReactors(map[string]p2p.Reactor{"FOO": cr, "BLOCKCHAIN": customBlockchainReactor}), diff --git a/tm2/pkg/bft/rpc/test/helpers.go b/tm2/pkg/bft/rpc/test/helpers.go index 4be9a12055b..03de92dedc4 100644 --- a/tm2/pkg/bft/rpc/test/helpers.go +++ b/tm2/pkg/bft/rpc/test/helpers.go @@ -63,7 +63,7 @@ func makePathname() string { func createConfig() *cfg.Config { pathname := makePathname() - c := cfg.ResetTestRoot(pathname) + c, _ := cfg.ResetTestRoot(pathname) // and we use random ports to run in parallel c.P2P.ListenAddress = "tcp://127.0.0.1:0" diff --git a/tm2/pkg/bft/state/state_test.go b/tm2/pkg/bft/state/state_test.go index b7627cbb59f..15c87a41589 100644 --- a/tm2/pkg/bft/state/state_test.go +++ b/tm2/pkg/bft/state/state_test.go @@ -26,12 +26,12 @@ import ( func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, sm.State) { t.Helper() - config := cfg.ResetTestRoot("state_") + config, genesisFile := cfg.ResetTestRoot("state_") dbType := dbm.BackendType(config.DBBackend) stateDB, err := dbm.NewDB("state", dbType, config.DBDir()) require.NoError(t, err) - state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile()) + state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, genesisFile) assert.NoError(t, err, "expected no error on LoadStateFromDBOrGenesisFile") tearDown := func(t *testing.T) { diff --git a/tm2/pkg/bft/state/store_test.go b/tm2/pkg/bft/state/store_test.go index add5d7e34d2..e2e86b76c16 100644 --- a/tm2/pkg/bft/state/store_test.go +++ b/tm2/pkg/bft/state/store_test.go @@ -60,13 +60,13 @@ func TestStoreLoadValidators(t *testing.T) { func BenchmarkLoadValidators(b *testing.B) { const valSetSize = 100 - config := cfg.ResetTestRoot("state_") + config, genesisFile := cfg.ResetTestRoot("state_") defer os.RemoveAll(config.RootDir) dbType := dbm.BackendType(config.DBBackend) stateDB, err := dbm.NewDB("state", dbType, config.DBDir()) require.NoError(b, err) - state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile()) + state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, genesisFile) require.NoError(b, err) state.Validators = genValSet(valSetSize) state.NextValidators = state.Validators.CopyIncrementProposerPriority(1) diff --git a/tm2/pkg/bft/store/store_test.go b/tm2/pkg/bft/store/store_test.go index e20db43c2d6..2e634681ecc 100644 --- a/tm2/pkg/bft/store/store_test.go +++ b/tm2/pkg/bft/store/store_test.go @@ -45,13 +45,13 @@ func makeBlock(height int64, state sm.State, lastCommit *types.Commit) *types.Bl return block } -func makeStateAndBlockStore(logger *slog.Logger) (sm.State, *BlockStore, cleanupFunc) { - config := cfg.ResetTestRoot("blockchain_reactor_test") +func makeStateAndBlockStore(_ *slog.Logger) (sm.State, *BlockStore, cleanupFunc) { + config, genesisFile := cfg.ResetTestRoot("blockchain_reactor_test") // blockDB := dbm.NewDebugDB("blockDB", memdb.NewMemDB()) // stateDB := dbm.NewDebugDB("stateDB", memdb.NewMemDB()) blockDB := memdb.NewMemDB() stateDB := memdb.NewMemDB() - state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile()) + state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, genesisFile) if err != nil { panic(errors.Wrap(err, "error constructing state from genesis file")) } From fd7a68a35ec8e17333ca1c262d90362ad795a1a0 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Tue, 23 Apr 2024 18:49:24 +0200 Subject: [PATCH 10/14] add integ test --- gno.land/cmd/gnoland/start_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/gno.land/cmd/gnoland/start_test.go b/gno.land/cmd/gnoland/start_test.go index 2f266d8a879..516e76af2f8 100644 --- a/gno.land/cmd/gnoland/start_test.go +++ b/gno.land/cmd/gnoland/start_test.go @@ -3,6 +3,7 @@ package main import ( "bytes" "context" + "path/filepath" "testing" "time" @@ -14,15 +15,24 @@ import ( func TestStartInitialize(t *testing.T) { t.Parallel() + // NOTE: cannot be txtar tests as they use their own parsing for the + // "gnoland" command line. See pkg/integration. + var ( - nodeDir = t.TempDir() + nodeDir = t.TempDir() + genesisFile = filepath.Join(nodeDir, "test_genesis.json") args = []string{ "start", "--skip-start", "--skip-failing-genesis-txs", + + // These two flags are tested together as they would otherwise + // pollute this directory (cmd/gnoland) if not set. "--data-dir", nodeDir, + "--genesis", + genesisFile, } ) @@ -34,7 +44,7 @@ func TestStartInitialize(t *testing.T) { io.SetErr(commands.WriteNopCloser(mockErr)) // Create and run the command - ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancelFn := context.WithTimeout(context.Background(), 30*time.Second) defer cancelFn() cmd := newRootCmd(io) @@ -42,4 +52,6 @@ func TestStartInitialize(t *testing.T) { // Make sure the directory is created assert.DirExists(t, nodeDir) + assert.FileExists(t, genesisFile) + assert.NotErrorIs(t, ctx.Err(), context.DeadlineExceeded, "should not have exceeded deadline (has flag --skip-start)") } From 9fc235c0fce53119a739cf2700b91024ddf614c2 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Tue, 23 Apr 2024 18:56:17 +0200 Subject: [PATCH 11/14] refer to gno.land node instead --- tm2/pkg/bft/config/toml.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tm2/pkg/bft/config/toml.go b/tm2/pkg/bft/config/toml.go index 371925a84c3..6f9ab670c99 100644 --- a/tm2/pkg/bft/config/toml.go +++ b/tm2/pkg/bft/config/toml.go @@ -78,7 +78,7 @@ func ResetTestRoot(testName string) (cfg *Config, genesisFile string) { baseConfig := DefaultBaseConfig() configFilePath := filepath.Join(rootDir, defaultConfigFileName) - // NOTE: this does not match the behaviour of the TM2 node. + // NOTE: this does not match the behaviour of the Gno.land node. // However, many tests rely on the fact that they can cleanup the directory // by doing RemoveAll on the rootDir; so to keep compatibility with that // behaviour, we place genesis.json in the rootDir. From 595466c2b02f739f6e944157646d77904ae8a6a9 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Wed, 24 Apr 2024 14:59:44 +0200 Subject: [PATCH 12/14] remove context check (ctx is unused anyway) --- gno.land/cmd/gnoland/start_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gno.land/cmd/gnoland/start_test.go b/gno.land/cmd/gnoland/start_test.go index 516e76af2f8..f34d4e5d66e 100644 --- a/gno.land/cmd/gnoland/start_test.go +++ b/gno.land/cmd/gnoland/start_test.go @@ -5,7 +5,6 @@ import ( "context" "path/filepath" "testing" - "time" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/stretchr/testify/assert" @@ -43,15 +42,10 @@ func TestStartInitialize(t *testing.T) { io.SetOut(commands.WriteNopCloser(mockOut)) io.SetErr(commands.WriteNopCloser(mockErr)) - // Create and run the command - ctx, cancelFn := context.WithTimeout(context.Background(), 30*time.Second) - defer cancelFn() - cmd := newRootCmd(io) - require.NoError(t, cmd.ParseAndRun(ctx, args)) + require.NoError(t, cmd.ParseAndRun(context.Background(), args)) // Make sure the directory is created assert.DirExists(t, nodeDir) assert.FileExists(t, genesisFile) - assert.NotErrorIs(t, ctx.Err(), context.DeadlineExceeded, "should not have exceeded deadline (has flag --skip-start)") } From eb5a3a2d3ec9f246f7f7892ebf396eff0d583f8a Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Thu, 25 Apr 2024 14:56:27 +0200 Subject: [PATCH 13/14] Revert dropped test context --- gno.land/cmd/gnoland/start_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gno.land/cmd/gnoland/start_test.go b/gno.land/cmd/gnoland/start_test.go index f34d4e5d66e..cdec6de0f99 100644 --- a/gno.land/cmd/gnoland/start_test.go +++ b/gno.land/cmd/gnoland/start_test.go @@ -5,6 +5,7 @@ import ( "context" "path/filepath" "testing" + "time" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/stretchr/testify/assert" @@ -42,8 +43,12 @@ func TestStartInitialize(t *testing.T) { io.SetOut(commands.WriteNopCloser(mockOut)) io.SetErr(commands.WriteNopCloser(mockErr)) + // Create and run the command + ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second) + defer cancelFn() + cmd := newRootCmd(io) - require.NoError(t, cmd.ParseAndRun(context.Background(), args)) + require.NoError(t, cmd.ParseAndRun(ctx, args)) // Make sure the directory is created assert.DirExists(t, nodeDir) From e1a5d32add095a8aeb4753b7904bbc4485263525 Mon Sep 17 00:00:00 2001 From: Milos Zivkovic Date: Thu, 25 Apr 2024 15:26:22 +0200 Subject: [PATCH 14/14] Make the genesis path absolute --- gno.land/cmd/gnoland/start.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 60d199f5cc1..0cbbc6cb36d 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -111,7 +111,7 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { &c.genesisFile, "genesis", "genesis.json", - "path to genesis file", + "the path to the genesis.json", ) fs.StringVar( @@ -208,6 +208,12 @@ func execStart(c *startCfg, io commands.IO) error { return fmt.Errorf("unable to get absolute path for data directory, %w", err) } + // Get the absolute path to the node's genesis.json + genesisPath, err := filepath.Abs(c.genesisFile) + if err != nil { + return fmt.Errorf("unable to get absolute path for the genesis.json, %w", err) + } + var ( cfg *config.Config loadCfgErr error @@ -251,7 +257,7 @@ func execStart(c *startCfg, io commands.IO) error { // Write genesis file if missing. // NOTE: this will be dropped in a PR that resolves issue #1886: // https://github.com/gnolang/gno/issues/1886 - if !osm.FileExists(c.genesisFile) { + if !osm.FileExists(genesisPath) { // Create priv validator first. // Need it to generate genesis.json newPrivValKey := cfg.PrivValidatorKeyFile() @@ -260,7 +266,7 @@ func execStart(c *startCfg, io commands.IO) error { pk := priv.GetPubKey() // Generate genesis.json file - if err := generateGenesisFile(c.genesisFile, pk, c); err != nil { + if err := generateGenesisFile(genesisPath, pk, c); err != nil { return fmt.Errorf("unable to generate genesis file: %w", err) } } @@ -283,7 +289,7 @@ func execStart(c *startCfg, io commands.IO) error { io.Println(startGraphic) } - gnoNode, err := node.DefaultNewNode(cfg, c.genesisFile, logger) + gnoNode, err := node.DefaultNewNode(cfg, genesisPath, logger) if err != nil { return fmt.Errorf("error in creating node: %w", err) }