Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: load config defaults if not specified in existing config #1544

Merged
merged 10 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contribs/gnodev/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
)

require (
dario.cat/mergo v1.0.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contribs/gnodev/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contribs/gnokeykc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
Expand Down
3 changes: 3 additions & 0 deletions contribs/gnokeykc/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,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, nil)
cfg, loadCfgErr = config.LoadOrMakeConfigWithOptions(dataDir)
}

if loadCfgErr != nil {
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ require (
gopkg.in/yaml.v3 v3.0.1
)

require dario.cat/mergo v1.0.0

require (
github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions misc/loop/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
)

require (
dario.cat/mergo v1.0.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions misc/loop/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions tm2/pkg/bft/blockchain/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"testing"
"time"

"github.com/stretchr/testify/assert"

abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
cfg "github.com/gnolang/gno/tm2/pkg/bft/config"
"github.com/gnolang/gno/tm2/pkg/bft/mempool/mock"
Expand All @@ -21,6 +19,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/log"
"github.com/gnolang/gno/tm2/pkg/p2p"
"github.com/gnolang/gno/tm2/pkg/testutils"
"github.com/stretchr/testify/assert"
)

var config *cfg.Config
Expand Down
88 changes: 60 additions & 28 deletions tm2/pkg/bft/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"os"
"path/filepath"

"dario.cat/mergo"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
cns "github.com/gnolang/gno/tm2/pkg/bft/consensus/config"
mem "github.com/gnolang/gno/tm2/pkg/bft/mempool/config"
Expand All @@ -20,7 +21,7 @@
// Top level options use an anonymous struct
BaseConfig `toml:",squash"`

// Options for services
// Option for services
thehowl marked this conversation as resolved.
Show resolved Hide resolved
RPC *rpc.RPCConfig `toml:"rpc"`
P2P *p2p.P2PConfig `toml:"p2p"`
Mempool *mem.MempoolConfig `toml:"mempool"`
Expand All @@ -40,37 +41,62 @@
}
}

type ConfigOptions func(cfg *Config)
type Option func(cfg *Config)

// LoadOrMakeConfigWithOptions loads configuration or saves one
// made by modifying the default config with override options
thehowl marked this conversation as resolved.
Show resolved Hide resolved
func LoadOrMakeConfigWithOptions(root string, options ConfigOptions) (*Config, error) {
var cfg *Config

configPath := join(root, defaultConfigFilePath)
func LoadOrMakeConfigWithOptions(root string, opts ...Option) (*Config, error) {
// Initialize the config as default
var (
cfg = DefaultConfig()
configPath = join(root, defaultConfigFilePath)
)

// Check if the config exists

Check warning on line 55 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L48-L55

Added lines #L48 - L55 were not covered by tests
if osm.FileExists(configPath) {
var loadErr error

// Load the configuration
if cfg, loadErr = LoadConfigFile(configPath); loadErr != nil {
loadedCfg, loadErr := LoadConfigFile(configPath)
if loadErr != nil {

Check warning on line 59 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L58-L59

Added lines #L58 - L59 were not covered by tests
return nil, loadErr
}

cfg.SetRootDir(root)
cfg.EnsureDirs()
} else {
cfg = DefaultConfig()
if options != nil {
options(cfg)
// Merge the loaded config with the default values
if err := mergo.Merge(loadedCfg, cfg); err != nil {
return nil, err

Check warning on line 65 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L64-L65

Added lines #L64 - L65 were not covered by tests
}
cfg.SetRootDir(root)
cfg.EnsureDirs()
WriteConfigFile(configPath, cfg)

// Validate the configuration
if validateErr := cfg.ValidateBasic(); validateErr != nil {
return nil, fmt.Errorf("unable to validate config, %w", validateErr)
// Set the root directory
loadedCfg.SetRootDir(root)

// Make sure the directories are initialized
if err := loadedCfg.EnsureDirs(); err != nil {
return nil, err

Check warning on line 73 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L69-L73

Added lines #L69 - L73 were not covered by tests
thehowl marked this conversation as resolved.
Show resolved Hide resolved
}

return loadedCfg, nil

Check warning on line 76 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L76

Added line #L76 was not covered by tests
}

// Config doesn't exist, create it
// from the default one
for _, opt := range opts {
opt(cfg)
}

Check warning on line 83 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L81-L83

Added lines #L81 - L83 were not covered by tests

cfg.SetRootDir(root)

// Make sure the directories are initialized
if err := cfg.EnsureDirs(); err != nil {
return nil, err
}

Check warning on line 90 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L85-L90

Added lines #L85 - L90 were not covered by tests

// Validate the configuration
if validateErr := cfg.ValidateBasic(); validateErr != nil {
return nil, fmt.Errorf("unable to validate config, %w", validateErr)
}

Check warning on line 95 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L93-L95

Added lines #L93 - L95 were not covered by tests

// Save the config
if err := WriteConfigFile(configPath, cfg); err != nil {
return nil, err

Check warning on line 99 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L98-L99

Added lines #L98 - L99 were not covered by tests
}

return cfg, nil
Expand All @@ -79,7 +105,7 @@
// TestConfig returns a configuration that can be used for testing
func TestConfig() *Config {
return &Config{
BaseConfig: TestBaseConfig(),
BaseConfig: testBaseConfig(),

Check warning on line 108 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L108

Added line #L108 was not covered by tests
RPC: rpc.TestRPCConfig(),
P2P: p2p.TestP2PConfig(),
Mempool: mem.TestMempoolConfig(),
Expand All @@ -95,21 +121,27 @@
cfg.P2P.RootDir = root
cfg.Mempool.RootDir = root
cfg.Consensus.RootDir = root

Check warning on line 124 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L124

Added line #L124 was not covered by tests
return cfg
}

// EnsureDirs ensures default directories in root dir (and root dir).
func (cfg *Config) EnsureDirs() {
func (cfg *Config) EnsureDirs() error {

Check warning on line 129 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L129

Added line #L129 was not covered by tests
rootDir := cfg.BaseConfig.RootDir

Check warning on line 131 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L131

Added line #L131 was not covered by tests
if err := osm.EnsureDir(rootDir, DefaultDirPerm); err != nil {
panic(err.Error())
return fmt.Errorf("no root directory, %w", err)

Check warning on line 133 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L133

Added line #L133 was not covered by tests
}

if err := osm.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
panic(err.Error())
return fmt.Errorf("no config directory, %w", err)

Check warning on line 137 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L137

Added line #L137 was not covered by tests
}

if err := osm.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
panic(err.Error())
return fmt.Errorf("no data directory, %w", err)

Check warning on line 141 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L141

Added line #L141 was not covered by tests
}

return nil

Check warning on line 144 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L144

Added line #L144 was not covered by tests
}

// ValidateBasic performs basic validation (checking param bounds, etc.) and
Expand Down Expand Up @@ -255,8 +287,8 @@
}
}

// TestBaseConfig returns a base configuration for testing a Tendermint node
func TestBaseConfig() BaseConfig {
// testBaseConfig returns a base configuration for testing a Tendermint node
func testBaseConfig() BaseConfig {

Check warning on line 291 in tm2/pkg/bft/config/config.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/bft/config/config.go#L291

Added line #L291 was not covered by tests
cfg := DefaultBaseConfig()
cfg.chainID = "tendermint_test"
cfg.ProxyApp = "mock://kvstore"
Expand Down
90 changes: 90 additions & 0 deletions tm2/pkg/bft/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package config

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestConfig_LoadOrMakeConfigWithOptions(t *testing.T) {
t.Parallel()

t.Run("existing configuration", func(t *testing.T) {
t.Parallel()

// Provide an empty directory
cfgDir := t.TempDir()
cfgPath := join(cfgDir, defaultConfigFilePath)

// Create a default config
cfg := DefaultConfig()
cfg.SetRootDir(cfgDir)

// Make an incremental changes
cfg.Moniker = "custom monkier"
thehowl marked this conversation as resolved.
Show resolved Hide resolved

// Make sure the cfg paths are initialized
require.NoError(t, cfg.EnsureDirs())

// Write the config
require.NoError(t, WriteConfigFile(cfgPath, cfg))

// Load the config
loadedCfg, loadErr := LoadOrMakeConfigWithOptions(cfgDir)
require.NoError(t, loadErr)

assert.Equal(t, cfg, loadedCfg)
})

t.Run("no existing config", func(t *testing.T) {
t.Parallel()

// Provide an empty directory
cfgDir := t.TempDir()
cfgPath := join(cfgDir, defaultConfigFilePath)

cfg, err := LoadOrMakeConfigWithOptions(cfgDir)
require.NoError(t, err)

// Make sure the returned cfg is the default one
expectedCfg := DefaultConfig()
expectedCfg.SetRootDir(cfgDir)

assert.Equal(t, expectedCfg, cfg)

// Make sure the returned config was saved
loadedCfg, loadErr := LoadConfigFile(cfgPath)
require.NoError(t, loadErr)

loadedCfg.SetRootDir(cfgDir)

assert.Equal(t, cfg, loadedCfg)
})

t.Run("no existing config, with options", func(t *testing.T) {
t.Parallel()

monkier := "dummy monkier"
thehowl marked this conversation as resolved.
Show resolved Hide resolved

// Provide an empty directory
cfgDir := t.TempDir()
cfgPath := join(cfgDir, defaultConfigFilePath)

cfg, err := LoadOrMakeConfigWithOptions(
cfgDir,
func(cfg *Config) {
cfg.BaseConfig.Moniker = monkier
},
)
require.NoError(t, err)

// Make sure the returned config was saved
loadedCfg, loadErr := LoadConfigFile(cfgPath)
require.NoError(t, loadErr)

loadedCfg.SetRootDir(cfgDir)

assert.Equal(t, cfg, loadedCfg)
})
}
Loading
Loading