github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/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/tendermint/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/tendermint/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 ##### fast sync configuration options ##### 319 [fastsync] 320 321 # Fast Sync version to use: 322 # 1) "v0" (default) - the legacy fast sync implementation 323 # 2) "v1" - refactor of v0 version for better testability 324 # 3) "v2" - refactor of v1 version for better usability 325 version = "{{ .FastSync.Version }}" 326 327 ##### consensus configuration options ##### 328 [consensus] 329 330 wal_file = "{{ js .Consensus.WalPath }}" 331 332 timeout_propose = "{{ .Consensus.TimeoutPropose }}" 333 timeout_propose_delta = "{{ .Consensus.TimeoutProposeDelta }}" 334 timeout_prevote = "{{ .Consensus.TimeoutPrevote }}" 335 timeout_prevote_delta = "{{ .Consensus.TimeoutPrevoteDelta }}" 336 timeout_precommit = "{{ .Consensus.TimeoutPrecommit }}" 337 timeout_precommit_delta = "{{ .Consensus.TimeoutPrecommitDelta }}" 338 timeout_commit = "{{ .Consensus.TimeoutCommit }}" 339 340 # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) 341 skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }} 342 343 # EmptyBlocks mode and possible interval between empty blocks 344 create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }} 345 create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}" 346 347 # Reactor sleep duration parameters 348 peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}" 349 peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}" 350 351 ##### transactions indexer configuration options ##### 352 [tx_index] 353 354 # What indexer to use for transactions 355 # 356 # Options: 357 # 1) "null" 358 # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). 359 indexer = "{{ .TxIndex.Indexer }}" 360 361 # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") 362 # Remember that Event has the following structure: type.key 363 # type: [ 364 # key: value, 365 # ... 366 # ] 367 # 368 # You can also index transactions by height by adding "tx.height" key here. 369 # 370 # It's recommended to index only a subset of keys due to possible memory 371 # bloat. This is, of course, depends on the indexer's DB and the volume of 372 # transactions. 373 index_keys = "{{ .TxIndex.IndexKeys }}" 374 375 # When set to true, tells indexer to index all compositeKeys (predefined keys: 376 # "tx.hash", "tx.height" and all keys from DeliverTx responses). 377 # 378 # Note this may be not desirable (see the comment above). IndexKeys has a 379 # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be 380 # indexed). 381 index_all_keys = {{ .TxIndex.IndexAllKeys }} 382 383 ##### instrumentation configuration options ##### 384 [instrumentation] 385 386 # When true, Prometheus metrics are served under /metrics on 387 # PrometheusListenAddr. 388 # Check out the documentation for the list of available metrics. 389 prometheus = {{ .Instrumentation.Prometheus }} 390 391 # Address to listen for Prometheus collector(s) connections 392 prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}" 393 394 # Maximum number of simultaneous connections. 395 # If you want to accept a larger number than the default, make sure 396 # you increase your OS limits. 397 # 0 - unlimited. 398 max_open_connections = {{ .Instrumentation.MaxOpenConnections }} 399 400 # Instrumentation namespace 401 namespace = "{{ .Instrumentation.Namespace }}" 402 ` 403 404 /****** these are for test settings ***********/ 405 406 func ResetTestRoot(testName string) *Config { 407 return ResetTestRootWithChainID(testName, "") 408 } 409 410 func ResetTestRootWithChainID(testName string, chainID string) *Config { 411 // create a unique, concurrency-safe test directory under os.TempDir() 412 rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName)) 413 if err != nil { 414 panic(err) 415 } 416 // ensure config and data subdirs are created 417 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { 418 panic(err) 419 } 420 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { 421 panic(err) 422 } 423 424 baseConfig := DefaultBaseConfig() 425 configFilePath := filepath.Join(rootDir, defaultConfigFilePath) 426 genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) 427 privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey) 428 privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState) 429 430 // Write default config file if missing. 431 if !tmos.FileExists(configFilePath) { 432 writeDefaultConfigFile(configFilePath) 433 } 434 if !tmos.FileExists(genesisFilePath) { 435 if chainID == "" { 436 chainID = "tendermint_test" 437 } 438 testGenesis := fmt.Sprintf(testGenesisFmt, chainID) 439 tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) 440 } 441 // we always overwrite the priv val 442 tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644) 443 tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644) 444 445 config := TestConfig().SetRoot(rootDir) 446 return config 447 } 448 449 var testGenesisFmt = `{ 450 "genesis_time": "2018-10-10T08:20:13.695936996Z", 451 "chain_id": "%s", 452 "validators": [ 453 { 454 "pub_key": { 455 "type": "tendermint/PubKeyEd25519", 456 "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" 457 }, 458 "power": "10", 459 "name": "" 460 } 461 ], 462 "app_hash": "" 463 }` 464 465 var testPrivValidatorKey = `{ 466 "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145", 467 "pub_key": { 468 "type": "tendermint/PubKeyEd25519", 469 "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" 470 }, 471 "priv_key": { 472 "type": "tendermint/PrivKeyEd25519", 473 "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ==" 474 } 475 }` 476 477 var testPrivValidatorState = `{ 478 "height": "0", 479 "round": "0", 480 "step": 0 481 }`