diff --git a/cmd/barak/main.go b/cmd/barak/main.go index ca64e4176..8c54fddf3 100644 --- a/cmd/barak/main.go +++ b/cmd/barak/main.go @@ -50,7 +50,9 @@ func main() { fmt.Printf("New Barak Process (PID: %d)\n", os.Getpid()) // Apply bare tendermint/* configuration. - cfg.ApplyConfig(cfg.MapConfig(map[string]interface{}{"log_level": "info"})) + config := cfg.NewMapConfig(nil) + config.Set("log_level", "info") + cfg.ApplyConfig(config) // Read options optionsFile := parseFlags() diff --git a/cmd/debora/main.go b/cmd/debora/main.go index 45a1b0c52..402ea520c 100644 --- a/cmd/debora/main.go +++ b/cmd/debora/main.go @@ -35,7 +35,9 @@ func main() { fmt.Printf("New Debora Process (PID: %d)\n", os.Getpid()) // Apply bare tendermint/* configuration. - cfg.ApplyConfig(cfg.MapConfig(map[string]interface{}{"log_level": "notice"})) + config := cfg.NewMapConfig(nil) + config.Set("log_level", "notice") + cfg.ApplyConfig(config) rootDir := os.Getenv("DEBROOT") if rootDir == "" { diff --git a/config/config.go b/config/config.go index 43963e25a..c9becc984 100644 --- a/config/config.go +++ b/config/config.go @@ -1,8 +1,11 @@ package config import ( + "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/naoina/toml" "sync" "time" + + . "github.com/tendermint/tendermint/common" ) type Config interface { @@ -19,28 +22,66 @@ type Config interface { Set(key string, value interface{}) } -type MapConfig map[string]interface{} +type MapConfig struct { + required map[string]struct{} // blows up if trying to use before setting. + data map[string]interface{} +} + +func ReadMapConfigFromFile(filePath string) (MapConfig, error) { + var configData = make(map[string]interface{}) + fileBytes := MustReadFile(filePath) + err := toml.Unmarshal(fileBytes, configData) + if err != nil { + return MapConfig{}, err + } + return NewMapConfig(configData), nil +} + +func NewMapConfig(data map[string]interface{}) MapConfig { + if data == nil { + data = make(map[string]interface{}) + } + return MapConfig{ + required: make(map[string]struct{}), + data: data, + } +} -func (cfg MapConfig) Get(key string) interface{} { return cfg[key] } -func (cfg MapConfig) GetBool(key string) bool { return cfg[key].(bool) } -func (cfg MapConfig) GetFloat64(key string) float64 { return cfg[key].(float64) } -func (cfg MapConfig) GetInt(key string) int { return cfg[key].(int) } -func (cfg MapConfig) GetString(key string) string { return cfg[key].(string) } +func (cfg MapConfig) Get(key string) interface{} { + if _, ok := cfg.required[key]; ok { + PanicSanity(Fmt("config key %v is required but was not set.", key)) + } + return cfg.data[key] +} +func (cfg MapConfig) GetBool(key string) bool { return cfg.Get(key).(bool) } +func (cfg MapConfig) GetFloat64(key string) float64 { return cfg.Get(key).(float64) } +func (cfg MapConfig) GetInt(key string) int { return cfg.Get(key).(int) } +func (cfg MapConfig) GetString(key string) string { return cfg.Get(key).(string) } func (cfg MapConfig) GetStringMap(key string) map[string]interface{} { - return cfg[key].(map[string]interface{}) + return cfg.Get(key).(map[string]interface{}) } func (cfg MapConfig) GetStringMapString(key string) map[string]string { - return cfg[key].(map[string]string) + return cfg.Get(key).(map[string]string) +} +func (cfg MapConfig) GetStringSlice(key string) []string { return cfg.Get(key).([]string) } +func (cfg MapConfig) GetTime(key string) time.Time { return cfg.Get(key).(time.Time) } +func (cfg MapConfig) IsSet(key string) bool { _, ok := cfg.data[key]; return ok } +func (cfg MapConfig) Set(key string, value interface{}) { + delete(cfg.required, key) + cfg.data[key] = value } -func (cfg MapConfig) GetStringSlice(key string) []string { return cfg[key].([]string) } -func (cfg MapConfig) GetTime(key string) time.Time { return cfg[key].(time.Time) } -func (cfg MapConfig) IsSet(key string) bool { _, ok := cfg[key]; return ok } -func (cfg MapConfig) Set(key string, value interface{}) { cfg[key] = value } func (cfg MapConfig) SetDefault(key string, value interface{}) { + delete(cfg.required, key) + if cfg.IsSet(key) { + return + } + cfg.data[key] = value +} +func (cfg MapConfig) SetRequired(key string) { if cfg.IsSet(key) { return } - cfg[key] = value + cfg.required[key] = struct{}{} } //-------------------------------------------------------------------------------- diff --git a/config/tendermint/config.go b/config/tendermint/config.go index e8abcebbb..e18f3c83f 100644 --- a/config/tendermint/config.go +++ b/config/tendermint/config.go @@ -1,7 +1,6 @@ package tendermint import ( - "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/naoina/toml" "os" "path" "strings" @@ -38,10 +37,8 @@ func GetConfig(rootDir string) cfg.Config { rootDir = getTMRoot(rootDir) initTMRoot(rootDir) - var mapConfig = cfg.MapConfig(make(map[string]interface{})) configFilePath := path.Join(rootDir, "config.toml") - configFileBytes := MustReadFile(configFilePath) - err := toml.Unmarshal(configFileBytes, mapConfig) + mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) if err != nil { Exit(Fmt("Could not read config: %v", err)) } @@ -53,7 +50,7 @@ func GetConfig(rootDir string) cfg.Config { if mapConfig.IsSet("revision_file") { Exit("Cannot set 'revision_file' via config.toml. It must match what's in the Makefile") } - mapConfig.SetDefault("chain_id", "tendermint_testnet_11.c") // TODO ALSO UPDATE GENESIS BELOW!!! + mapConfig.SetRequired("chain_id") // blows up if you try to use it before setting. mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") mapConfig.SetDefault("moniker", "anonymous") mapConfig.SetDefault("node_laddr", "0.0.0.0:46656") @@ -73,12 +70,6 @@ func GetConfig(rootDir string) cfg.Config { return mapConfig } -func ensureDefault(mapConfig cfg.MapConfig, key string, value interface{}) { - if !mapConfig.IsSet(key) { - mapConfig[key] = value - } -} - var defaultConfigTmpl = `# This is a TOML config file. # For more information, see https://github.com/toml-lang/toml diff --git a/config/tendermint_test/config.go b/config/tendermint_test/config.go index 79a42e495..9e530a71d 100644 --- a/config/tendermint_test/config.go +++ b/config/tendermint_test/config.go @@ -3,7 +3,6 @@ package tendermint_test import ( - "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/naoina/toml" "os" "path" "strings" @@ -47,10 +46,8 @@ func GetConfig(rootDir string) cfg.Config { rootDir = getTMRoot(rootDir) initTMRoot(rootDir) - var mapConfig = cfg.MapConfig(make(map[string]interface{})) configFilePath := path.Join(rootDir, "config.toml") - configFileBytes := MustReadFile(configFilePath) - err := toml.Unmarshal(configFileBytes, mapConfig) + mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) if err != nil { Exit(Fmt("Could not read config: %v", err)) } @@ -78,12 +75,6 @@ func GetConfig(rootDir string) cfg.Config { return mapConfig } -func ensureDefault(mapConfig cfg.MapConfig, key string, value interface{}) { - if !mapConfig.IsSet(key) { - mapConfig[key] = value - } -} - var defaultConfigTmpl = `# This is a TOML config file. # For more information, see https://github.com/toml-lang/toml diff --git a/node/node.go b/node/node.go index 1ca41b935..75c35da2f 100644 --- a/node/node.go +++ b/node/node.go @@ -2,6 +2,7 @@ package node import ( "bytes" + "io/ioutil" "math/rand" "net" "net/http" @@ -297,6 +298,16 @@ func RunNode() { if FileExists(genDocFile) { break } + jsonBlob, err := ioutil.ReadFile(genDocFile) + if err != nil { + Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) + } + genDoc := stypes.GenesisDocFromJSON(jsonBlob) + if genDoc.ChainID == "" { + PanicSanity(Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) + } + config.Set("chain_id", genDoc.ChainID) + config.Set("genesis_doc", genDoc) } }