Skip to content

Commit

Permalink
fix config save/ensure/load logic
Browse files Browse the repository at this point in the history
  • Loading branch information
jaekwon committed Sep 3, 2021
1 parent 230e76e commit 0072778
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 112 deletions.
4 changes: 1 addition & 3 deletions cmd/gnoland/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ import (

func main() {
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
cfg := config.DefaultConfig()
rootDir := "testdir"
config.EnsureRoot(rootDir)
cfg.SetRootDir(rootDir)
cfg := config.LoadOrMakeDefaultConfig(rootDir)

// create priv validator first.
// need it to generate genesis.json
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/jmhodges/levigo v1.0.0
github.com/libp2p/go-buffer-pool v0.0.2
github.com/mattn/go-runewidth v0.0.10
github.com/pelletier/go-toml v1.9.3 // indirect
github.com/stretchr/testify v1.6.1
github.com/syndtr/goleveldb v1.0.0
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
Expand Down
76 changes: 55 additions & 21 deletions pkgs/bft/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@ import (
mem "github.com/gnolang/gno/pkgs/bft/mempool/config"
rpc "github.com/gnolang/gno/pkgs/bft/rpc/config"
"github.com/gnolang/gno/pkgs/errors"
osm "github.com/gnolang/gno/pkgs/os"
p2p "github.com/gnolang/gno/pkgs/p2p/config"
)

// Config defines the top level configuration for a Tendermint node
type Config struct {
// Top level options use an anonymous struct
BaseConfig `mapstructure:",squash"`
BaseConfig `toml:",squash"`

// Options for services
RPC *rpc.RPCConfig `mapstructure:"rpc"`
P2P *p2p.P2PConfig `mapstructure:"p2p"`
Mempool *mem.MempoolConfig `mapstructure:"mempool"`
Consensus *cns.ConsensusConfig `mapstructure:"consensus"`
RPC *rpc.RPCConfig `toml:"rpc"`
P2P *p2p.P2PConfig `toml:"p2p"`
Mempool *mem.MempoolConfig `toml:"mempool"`
Consensus *cns.ConsensusConfig `toml:"consensus"`
}

// DefaultConfig returns a default configuration for a Tendermint node
Expand All @@ -36,6 +37,25 @@ func DefaultConfig() *Config {
}
}

// LoadOrMakeDefaultConfig() loads configuration or saves a default one.
func LoadOrMakeDefaultConfig(root string) (cfg *Config) {
configPath := rootify(defaultConfigFilePath, root)
if osm.FileExists(configPath) {
cfg = LoadConfigFile(configPath)
cfg.SetRootDir(root)
cfg.EnsureDirs()
} else {
cfg = DefaultConfig()
cfg.SetRootDir(root)
cfg.EnsureDirs()
WriteConfigFile(configPath, cfg)
}
if err := cfg.ValidateBasic(); err != nil {
panic(err)
}
return cfg
}

// TestConfig returns a configuration that can be used for testing
func TestConfig() *Config {
return &Config{
Expand All @@ -57,6 +77,20 @@ func (cfg *Config) SetRootDir(root string) *Config {
return cfg
}

// EnsureDirs ensures default directories in root dir (and root dir).
func (cfg *Config) EnsureDirs() {
rootDir := cfg.BaseConfig.RootDir
if err := osm.EnsureDir(rootDir, DefaultDirPerm); err != nil {
panic(err.Error())
}
if err := osm.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
panic(err.Error())
}
if err := osm.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
panic(err.Error())
}
}

// ValidateBasic performs basic validation (checking param bounds, etc.) and
// returns an error if any check fails.
func (cfg *Config) ValidateBasic() error {
Expand Down Expand Up @@ -112,23 +146,23 @@ type BaseConfig struct {

// The root directory for all data.
// This should be set in viper so it can unmarshal into this struct
RootDir string `mapstructure:"home"`
RootDir string `toml:"home"`

// TCP or UNIX socket address of the ABCI application,
// or the name of an ABCI application compiled in with the Tendermint binary,
// or empty if local application instance.
ProxyApp string `mapstructure:"proxy_app"`
ProxyApp string `toml:"proxy_app"`

// Local application instance in lieu of remote app.
LocalApp abci.Application

// A custom human readable name for this node
Moniker string `mapstructure:"moniker"`
Moniker string `toml:"moniker"`

// If this node is many blocks behind the tip of the chain, FastSync
// allows them to catchup quickly by downloading blocks in parallel
// and verifying their commits
FastSyncMode bool `mapstructure:"fast_sync"`
FastSyncMode bool `toml:"fast_sync"`

// Database backend: goleveldb | cleveldb | boltdb
// * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
Expand All @@ -142,42 +176,42 @@ type BaseConfig struct {
// - EXPERIMENTAL
// - may be faster is some use-cases (random reads - indexer)
// - use boltdb build tag (go build -tags boltdb)
DBBackend string `mapstructure:"db_backend"`
DBBackend string `toml:"db_backend"`

// Database directory
DBPath string `mapstructure:"db_dir"`
DBPath string `toml:"db_dir"`

// Output level for logging
LogLevel string `mapstructure:"log_level"`
LogLevel string `toml:"log_level"`

// Output format: 'plain' (colored text) or 'json'
LogFormat string `mapstructure:"log_format"`
LogFormat string `toml:"log_format"`

// Path to the JSON file containing the initial validator set and other meta data
Genesis string `mapstructure:"genesis_file"`
Genesis string `toml:"genesis_file"`

// Path to the JSON file containing the private key to use as a validator in the consensus protocol
PrivValidatorKey string `mapstructure:"priv_validator_key_file"`
PrivValidatorKey string `toml:"priv_validator_key_file"`

// Path to the JSON file containing the last sign state of a validator
PrivValidatorState string `mapstructure:"priv_validator_state_file"`
PrivValidatorState string `toml:"priv_validator_state_file"`

// TCP or UNIX socket address for Tendermint to listen on for
// connections from an external PrivValidator process
PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"`
PrivValidatorListenAddr string `toml:"priv_validator_laddr"`

// A JSON file containing the private key to use for p2p authenticated encryption
NodeKey string `mapstructure:"node_key_file"`
NodeKey string `toml:"node_key_file"`

// Mechanism to connect to the ABCI application: local | socket
ABCI string `mapstructure:"abci"`
ABCI string `toml:"abci"`

// TCP or UNIX socket address for the profiling server to listen on
ProfListenAddress string `mapstructure:"prof_laddr"`
ProfListenAddress string `toml:"prof_laddr"`

// If true, query the ABCI app on connecting to a new peer
// so the app can decide if we should keep the connection or not
FilterPeers bool `mapstructure:"filter_peers"` // false
FilterPeers bool `toml:"filter_peers"` // false
}

// DefaultBaseConfig returns a default base configuration for a Tendermint node
Expand Down
39 changes: 13 additions & 26 deletions pkgs/bft/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"text/template"

osm "github.com/gnolang/gno/pkgs/os"
"github.com/pelletier/go-toml"
)

// DefaultDirPerm is the default permissions used when creating directories.
Expand All @@ -22,34 +23,20 @@ func init() {
}
}

/****** these are for production settings ***********/

// EnsureRoot creates the root, config, and data directories if they don't exist,
// and panics if it fails.
func EnsureRoot(rootDir string) {
if err := osm.EnsureDir(rootDir, DefaultDirPerm); err != nil {
panic(err.Error())
}
if err := osm.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
panic(err.Error())
}
if err := osm.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
panic(err.Error())
func LoadConfigFile(configFilePath string) *Config {
bz, err := ioutil.ReadFile(configFilePath)
if err != nil {
panic(err)
}

configFilePath := filepath.Join(rootDir, defaultConfigFilePath)

// Write default config file if missing.
if !osm.FileExists(configFilePath) {
writeDefaultConfigFile(configFilePath)
var config Config
err = toml.Unmarshal(bz, &config)
if err != nil {
panic(err)
}
return &config
}

// XXX: this func should probably be called by cmd/tendermint/commands/init.go
// alongside the writing of the genesis.json and priv_validator.json
func writeDefaultConfigFile(configFilePath string) {
WriteConfigFile(configFilePath, DefaultConfig())
}
/****** these are for production settings ***********/

// WriteConfigFile renders config using the template and writes it to configFilePath.
func WriteConfigFile(configFilePath string, config *Config) {
Expand All @@ -62,7 +49,7 @@ func WriteConfigFile(configFilePath string, config *Config) {
osm.MustWriteFile(configFilePath, buffer.Bytes(), 0644)
}

// Note: any changes to the comments/variables/mapstructure
// Note: any changes to the comments/variables/field-names
// must be reflected in the appropriate struct in config/config.go
const defaultConfigTemplate = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
Expand Down Expand Up @@ -330,7 +317,7 @@ func ResetTestRootWithChainID(testName string, chainID string) *Config {

// Write default config file if missing.
if !osm.FileExists(configFilePath) {
writeDefaultConfigFile(configFilePath)
WriteConfigFile(configFilePath, DefaultConfig())
}
if !osm.FileExists(genesisFilePath) {
if chainID == "" {
Expand Down
28 changes: 14 additions & 14 deletions pkgs/bft/consensus/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,28 @@ const (
// ConsensusConfig defines the configuration for the Tendermint consensus service,
// including timeouts and details about the WAL and the block structure.
type ConsensusConfig struct {
RootDir string `mapstructure:"home"`
WalPath string `mapstructure:"wal_file"`
RootDir string `toml:"home"`
WalPath string `toml:"wal_file"`
walFile string // overrides WalPath if set

TimeoutPropose time.Duration `mapstructure:"timeout_propose"`
TimeoutProposeDelta time.Duration `mapstructure:"timeout_propose_delta"`
TimeoutPrevote time.Duration `mapstructure:"timeout_prevote"`
TimeoutPrevoteDelta time.Duration `mapstructure:"timeout_prevote_delta"`
TimeoutPrecommit time.Duration `mapstructure:"timeout_precommit"`
TimeoutPrecommitDelta time.Duration `mapstructure:"timeout_precommit_delta"`
TimeoutCommit time.Duration `mapstructure:"timeout_commit"`
TimeoutPropose time.Duration `toml:"timeout_propose"`
TimeoutProposeDelta time.Duration `toml:"timeout_propose_delta"`
TimeoutPrevote time.Duration `toml:"timeout_prevote"`
TimeoutPrevoteDelta time.Duration `toml:"timeout_prevote_delta"`
TimeoutPrecommit time.Duration `toml:"timeout_precommit"`
TimeoutPrecommitDelta time.Duration `toml:"timeout_precommit_delta"`
TimeoutCommit time.Duration `toml:"timeout_commit"`

// Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"`
SkipTimeoutCommit bool `toml:"skip_timeout_commit"`

// EmptyBlocks mode and possible interval between empty blocks
CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"`
CreateEmptyBlocksInterval time.Duration `mapstructure:"create_empty_blocks_interval"`
CreateEmptyBlocks bool `toml:"create_empty_blocks"`
CreateEmptyBlocksInterval time.Duration `toml:"create_empty_blocks_interval"`

// Reactor sleep duration parameters
PeerGossipSleepDuration time.Duration `mapstructure:"peer_gossip_sleep_duration"`
PeerQueryMaj23SleepDuration time.Duration `mapstructure:"peer_query_maj23_sleep_duration"`
PeerGossipSleepDuration time.Duration `toml:"peer_gossip_sleep_duration"`
PeerQueryMaj23SleepDuration time.Duration `toml:"peer_query_maj23_sleep_duration"`
}

// DefaultConsensusConfig returns a default configuration for the consensus service
Expand Down
14 changes: 7 additions & 7 deletions pkgs/bft/mempool/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import "github.com/gnolang/gno/pkgs/errors"

// MempoolConfig defines the configuration options for the Tendermint mempool
type MempoolConfig struct {
RootDir string `mapstructure:"home"`
Recheck bool `mapstructure:"recheck"`
Broadcast bool `mapstructure:"broadcast"`
WalPath string `mapstructure:"wal_dir"`
Size int `mapstructure:"size"`
MaxPendingTxsBytes int64 `mapstructure:"max_pending_txs_bytes"`
CacheSize int `mapstructure:"cache_size"`
RootDir string `toml:"home"`
Recheck bool `toml:"recheck"`
Broadcast bool `toml:"broadcast"`
WalPath string `toml:"wal_dir"`
Size int `toml:"size"`
MaxPendingTxsBytes int64 `toml:"max_pending_txs_bytes"`
CacheSize int `toml:"cache_size"`
}

// DefaultMempoolConfig returns a default configuration for the Tendermint mempool
Expand Down
Loading

0 comments on commit 0072778

Please sign in to comment.