You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

515 lines
17 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package config
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "time"
  7. )
  8. // Note: Most of the structs & relevant comments + the
  9. // default configuration options were used to manually
  10. // generate the config.toml. Please reflect any changes
  11. // made here in the defaultConfigTemplate constant in
  12. // config/toml.go
  13. var (
  14. DefaultTendermintDir = ".tendermint"
  15. defaultConfigDir = "config"
  16. defaultDataDir = "data"
  17. defaultConfigFileName = "config.toml"
  18. defaultGenesisJSONName = "genesis.json"
  19. defaultPrivValName = "priv_validator.json"
  20. defaultNodeKeyName = "node_key.json"
  21. defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
  22. defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
  23. defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName)
  24. defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName)
  25. )
  26. // Config defines the top level configuration for a Tendermint node
  27. type Config struct {
  28. // Top level options use an anonymous struct
  29. BaseConfig `mapstructure:",squash"`
  30. // Options for services
  31. RPC *RPCConfig `mapstructure:"rpc"`
  32. P2P *P2PConfig `mapstructure:"p2p"`
  33. Mempool *MempoolConfig `mapstructure:"mempool"`
  34. Consensus *ConsensusConfig `mapstructure:"consensus"`
  35. TxIndex *TxIndexConfig `mapstructure:"tx_index"`
  36. }
  37. // DefaultConfig returns a default configuration for a Tendermint node
  38. func DefaultConfig() *Config {
  39. return &Config{
  40. BaseConfig: DefaultBaseConfig(),
  41. RPC: DefaultRPCConfig(),
  42. P2P: DefaultP2PConfig(),
  43. Mempool: DefaultMempoolConfig(),
  44. Consensus: DefaultConsensusConfig(),
  45. TxIndex: DefaultTxIndexConfig(),
  46. }
  47. }
  48. // TestConfig returns a configuration that can be used for testing
  49. func TestConfig() *Config {
  50. return &Config{
  51. BaseConfig: TestBaseConfig(),
  52. RPC: TestRPCConfig(),
  53. P2P: TestP2PConfig(),
  54. Mempool: DefaultMempoolConfig(),
  55. Consensus: TestConsensusConfig(),
  56. TxIndex: DefaultTxIndexConfig(),
  57. }
  58. }
  59. // SetRoot sets the RootDir for all Config structs
  60. func (cfg *Config) SetRoot(root string) *Config {
  61. cfg.BaseConfig.RootDir = root
  62. cfg.RPC.RootDir = root
  63. cfg.P2P.RootDir = root
  64. cfg.Mempool.RootDir = root
  65. cfg.Consensus.RootDir = root
  66. return cfg
  67. }
  68. //-----------------------------------------------------------------------------
  69. // BaseConfig
  70. // BaseConfig defines the base configuration for a Tendermint node
  71. type BaseConfig struct {
  72. // chainID is unexposed and immutable but here for convenience
  73. chainID string
  74. // The root directory for all data.
  75. // This should be set in viper so it can unmarshal into this struct
  76. RootDir string `mapstructure:"home"`
  77. // Path to the JSON file containing the initial validator set and other meta data
  78. Genesis string `mapstructure:"genesis_file"`
  79. // Path to the JSON file containing the private key to use as a validator in the consensus protocol
  80. PrivValidator string `mapstructure:"priv_validator_file"`
  81. // A JSON file containing the private key to use for p2p authenticated encryption
  82. NodeKey string `mapstructure:"node_key_file"`
  83. // A custom human readable name for this node
  84. Moniker string `mapstructure:"moniker"`
  85. // TCP or UNIX socket address of the ABCI application,
  86. // or the name of an ABCI application compiled in with the Tendermint binary
  87. ProxyApp string `mapstructure:"proxy_app"`
  88. // Mechanism to connect to the ABCI application: socket | grpc
  89. ABCI string `mapstructure:"abci"`
  90. // Output level for logging
  91. LogLevel string `mapstructure:"log_level"`
  92. // TCP or UNIX socket address for the profiling server to listen on
  93. ProfListenAddress string `mapstructure:"prof_laddr"`
  94. // If this node is many blocks behind the tip of the chain, FastSync
  95. // allows them to catchup quickly by downloading blocks in parallel
  96. // and verifying their commits
  97. FastSync bool `mapstructure:"fast_sync"`
  98. // If true, query the ABCI app on connecting to a new peer
  99. // so the app can decide if we should keep the connection or not
  100. FilterPeers bool `mapstructure:"filter_peers"` // false
  101. // Database backend: leveldb | memdb
  102. DBBackend string `mapstructure:"db_backend"`
  103. // Database directory
  104. DBPath string `mapstructure:"db_dir"`
  105. }
  106. func (c BaseConfig) ChainID() string {
  107. return c.chainID
  108. }
  109. // DefaultBaseConfig returns a default base configuration for a Tendermint node
  110. func DefaultBaseConfig() BaseConfig {
  111. return BaseConfig{
  112. Genesis: defaultGenesisJSONPath,
  113. PrivValidator: defaultPrivValPath,
  114. NodeKey: defaultNodeKeyPath,
  115. Moniker: defaultMoniker,
  116. ProxyApp: "tcp://127.0.0.1:46658",
  117. ABCI: "socket",
  118. LogLevel: DefaultPackageLogLevels(),
  119. ProfListenAddress: "",
  120. FastSync: true,
  121. FilterPeers: false,
  122. DBBackend: "leveldb",
  123. DBPath: "data",
  124. }
  125. }
  126. // TestBaseConfig returns a base configuration for testing a Tendermint node
  127. func TestBaseConfig() BaseConfig {
  128. conf := DefaultBaseConfig()
  129. conf.chainID = "tendermint_test"
  130. conf.ProxyApp = "dummy"
  131. conf.FastSync = false
  132. conf.DBBackend = "memdb"
  133. return conf
  134. }
  135. // GenesisFile returns the full path to the genesis.json file
  136. func (b BaseConfig) GenesisFile() string {
  137. return rootify(b.Genesis, b.RootDir)
  138. }
  139. // PrivValidatorFile returns the full path to the priv_validator.json file
  140. func (b BaseConfig) PrivValidatorFile() string {
  141. return rootify(b.PrivValidator, b.RootDir)
  142. }
  143. // NodeKeyFile returns the full path to the node_key.json file
  144. func (b BaseConfig) NodeKeyFile() string {
  145. return rootify(b.NodeKey, b.RootDir)
  146. }
  147. // DBDir returns the full path to the database directory
  148. func (b BaseConfig) DBDir() string {
  149. return rootify(b.DBPath, b.RootDir)
  150. }
  151. // DefaultLogLevel returns a default log level of "error"
  152. func DefaultLogLevel() string {
  153. return "error"
  154. }
  155. // DefaultPackageLogLevels returns a default log level setting so all packages log at "error", while the `state` package logs at "info"
  156. func DefaultPackageLogLevels() string {
  157. return fmt.Sprintf("state:info,*:%s", DefaultLogLevel())
  158. }
  159. //-----------------------------------------------------------------------------
  160. // RPCConfig
  161. // RPCConfig defines the configuration options for the Tendermint RPC server
  162. type RPCConfig struct {
  163. RootDir string `mapstructure:"home"`
  164. // TCP or UNIX socket address for the RPC server to listen on
  165. ListenAddress string `mapstructure:"laddr"`
  166. // TCP or UNIX socket address for the gRPC server to listen on
  167. // NOTE: This server only supports /broadcast_tx_commit
  168. GRPCListenAddress string `mapstructure:"grpc_laddr"`
  169. // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool
  170. Unsafe bool `mapstructure:"unsafe"`
  171. }
  172. // DefaultRPCConfig returns a default configuration for the RPC server
  173. func DefaultRPCConfig() *RPCConfig {
  174. return &RPCConfig{
  175. ListenAddress: "tcp://0.0.0.0:46657",
  176. GRPCListenAddress: "",
  177. Unsafe: false,
  178. }
  179. }
  180. // TestRPCConfig returns a configuration for testing the RPC server
  181. func TestRPCConfig() *RPCConfig {
  182. conf := DefaultRPCConfig()
  183. conf.ListenAddress = "tcp://0.0.0.0:36657"
  184. conf.GRPCListenAddress = "tcp://0.0.0.0:36658"
  185. conf.Unsafe = true
  186. return conf
  187. }
  188. //-----------------------------------------------------------------------------
  189. // P2PConfig
  190. // P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer
  191. type P2PConfig struct {
  192. RootDir string `mapstructure:"home"`
  193. // Address to listen for incoming connections
  194. ListenAddress string `mapstructure:"laddr"`
  195. // Comma separated list of seed nodes to connect to
  196. // We only use these if we can’t connect to peers in the addrbook
  197. Seeds string `mapstructure:"seeds"`
  198. // Comma separated list of persistent peers to connect to
  199. // We always connect to these
  200. PersistentPeers string `mapstructure:"persistent_peers"`
  201. // Skip UPNP port forwarding
  202. SkipUPNP bool `mapstructure:"skip_upnp"`
  203. // Path to address book
  204. AddrBook string `mapstructure:"addr_book_file"`
  205. // Set true for strict address routability rules
  206. AddrBookStrict bool `mapstructure:"addr_book_strict"`
  207. // Set true to enable the peer-exchange reactor
  208. PexReactor bool `mapstructure:"pex"`
  209. // Maximum number of peers to connect to
  210. MaxNumPeers int `mapstructure:"max_num_peers"`
  211. // Time to wait before flushing messages out on the connection, in ms
  212. FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"`
  213. // Maximum size of a message packet payload, in bytes
  214. MaxMsgPacketPayloadSize int `mapstructure:"max_msg_packet_payload_size"`
  215. // Rate at which packets can be sent, in bytes/second
  216. SendRate int64 `mapstructure:"send_rate"`
  217. // Rate at which packets can be received, in bytes/second
  218. RecvRate int64 `mapstructure:"recv_rate"`
  219. }
  220. // DefaultP2PConfig returns a default configuration for the peer-to-peer layer
  221. func DefaultP2PConfig() *P2PConfig {
  222. return &P2PConfig{
  223. ListenAddress: "tcp://0.0.0.0:46656",
  224. AddrBook: "addrbook.json",
  225. AddrBookStrict: true,
  226. MaxNumPeers: 50,
  227. FlushThrottleTimeout: 100,
  228. MaxMsgPacketPayloadSize: 1024, // 1 kB
  229. SendRate: 512000, // 500 kB/s
  230. RecvRate: 512000, // 500 kB/s
  231. PexReactor: true,
  232. }
  233. }
  234. // TestP2PConfig returns a configuration for testing the peer-to-peer layer
  235. func TestP2PConfig() *P2PConfig {
  236. conf := DefaultP2PConfig()
  237. conf.ListenAddress = "tcp://0.0.0.0:36656"
  238. conf.SkipUPNP = true
  239. return conf
  240. }
  241. // AddrBookFile returns the full path to the address book
  242. func (p *P2PConfig) AddrBookFile() string {
  243. return rootify(p.AddrBook, p.RootDir)
  244. }
  245. //-----------------------------------------------------------------------------
  246. // MempoolConfig
  247. // MempoolConfig defines the configuration options for the Tendermint mempool
  248. type MempoolConfig struct {
  249. RootDir string `mapstructure:"home"`
  250. Recheck bool `mapstructure:"recheck"`
  251. RecheckEmpty bool `mapstructure:"recheck_empty"`
  252. Broadcast bool `mapstructure:"broadcast"`
  253. WalPath string `mapstructure:"wal_dir"`
  254. }
  255. // DefaultMempoolConfig returns a default configuration for the Tendermint mempool
  256. func DefaultMempoolConfig() *MempoolConfig {
  257. return &MempoolConfig{
  258. Recheck: true,
  259. RecheckEmpty: true,
  260. Broadcast: true,
  261. WalPath: filepath.Join(defaultDataDir, "mempool.wal"),
  262. }
  263. }
  264. // WalDir returns the full path to the mempool's write-ahead log
  265. func (m *MempoolConfig) WalDir() string {
  266. return rootify(m.WalPath, m.RootDir)
  267. }
  268. //-----------------------------------------------------------------------------
  269. // ConsensusConfig
  270. // ConsensusConfig defines the confuguration for the Tendermint consensus service,
  271. // including timeouts and details about the WAL and the block structure.
  272. type ConsensusConfig struct {
  273. RootDir string `mapstructure:"home"`
  274. WalPath string `mapstructure:"wal_file"`
  275. WalLight bool `mapstructure:"wal_light"`
  276. walFile string // overrides WalPath if set
  277. // All timeouts are in milliseconds
  278. TimeoutPropose int `mapstructure:"timeout_propose"`
  279. TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"`
  280. TimeoutPrevote int `mapstructure:"timeout_prevote"`
  281. TimeoutPrevoteDelta int `mapstructure:"timeout_prevote_delta"`
  282. TimeoutPrecommit int `mapstructure:"timeout_precommit"`
  283. TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"`
  284. TimeoutCommit int `mapstructure:"timeout_commit"`
  285. // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
  286. SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"`
  287. // BlockSize
  288. MaxBlockSizeTxs int `mapstructure:"max_block_size_txs"`
  289. MaxBlockSizeBytes int `mapstructure:"max_block_size_bytes"`
  290. // EmptyBlocks mode and possible interval between empty blocks in seconds
  291. CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"`
  292. CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"`
  293. // Reactor sleep duration parameters are in milliseconds
  294. PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"`
  295. PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"`
  296. }
  297. // WaitForTxs returns true if the consensus should wait for transactions before entering the propose step
  298. func (cfg *ConsensusConfig) WaitForTxs() bool {
  299. return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0
  300. }
  301. // EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available
  302. func (cfg *ConsensusConfig) EmptyBlocksInterval() time.Duration {
  303. return time.Duration(cfg.CreateEmptyBlocksInterval) * time.Second
  304. }
  305. // Propose returns the amount of time to wait for a proposal
  306. func (cfg *ConsensusConfig) Propose(round int) time.Duration {
  307. return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond
  308. }
  309. // Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes
  310. func (cfg *ConsensusConfig) Prevote(round int) time.Duration {
  311. return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond
  312. }
  313. // Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits
  314. func (cfg *ConsensusConfig) Precommit(round int) time.Duration {
  315. return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond
  316. }
  317. // Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit).
  318. func (cfg *ConsensusConfig) Commit(t time.Time) time.Time {
  319. return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond)
  320. }
  321. // PeerGossipSleep returns the amount of time to sleep if there is nothing to send from the ConsensusReactor
  322. func (cfg *ConsensusConfig) PeerGossipSleep() time.Duration {
  323. return time.Duration(cfg.PeerGossipSleepDuration) * time.Millisecond
  324. }
  325. // PeerQueryMaj23Sleep returns the amount of time to sleep after each VoteSetMaj23Message is sent in the ConsensusReactor
  326. func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration {
  327. return time.Duration(cfg.PeerQueryMaj23SleepDuration) * time.Millisecond
  328. }
  329. // DefaultConsensusConfig returns a default configuration for the consensus service
  330. func DefaultConsensusConfig() *ConsensusConfig {
  331. return &ConsensusConfig{
  332. WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"),
  333. WalLight: false,
  334. TimeoutPropose: 3000,
  335. TimeoutProposeDelta: 500,
  336. TimeoutPrevote: 1000,
  337. TimeoutPrevoteDelta: 500,
  338. TimeoutPrecommit: 1000,
  339. TimeoutPrecommitDelta: 500,
  340. TimeoutCommit: 1000,
  341. SkipTimeoutCommit: false,
  342. MaxBlockSizeTxs: 10000,
  343. MaxBlockSizeBytes: 1, // TODO
  344. CreateEmptyBlocks: true,
  345. CreateEmptyBlocksInterval: 0,
  346. PeerGossipSleepDuration: 100,
  347. PeerQueryMaj23SleepDuration: 2000,
  348. }
  349. }
  350. // TestConsensusConfig returns a configuration for testing the consensus service
  351. func TestConsensusConfig() *ConsensusConfig {
  352. config := DefaultConsensusConfig()
  353. config.TimeoutPropose = 100
  354. config.TimeoutProposeDelta = 1
  355. config.TimeoutPrevote = 10
  356. config.TimeoutPrevoteDelta = 1
  357. config.TimeoutPrecommit = 10
  358. config.TimeoutPrecommitDelta = 1
  359. config.TimeoutCommit = 10
  360. config.SkipTimeoutCommit = true
  361. return config
  362. }
  363. // WalFile returns the full path to the write-ahead log file
  364. func (c *ConsensusConfig) WalFile() string {
  365. if c.walFile != "" {
  366. return c.walFile
  367. }
  368. return rootify(c.WalPath, c.RootDir)
  369. }
  370. // SetWalFile sets the path to the write-ahead log file
  371. func (c *ConsensusConfig) SetWalFile(walFile string) {
  372. c.walFile = walFile
  373. }
  374. //-----------------------------------------------------------------------------
  375. // TxIndexConfig
  376. // TxIndexConfig defines the confuguration for the transaction
  377. // indexer, including tags to index.
  378. type TxIndexConfig struct {
  379. // What indexer to use for transactions
  380. //
  381. // Options:
  382. // 1) "null" (default)
  383. // 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
  384. Indexer string `mapstructure:"indexer"`
  385. // Comma-separated list of tags to index (by default the only tag is tx hash)
  386. //
  387. // It's recommended to index only a subset of tags due to possible memory
  388. // bloat. This is, of course, depends on the indexer's DB and the volume of
  389. // transactions.
  390. IndexTags string `mapstructure:"index_tags"`
  391. // When set to true, tells indexer to index all tags. Note this may be not
  392. // desirable (see the comment above). IndexTags has a precedence over
  393. // IndexAllTags (i.e. when given both, IndexTags will be indexed).
  394. IndexAllTags bool `mapstructure:"index_all_tags"`
  395. }
  396. // DefaultTxIndexConfig returns a default configuration for the transaction indexer.
  397. func DefaultTxIndexConfig() *TxIndexConfig {
  398. return &TxIndexConfig{
  399. Indexer: "kv",
  400. IndexTags: "",
  401. IndexAllTags: false,
  402. }
  403. }
  404. //-----------------------------------------------------------------------------
  405. // Utils
  406. // helper function to make config creation independent of root dir
  407. func rootify(path, root string) string {
  408. if filepath.IsAbs(path) {
  409. return path
  410. }
  411. return filepath.Join(root, path)
  412. }
  413. //-----------------------------------------------------------------------------
  414. // Moniker
  415. var defaultMoniker = getDefaultMoniker()
  416. // getDefaultMoniker returns a default moniker, which is the host name. If runtime
  417. // fails to get the host name, "anonymous" will be returned.
  418. func getDefaultMoniker() string {
  419. moniker, err := os.Hostname()
  420. if err != nil {
  421. moniker = "anonymous"
  422. }
  423. return moniker
  424. }