github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/config/toml.go (about) 1 package config 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "path/filepath" 8 "text/template" 9 10 tmos "github.com/franono/tendermint/libs/os" 11 ) 12 13 // DefaultDirPerm is the default permissions used when creating directories. 14 const DefaultDirPerm = 0700 15 16 var configTemplate *template.Template 17 18 func init() { 19 var err error 20 if configTemplate, err = template.New("configFileTemplate").Parse(defaultConfigTemplate); err != nil { 21 panic(err) 22 } 23 } 24 25 /****** these are for production settings ***********/ 26 27 // EnsureRoot creates the root, config, and data directories if they don't exist, 28 // and panics if it fails. 29 func EnsureRoot(rootDir string) { 30 if err := tmos.EnsureDir(rootDir, DefaultDirPerm); err != nil { 31 panic(err.Error()) 32 } 33 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { 34 panic(err.Error()) 35 } 36 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { 37 panic(err.Error()) 38 } 39 40 configFilePath := filepath.Join(rootDir, defaultConfigFilePath) 41 42 // Write default config file if missing. 43 if !tmos.FileExists(configFilePath) { 44 writeDefaultConfigFile(configFilePath) 45 } 46 } 47 48 // XXX: this func should probably be called by cmd/tendermint/commands/init.go 49 // alongside the writing of the genesis.json and priv_validator.json 50 func writeDefaultConfigFile(configFilePath string) { 51 WriteConfigFile(configFilePath, DefaultConfig()) 52 } 53 54 // WriteConfigFile renders config using the template and writes it to configFilePath. 55 func WriteConfigFile(configFilePath string, config *Config) { 56 var buffer bytes.Buffer 57 58 if err := configTemplate.Execute(&buffer, config); err != nil { 59 panic(err) 60 } 61 62 tmos.MustWriteFile(configFilePath, buffer.Bytes(), 0644) 63 } 64 65 // Note: any changes to the comments/variables/mapstructure 66 // must be reflected in the appropriate struct in config/config.go 67 const defaultConfigTemplate = `# This is a TOML config file. 68 # For more information, see https://github.com/toml-lang/toml 69 70 # NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or 71 # relative to the home directory (e.g. "data"). The home directory is 72 # "$HOME/.tendermint" by default, but could be changed via $TMHOME env variable 73 # or --home cmd flag. 74 75 ##### main base config options ##### 76 77 # TCP or UNIX socket address of the ABCI application, 78 # or the name of an ABCI application compiled in with the Tendermint binary 79 proxy_app = "{{ .BaseConfig.ProxyApp }}" 80 81 # A custom human readable name for this node 82 moniker = "{{ .BaseConfig.Moniker }}" 83 84 # If this node is many blocks behind the tip of the chain, FastSync 85 # allows them to catchup quickly by downloading blocks in parallel 86 # and verifying their commits 87 fast_sync = {{ .BaseConfig.FastSyncMode }} 88 89 # Database backend: goleveldb | cleveldb | boltdb | rocksdb 90 # * goleveldb (github.com/syndtr/goleveldb - most popular implementation) 91 # - pure go 92 # - stable 93 # * cleveldb (uses levigo wrapper) 94 # - fast 95 # - requires gcc 96 # - use cleveldb build tag (go build -tags cleveldb) 97 # * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt) 98 # - EXPERIMENTAL 99 # - may be faster is some use-cases (random reads - indexer) 100 # - use boltdb build tag (go build -tags boltdb) 101 # * rocksdb (uses github.com/tecbot/gorocksdb) 102 # - EXPERIMENTAL 103 # - requires gcc 104 # - use rocksdb build tag (go build -tags rocksdb) 105 db_backend = "{{ .BaseConfig.DBBackend }}" 106 107 # Database directory 108 db_dir = "{{ js .BaseConfig.DBPath }}" 109 110 # Output level for logging, including package level options 111 log_level = "{{ .BaseConfig.LogLevel }}" 112 113 # Output format: 'plain' (colored text) or 'json' 114 log_format = "{{ .BaseConfig.LogFormat }}" 115 116 ##### additional base config options ##### 117 118 # Path to the JSON file containing the initial validator set and other meta data 119 genesis_file = "{{ js .BaseConfig.Genesis }}" 120 121 # Path to the JSON file containing the private key to use as a validator in the consensus protocol 122 priv_validator_key_file = "{{ js .BaseConfig.PrivValidatorKey }}" 123 124 # Path to the JSON file containing the last sign state of a validator 125 priv_validator_state_file = "{{ js .BaseConfig.PrivValidatorState }}" 126 127 # TCP or UNIX socket address for Tendermint to listen on for 128 # connections from an external PrivValidator process 129 priv_validator_laddr = "{{ .BaseConfig.PrivValidatorListenAddr }}" 130 131 # Path to the JSON file containing the private key to use for node authentication in the p2p protocol 132 node_key_file = "{{ js .BaseConfig.NodeKey }}" 133 134 # Mechanism to connect to the ABCI application: socket | grpc 135 abci = "{{ .BaseConfig.ABCI }}" 136 137 # TCP or UNIX socket address for the profiling server to listen on 138 prof_laddr = "{{ .BaseConfig.ProfListenAddress }}" 139 140 # If true, query the ABCI app on connecting to a new peer 141 # so the app can decide if we should keep the connection or not 142 filter_peers = {{ .BaseConfig.FilterPeers }} 143 144 ##### advanced configuration options ##### 145 146 ##### rpc server configuration options ##### 147 [rpc] 148 149 # TCP or UNIX socket address for the RPC server to listen on 150 laddr = "{{ .RPC.ListenAddress }}" 151 152 # A list of origins a cross-domain request can be executed from 153 # Default value '[]' disables cors support 154 # Use '["*"]' to allow any origin 155 cors_allowed_origins = [{{ range .RPC.CORSAllowedOrigins }}{{ printf "%q, " . }}{{end}}] 156 157 # A list of methods the client is allowed to use with cross-domain requests 158 cors_allowed_methods = [{{ range .RPC.CORSAllowedMethods }}{{ printf "%q, " . }}{{end}}] 159 160 # A list of non simple headers the client is allowed to use with cross-domain requests 161 cors_allowed_headers = [{{ range .RPC.CORSAllowedHeaders }}{{ printf "%q, " . }}{{end}}] 162 163 # TCP or UNIX socket address for the gRPC server to listen on 164 # NOTE: This server only supports /broadcast_tx_commit 165 grpc_laddr = "{{ .RPC.GRPCListenAddress }}" 166 167 # Maximum number of simultaneous connections. 168 # Does not include RPC (HTTP&WebSocket) connections. See max_open_connections 169 # If you want to accept a larger number than the default, make sure 170 # you increase your OS limits. 171 # 0 - unlimited. 172 # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} 173 # 1024 - 40 - 10 - 50 = 924 = ~900 174 grpc_max_open_connections = {{ .RPC.GRPCMaxOpenConnections }} 175 176 # Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool 177 unsafe = {{ .RPC.Unsafe }} 178 179 # Maximum number of simultaneous connections (including WebSocket). 180 # Does not include gRPC connections. See grpc_max_open_connections 181 # If you want to accept a larger number than the default, make sure 182 # you increase your OS limits. 183 # 0 - unlimited. 184 # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} 185 # 1024 - 40 - 10 - 50 = 924 = ~900 186 max_open_connections = {{ .RPC.MaxOpenConnections }} 187 188 # Maximum number of unique clientIDs that can /subscribe 189 # If you're using /broadcast_tx_commit, set to the estimated maximum number 190 # of broadcast_tx_commit calls per block. 191 max_subscription_clients = {{ .RPC.MaxSubscriptionClients }} 192 193 # Maximum number of unique queries a given client can /subscribe to 194 # If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to 195 # the estimated # maximum number of broadcast_tx_commit calls per block. 196 max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }} 197 198 # How long to wait for a tx to be committed during /broadcast_tx_commit. 199 # WARNING: Using a value larger than 10s will result in increasing the 200 # global HTTP write timeout, which applies to all connections and endpoints. 201 # See https://github.com/franono/tendermint/issues/3435 202 timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}" 203 204 # Maximum size of request body, in bytes 205 max_body_bytes = {{ .RPC.MaxBodyBytes }} 206 207 # Maximum size of request header, in bytes 208 max_header_bytes = {{ .RPC.MaxHeaderBytes }} 209 210 # The path to a file containing certificate that is used to create the HTTPS server. 211 # Migth be either absolute path or path related to tendermint's config directory. 212 # If the certificate is signed by a certificate authority, 213 # the certFile should be the concatenation of the server's certificate, any intermediates, 214 # and the CA's certificate. 215 # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. 216 # Otherwise, HTTP server is run. 217 tls_cert_file = "{{ .RPC.TLSCertFile }}" 218 219 # The path to a file containing matching private key that is used to create the HTTPS server. 220 # Migth be either absolute path or path related to tendermint's config directory. 221 # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. 222 # Otherwise, HTTP server is run. 223 tls_key_file = "{{ .RPC.TLSKeyFile }}" 224 225 ##### peer to peer configuration options ##### 226 [p2p] 227 228 # Address to listen for incoming connections 229 laddr = "{{ .P2P.ListenAddress }}" 230 231 # Address to advertise to peers for them to dial 232 # If empty, will use the same port as the laddr, 233 # and will introspect on the listener or use UPnP 234 # to figure out the address. 235 external_address = "{{ .P2P.ExternalAddress }}" 236 237 # Comma separated list of seed nodes to connect to 238 seeds = "{{ .P2P.Seeds }}" 239 240 # Comma separated list of nodes to keep persistent connections to 241 persistent_peers = "{{ .P2P.PersistentPeers }}" 242 243 # UPNP port forwarding 244 upnp = {{ .P2P.UPNP }} 245 246 # Path to address book 247 addr_book_file = "{{ js .P2P.AddrBook }}" 248 249 # Set true for strict address routability rules 250 # Set false for private or local networks 251 addr_book_strict = {{ .P2P.AddrBookStrict }} 252 253 # Maximum number of inbound peers 254 max_num_inbound_peers = {{ .P2P.MaxNumInboundPeers }} 255 256 # Maximum number of outbound peers to connect to, excluding persistent peers 257 max_num_outbound_peers = {{ .P2P.MaxNumOutboundPeers }} 258 259 # List of node IDs, to which a connection will be (re)established ignoring any existing limits 260 unconditional_peer_ids = "{{ .P2P.UnconditionalPeerIDs }}" 261 262 # Maximum pause when redialing a persistent peer (if zero, exponential backoff is used) 263 persistent_peers_max_dial_period = "{{ .P2P.PersistentPeersMaxDialPeriod }}" 264 265 # Time to wait before flushing messages out on the connection 266 flush_throttle_timeout = "{{ .P2P.FlushThrottleTimeout }}" 267 268 # Maximum size of a message packet payload, in bytes 269 max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }} 270 271 # Rate at which packets can be sent, in bytes/second 272 send_rate = {{ .P2P.SendRate }} 273 274 # Rate at which packets can be received, in bytes/second 275 recv_rate = {{ .P2P.RecvRate }} 276 277 # Set true to enable the peer-exchange reactor 278 pex = {{ .P2P.PexReactor }} 279 280 # Seed mode, in which node constantly crawls the network and looks for 281 # peers. If another node asks it for addresses, it responds and disconnects. 282 # 283 # Does not work if the peer-exchange reactor is disabled. 284 seed_mode = {{ .P2P.SeedMode }} 285 286 # Comma separated list of peer IDs to keep private (will not be gossiped to other peers) 287 private_peer_ids = "{{ .P2P.PrivatePeerIDs }}" 288 289 # Toggle to disable guard against peers connecting from the same ip. 290 allow_duplicate_ip = {{ .P2P.AllowDuplicateIP }} 291 292 # Peer connection configuration. 293 handshake_timeout = "{{ .P2P.HandshakeTimeout }}" 294 dial_timeout = "{{ .P2P.DialTimeout }}" 295 296 ##### mempool configuration options ##### 297 [mempool] 298 299 recheck = {{ .Mempool.Recheck }} 300 broadcast = {{ .Mempool.Broadcast }} 301 wal_dir = "{{ js .Mempool.WalPath }}" 302 303 # Maximum number of transactions in the mempool 304 size = {{ .Mempool.Size }} 305 306 # Limit the total size of all txs in the mempool. 307 # This only accounts for raw transactions (e.g. given 1MB transactions and 308 # max_txs_bytes=5MB, mempool will only accept 5 transactions). 309 max_txs_bytes = {{ .Mempool.MaxTxsBytes }} 310 311 # Size of the cache (used to filter transactions we saw earlier) in transactions 312 cache_size = {{ .Mempool.CacheSize }} 313 314 # Maximum size of a single transaction. 315 # NOTE: the max size of a tx transmitted over the network is {max_tx_bytes} + {amino overhead}. 316 max_tx_bytes = {{ .Mempool.MaxTxBytes }} 317 318 ##### state sync configuration options ##### 319 [statesync] 320 # State sync rapidly bootstraps a new node by discovering, fetching, and restoring a state machine 321 # snapshot from peers instead of fetching and replaying historical blocks. Requires some peers in 322 # the network to take and serve state machine snapshots. State sync is not attempted if the node 323 # has any local state (LastBlockHeight > 0). The node will have a truncated block history, 324 # starting from the height of the snapshot. 325 enable = {{ .StateSync.Enable }} 326 327 # RPC servers (comma-separated) for light client verification of the synced state machine and 328 # retrieval of state data for node bootstrapping. Also needs a trusted height and corresponding 329 # header hash obtained from a trusted source, and a period during which validators can be trusted. 330 # 331 # For Cosmos SDK-based chains, trust_period should usually be about 2/3 of the unbonding time (~2 332 # weeks) during which they can be financially punished (slashed) for misbehavior. 333 rpc_servers = "" 334 trust_height = {{ .StateSync.TrustHeight }} 335 trust_hash = "{{ .StateSync.TrustHash }}" 336 trust_period = "{{ .StateSync.TrustPeriod }}" 337 338 # Temporary directory for state sync snapshot chunks, defaults to the OS tempdir (typically /tmp). 339 # Will create a new, randomly named directory within, and remove it when done. 340 temp_dir = "{{ .StateSync.TempDir }}" 341 342 ##### fast sync configuration options ##### 343 [fastsync] 344 345 # Fast Sync version to use: 346 # 1) "v0" (default) - the legacy fast sync implementation 347 # 2) "v1" - refactor of v0 version for better testability 348 # 3) "v2" - refactor of v1 version for better usability 349 version = "{{ .FastSync.Version }}" 350 351 ##### consensus configuration options ##### 352 [consensus] 353 354 wal_file = "{{ js .Consensus.WalPath }}" 355 356 timeout_propose = "{{ .Consensus.TimeoutPropose }}" 357 timeout_propose_delta = "{{ .Consensus.TimeoutProposeDelta }}" 358 timeout_prevote = "{{ .Consensus.TimeoutPrevote }}" 359 timeout_prevote_delta = "{{ .Consensus.TimeoutPrevoteDelta }}" 360 timeout_precommit = "{{ .Consensus.TimeoutPrecommit }}" 361 timeout_precommit_delta = "{{ .Consensus.TimeoutPrecommitDelta }}" 362 timeout_commit = "{{ .Consensus.TimeoutCommit }}" 363 364 # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) 365 skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }} 366 367 # EmptyBlocks mode and possible interval between empty blocks 368 create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }} 369 create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}" 370 371 # Reactor sleep duration parameters 372 peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}" 373 peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}" 374 375 ##### transactions indexer configuration options ##### 376 [tx_index] 377 378 # What indexer to use for transactions 379 # 380 # Options: 381 # 1) "null" 382 # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). 383 indexer = "{{ .TxIndex.Indexer }}" 384 385 # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") 386 # Remember that Event has the following structure: type.key 387 # type: [ 388 # key: value, 389 # ... 390 # ] 391 # 392 # You can also index transactions by height by adding "tx.height" key here. 393 # 394 # It's recommended to index only a subset of keys due to possible memory 395 # bloat. This is, of course, depends on the indexer's DB and the volume of 396 # transactions. 397 index_keys = "{{ .TxIndex.IndexKeys }}" 398 399 # When set to true, tells indexer to index all compositeKeys (predefined keys: 400 # "tx.hash", "tx.height" and all keys from DeliverTx responses). 401 # 402 # Note this may be not desirable (see the comment above). IndexKeys has a 403 # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be 404 # indexed). 405 index_all_keys = {{ .TxIndex.IndexAllKeys }} 406 407 ##### instrumentation configuration options ##### 408 [instrumentation] 409 410 # When true, Prometheus metrics are served under /metrics on 411 # PrometheusListenAddr. 412 # Check out the documentation for the list of available metrics. 413 prometheus = {{ .Instrumentation.Prometheus }} 414 415 # Address to listen for Prometheus collector(s) connections 416 prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}" 417 418 # Maximum number of simultaneous connections. 419 # If you want to accept a larger number than the default, make sure 420 # you increase your OS limits. 421 # 0 - unlimited. 422 max_open_connections = {{ .Instrumentation.MaxOpenConnections }} 423 424 # Instrumentation namespace 425 namespace = "{{ .Instrumentation.Namespace }}" 426 ` 427 428 /****** these are for test settings ***********/ 429 430 func ResetTestRoot(testName string) *Config { 431 return ResetTestRootWithChainID(testName, "") 432 } 433 434 func ResetTestRootWithChainID(testName string, chainID string) *Config { 435 // create a unique, concurrency-safe test directory under os.TempDir() 436 rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName)) 437 if err != nil { 438 panic(err) 439 } 440 // ensure config and data subdirs are created 441 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { 442 panic(err) 443 } 444 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { 445 panic(err) 446 } 447 448 baseConfig := DefaultBaseConfig() 449 configFilePath := filepath.Join(rootDir, defaultConfigFilePath) 450 genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) 451 privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey) 452 privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState) 453 454 // Write default config file if missing. 455 if !tmos.FileExists(configFilePath) { 456 writeDefaultConfigFile(configFilePath) 457 } 458 if !tmos.FileExists(genesisFilePath) { 459 if chainID == "" { 460 chainID = "tendermint_test" 461 } 462 testGenesis := fmt.Sprintf(testGenesisFmt, chainID) 463 tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) 464 } 465 // we always overwrite the priv val 466 tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644) 467 tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644) 468 469 config := TestConfig().SetRoot(rootDir) 470 return config 471 } 472 473 var testGenesisFmt = `{ 474 "genesis_time": "2018-10-10T08:20:13.695936996Z", 475 "chain_id": "%s", 476 "validators": [ 477 { 478 "pub_key": { 479 "type": "tendermint/PubKeyEd25519", 480 "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" 481 }, 482 "power": "10", 483 "name": "" 484 } 485 ], 486 "app_hash": "" 487 }` 488 489 var testPrivValidatorKey = `{ 490 "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145", 491 "pub_key": { 492 "type": "tendermint/PubKeyEd25519", 493 "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" 494 }, 495 "priv_key": { 496 "type": "tendermint/PrivKeyEd25519", 497 "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ==" 498 } 499 }` 500 501 var testPrivValidatorState = `{ 502 "height": "0", 503 "round": "0", 504 "step": 0 505 }`