Tendermint源码阅读(三)
2018-09-20 本文已影响74人
印随2018
关注点:BaseConfig相关配置
一、BaseConfig的所有配置项
源码文件
tendermint/config/config.go
// 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
RootDir string `mapstructure:"home"`
// TCP or UNIX socket address of the ABCI application,
// or the name of an ABCI application compiled in with the Tendermint binary
ProxyApp string `mapstructure:"proxy_app"`
// A custom human readable name for this node
Moniker string `mapstructure:"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
FastSync bool `mapstructure:"fast_sync"`
// Database backend: leveldb | memdb
DBBackend string `mapstructure:"db_backend"`
// Database directory
DBPath string `mapstructure:"db_dir"`
// Output level for logging
LogLevel string `mapstructure:"log_level"`
// Path to the JSON file containing the initial validator set and other meta data
Genesis string `mapstructure:"genesis_file"`
// Path to the JSON file containing the private key to use as a validator in the consensus protocol
PrivValidator string `mapstructure:"priv_validator_file"`
// TCP or UNIX socket address for Tendermint to listen on for
// connections from an external PrivValidator process
PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"`
// A JSON file containing the private key to use for p2p authenticated encryption
NodeKey string `mapstructure:"node_key_file"`
// Mechanism to connect to the ABCI application: socket | grpc
ABCI string `mapstructure:"abci"`
// TCP or UNIX socket address for the profiling server to listen on
ProfListenAddress string `mapstructure:"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
}
这是tendermint最基本的配置项,其中最为关键的配置项为RootDir,但是,我在代码中找了很久,都没有发现对这个配置项直接赋值的操作,那么,这个配置项是在哪初始化的呢?
rootCmd在执行的时候,预先执行了另外一个函数,我们来看看:
1 func PrepareBaseCmd(cmd *cobra.Command, envPrefix, defaultHome string) Executor {
2 cobra.OnInitialize(func() { initEnv(envPrefix) })
3 cmd.PersistentFlags().StringP(HomeFlag, "", defaultHome, "directory for config and data")
4 cmd.PersistentFlags().Bool(TraceFlag, false, "print out full stack trace on errors")
5 cmd.PersistentPreRunE = concatCobraCmdFuncs(bindFlagsLoadViper, cmd.PersistentPreRunE)
6 return Executor{cmd, os.Exit}
}
其中,在第3行代码中,注入了一个环境变量
home = ~./tendermint # HomeFlag = "home", defaultHome=cfg.DefaultTendermintDir
再回头看看ParseConfig()
这个函数
1 func ParseConfig() (*cfg.Config, error) {
2 conf := cfg.DefaultConfig()
3 err := viper.Unmarshal(conf)
4 if err != nil {
5 return nil, err
6 }
7 conf.SetRoot(conf.RootDir)
8 cfg.EnsureRoot(conf.RootDir)
9 return conf, err
}
在第二行中从代码中加载了默认配置,而第三行会从配置文件中加载配置,实际上,viper先从环境变量中加载对应的配置,下面是viper加载配置的方式:
Viper uses the following precedence order. Each item takes precedence over the item below it:
- explicit call to Set
- flag
- env
- config
- key/value store
- default
从上面可以看出,环境变量是可以覆盖配置文件中的设置的。这个原则可以类比12-Factor