github.com/okex/exchain@v1.8.0/libs/tendermint/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/okex/exchain/libs/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 # AutoFastSync allows this node switches from consensus mode to fast-sync mode automatically 90 # when it is many blocks behind the tip of the chain. 91 auto_fast_sync = {{ .BaseConfig.AutoFastSync }} 92 93 # Database backend: goleveldb | cleveldb | boltdb | rocksdb 94 # * goleveldb (github.com/syndtr/goleveldb - most popular implementation) 95 # - pure go 96 # - stable 97 # * cleveldb (uses levigo wrapper) 98 # - fast 99 # - requires gcc 100 # - use cleveldb build tag (go build -tags cleveldb) 101 # * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt) 102 # - EXPERIMENTAL 103 # - may be faster is some use-cases (random reads - indexer) 104 # - use boltdb build tag (go build -tags boltdb) 105 # * rocksdb (uses github.com/tecbot/gorocksdb) 106 # - EXPERIMENTAL 107 # - requires gcc 108 # - use rocksdb build tag (go build -tags rocksdb) 109 db_backend = "{{ .BaseConfig.DBBackend }}" 110 111 # Database directory 112 db_dir = "{{ js .BaseConfig.DBPath }}" 113 114 # Output level for logging, including package level options 115 log_level = "{{ .BaseConfig.LogLevel }}" 116 117 # Output format: 'plain' (colored text) or 'json' 118 log_format = "{{ .BaseConfig.LogFormat }}" 119 120 ##### additional base config options ##### 121 122 # Path to the JSON file containing the initial validator set and other meta data 123 genesis_file = "{{ js .BaseConfig.Genesis }}" 124 125 # Path to the JSON file containing the private key to use as a validator in the consensus protocol 126 priv_validator_key_file = "{{ js .BaseConfig.PrivValidatorKey }}" 127 128 # Path to the JSON file containing the last sign state of a validator 129 priv_validator_state_file = "{{ js .BaseConfig.PrivValidatorState }}" 130 131 # TCP or UNIX socket address for Tendermint to listen on for 132 # connections from an external PrivValidator process 133 priv_validator_laddr = "{{ .BaseConfig.PrivValidatorListenAddr }}" 134 135 # Path to the JSON file containing the private key to use for node authentication in the p2p protocol 136 node_key_file = "{{ js .BaseConfig.NodeKey }}" 137 138 # Mechanism to connect to the ABCI application: socket | grpc 139 abci = "{{ .BaseConfig.ABCI }}" 140 141 # TCP or UNIX socket address for the profiling server to listen on 142 prof_laddr = "{{ .BaseConfig.ProfListenAddress }}" 143 144 # If true, query the ABCI app on connecting to a new peer 145 # so the app can decide if we should keep the connection or not 146 filter_peers = {{ .BaseConfig.FilterPeers }} 147 148 ##### advanced configuration options ##### 149 150 ##### rpc server configuration options ##### 151 [rpc] 152 153 # TCP or UNIX socket address for the RPC server to listen on 154 laddr = "{{ .RPC.ListenAddress }}" 155 156 # A list of origins a cross-domain request can be executed from 157 # Default value '[]' disables cors support 158 # Use '["*"]' to allow any origin 159 cors_allowed_origins = [{{ range .RPC.CORSAllowedOrigins }}{{ printf "%q, " . }}{{end}}] 160 161 # A list of methods the client is allowed to use with cross-domain requests 162 cors_allowed_methods = [{{ range .RPC.CORSAllowedMethods }}{{ printf "%q, " . }}{{end}}] 163 164 # A list of non simple headers the client is allowed to use with cross-domain requests 165 cors_allowed_headers = [{{ range .RPC.CORSAllowedHeaders }}{{ printf "%q, " . }}{{end}}] 166 167 # TCP or UNIX socket address for the gRPC server to listen on 168 # NOTE: This server only supports /broadcast_tx_commit 169 grpc_laddr = "{{ .RPC.GRPCListenAddress }}" 170 171 # Maximum number of simultaneous connections. 172 # Does not include RPC (HTTP&WebSocket) connections. See max_open_connections 173 # If you want to accept a larger number than the default, make sure 174 # you increase your OS limits. 175 # 0 - unlimited. 176 # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} 177 # 1024 - 40 - 10 - 50 = 924 = ~900 178 grpc_max_open_connections = {{ .RPC.GRPCMaxOpenConnections }} 179 180 # Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool 181 unsafe = {{ .RPC.Unsafe }} 182 183 # Maximum number of simultaneous connections (including WebSocket). 184 # Does not include gRPC connections. See grpc_max_open_connections 185 # If you want to accept a larger number than the default, make sure 186 # you increase your OS limits. 187 # 0 - unlimited. 188 # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} 189 # 1024 - 40 - 10 - 50 = 924 = ~900 190 max_open_connections = {{ .RPC.MaxOpenConnections }} 191 192 # Maximum number of unique clientIDs that can /subscribe 193 # If you're using /broadcast_tx_commit, set to the estimated maximum number 194 # of broadcast_tx_commit calls per block. 195 max_subscription_clients = {{ .RPC.MaxSubscriptionClients }} 196 197 # Maximum number of unique queries a given client can /subscribe to 198 # If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to 199 # the estimated # maximum number of broadcast_tx_commit calls per block. 200 max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }} 201 202 # How long to wait for a tx to be committed during /broadcast_tx_commit. 203 # WARNING: Using a value larger than 10s will result in increasing the 204 # global HTTP write timeout, which applies to all connections and endpoints. 205 # See https://github.com/tendermint/tendermint/issues/3435 206 timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}" 207 208 # Maximum size of request body, in bytes 209 max_body_bytes = {{ .RPC.MaxBodyBytes }} 210 211 # Maximum size of request header, in bytes 212 max_header_bytes = {{ .RPC.MaxHeaderBytes }} 213 214 # The path to a file containing certificate that is used to create the HTTPS server. 215 # Migth be either absolute path or path related to tendermint's config directory. 216 # If the certificate is signed by a certificate authority, 217 # the certFile should be the concatenation of the server's certificate, any intermediates, 218 # and the CA's certificate. 219 # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. 220 # Otherwise, HTTP server is run. 221 tls_cert_file = "{{ .RPC.TLSCertFile }}" 222 223 # The path to a file containing matching private key that is used to create the HTTPS server. 224 # Migth be either absolute path or path related to tendermint's config directory. 225 # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. 226 # Otherwise, HTTP server is run. 227 tls_key_file = "{{ .RPC.TLSKeyFile }}" 228 229 ##### peer to peer configuration options ##### 230 [p2p] 231 232 # Address to listen for incoming connections 233 laddr = "{{ .P2P.ListenAddress }}" 234 235 # Address to advertise to peers for them to dial 236 # If empty, will use the same port as the laddr, 237 # and will introspect on the listener or use UPnP 238 # to figure out the address. 239 external_address = "{{ .P2P.ExternalAddress }}" 240 241 # Comma separated list of seed nodes to connect to 242 seeds = "{{ .P2P.Seeds }}" 243 244 # Comma separated list of nodes to keep persistent connections to 245 persistent_peers = "{{ .P2P.PersistentPeers }}" 246 247 # UPNP port forwarding 248 upnp = {{ .P2P.UPNP }} 249 250 # Path to address book 251 addr_book_file = "{{ js .P2P.AddrBook }}" 252 253 # Set true for strict address routability rules 254 # Set false for private or local networks 255 addr_book_strict = {{ .P2P.AddrBookStrict }} 256 257 # Maximum number of inbound peers 258 max_num_inbound_peers = {{ .P2P.MaxNumInboundPeers }} 259 260 # Maximum number of outbound peers to connect to, excluding persistent peers 261 max_num_outbound_peers = {{ .P2P.MaxNumOutboundPeers }} 262 263 # List of node IDs, to which a connection will be (re)established ignoring any existing limits 264 unconditional_peer_ids = "{{ .P2P.UnconditionalPeerIDs }}" 265 266 # Maximum pause when redialing a persistent peer (if zero, exponential backoff is used) 267 persistent_peers_max_dial_period = "{{ .P2P.PersistentPeersMaxDialPeriod }}" 268 269 # Time to wait before flushing messages out on the connection 270 flush_throttle_timeout = "{{ .P2P.FlushThrottleTimeout }}" 271 272 # Maximum size of a message packet payload, in bytes 273 max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }} 274 275 # Rate at which packets can be sent, in bytes/second 276 send_rate = {{ .P2P.SendRate }} 277 278 # Rate at which packets can be received, in bytes/second 279 recv_rate = {{ .P2P.RecvRate }} 280 281 # Set true to enable the peer-exchange reactor 282 pex = {{ .P2P.PexReactor }} 283 284 # Seed mode, in which node constantly crawls the network and looks for 285 # peers. If another node asks it for addresses, it responds and disconnects. 286 # 287 # Does not work if the peer-exchange reactor is disabled. 288 seed_mode = {{ .P2P.SeedMode }} 289 290 # Comma separated list of peer IDs to keep private (will not be gossiped to other peers) 291 private_peer_ids = "{{ .P2P.PrivatePeerIDs }}" 292 293 # Toggle to disable guard against peers connecting from the same ip. 294 allow_duplicate_ip = {{ .P2P.AllowDuplicateIP }} 295 296 # Peer connection configuration. 297 handshake_timeout = "{{ .P2P.HandshakeTimeout }}" 298 dial_timeout = "{{ .P2P.DialTimeout }}" 299 300 ##### mempool configuration options ##### 301 [mempool] 302 303 recheck = {{ .Mempool.Recheck }} 304 force_recheck_gap = {{ .Mempool.ForceRecheckGap }} 305 broadcast = {{ .Mempool.Broadcast }} 306 307 # Maximum number of transactions in the mempool 308 size = {{ .Mempool.Size }} 309 310 # Limit the total size of all txs in the mempool. 311 # This only accounts for raw transactions (e.g. given 1MB transactions and 312 # max_txs_bytes=5MB, mempool will only accept 5 transactions). 313 max_txs_bytes = {{ .Mempool.MaxTxsBytes }} 314 315 # Size of the cache (used to filter transactions we saw earlier) in transactions 316 cache_size = {{ .Mempool.CacheSize }} 317 318 # Maximum size of a single transaction. 319 # NOTE: the max size of a tx transmitted over the network is {max_tx_bytes} + {amino overhead}. 320 max_tx_bytes = {{ .Mempool.MaxTxBytes }} 321 322 # Limit the max number of txs in the a block. 323 max_tx_num_per_block = {{ .Mempool.MaxTxNumPerBlock }} 324 325 # Enable sort txs in mempool by gas price. 326 sort_tx_by_gp = {{ .Mempool.SortTxByGp }} 327 328 # Minimum price bump percentage to replace an already existing transaction (nonce) 329 tx_price_bump = {{ .Mempool.TxPriceBump }} 330 331 # Node key whitelist used in mempool to reduce CPU and Memory tradeoff 332 node_key_whitelist = [{{ range .Mempool.NodeKeyWhitelist }}{{ printf "%q, " . }}{{end}}] 333 334 ##### fast sync configuration options ##### 335 [fastsync] 336 337 # Fast Sync version to use: 338 # 1) "v0" (default) - the legacy fast sync implementation 339 # 2) "v1" - refactor of v0 version for better testability 340 # 3) "v2" - refactor of v1 version for better usability 341 version = "{{ .FastSync.Version }}" 342 343 ##### consensus configuration options ##### 344 [consensus] 345 346 wal_file = "{{ js .Consensus.WalPath }}" 347 348 timeout_propose = "{{ .Consensus.TimeoutPropose }}" 349 timeout_propose_delta = "{{ .Consensus.TimeoutProposeDelta }}" 350 timeout_prevote = "{{ .Consensus.TimeoutPrevote }}" 351 timeout_prevote_delta = "{{ .Consensus.TimeoutPrevoteDelta }}" 352 timeout_precommit = "{{ .Consensus.TimeoutPrecommit }}" 353 timeout_precommit_delta = "{{ .Consensus.TimeoutPrecommitDelta }}" 354 timeout_commit = "{{ .Consensus.TimeoutCommit }}" 355 waiting = "{{ .Consensus.Waiting }}" 356 357 # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) 358 skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }} 359 360 # EmptyBlocks mode and possible interval between empty blocks 361 create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }} 362 create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}" 363 364 # Reactor sleep duration parameters 365 peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}" 366 peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}" 367 368 ##### transactions indexer configuration options ##### 369 [tx_index] 370 371 # What indexer to use for transactions 372 # 373 # Options: 374 # 1) "null" 375 # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). 376 indexer = "{{ .TxIndex.Indexer }}" 377 378 # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") 379 # Remember that Event has the following structure: type.key 380 # type: [ 381 # key: value, 382 # ... 383 # ] 384 # 385 # You can also index transactions by height by adding "tx.height" key here. 386 # 387 # It's recommended to index only a subset of keys due to possible memory 388 # bloat. This is, of course, depends on the indexer's DB and the volume of 389 # transactions. 390 index_keys = "{{ .TxIndex.IndexKeys }}" 391 392 # When set to true, tells indexer to index all compositeKeys (predefined keys: 393 # "tx.hash", "tx.height" and all keys from DeliverTx responses). 394 # 395 # Note this may be not desirable (see the comment above). IndexKeys has a 396 # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be 397 # indexed). 398 index_all_keys = {{ .TxIndex.IndexAllKeys }} 399 400 ##### instrumentation configuration options ##### 401 [instrumentation] 402 403 # When true, Prometheus metrics are served under /metrics on 404 # PrometheusListenAddr. 405 # Check out the documentation for the list of available metrics. 406 prometheus = {{ .Instrumentation.Prometheus }} 407 408 # Address to listen for Prometheus collector(s) connections 409 prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}" 410 411 # Maximum number of simultaneous connections. 412 # If you want to accept a larger number than the default, make sure 413 # you increase your OS limits. 414 # 0 - unlimited. 415 max_open_connections = {{ .Instrumentation.MaxOpenConnections }} 416 417 # Instrumentation namespace 418 namespace = "{{ .Instrumentation.Namespace }}" 419 420 # Log file 421 log_file = "{{ js .BaseConfig.LogFile }}" 422 423 # Log stdout 424 log_stdout = "{{ .BaseConfig.LogStdout }}" 425 ` 426 427 /****** these are for test settings ***********/ 428 429 func ResetTestRoot(testName string) *Config { 430 return ResetTestRootWithChainID(testName, "") 431 } 432 433 func ResetTestRootWithChainID(testName string, chainID string) *Config { 434 // create a unique, concurrency-safe test directory under os.TempDir() 435 rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName)) 436 if err != nil { 437 panic(err) 438 } 439 // ensure config and data subdirs are created 440 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { 441 panic(err) 442 } 443 if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { 444 panic(err) 445 } 446 447 baseConfig := DefaultBaseConfig() 448 configFilePath := filepath.Join(rootDir, defaultConfigFilePath) 449 genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) 450 privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey) 451 privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState) 452 453 // Write default config file if missing. 454 if !tmos.FileExists(configFilePath) { 455 writeDefaultConfigFile(configFilePath) 456 } 457 if !tmos.FileExists(genesisFilePath) { 458 if chainID == "" { 459 chainID = "tendermint_test" 460 } 461 testGenesis := fmt.Sprintf(testGenesisFmt, chainID) 462 tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) 463 } 464 // we always overwrite the priv val 465 tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644) 466 tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644) 467 468 config := TestConfig().SetRoot(rootDir) 469 return config 470 } 471 472 var testGenesisFmt = `{ 473 "genesis_time": "2018-10-10T08:20:13.695936996Z", 474 "chain_id": "%s", 475 "consensus_params": { 476 "block": { 477 "max_bytes": "22020096", 478 "max_gas": "-1", 479 "time_iota_ms": "10" 480 }, 481 "evidence": { 482 "max_age_num_blocks": "100000", 483 "max_age_duration": "172800000000000", 484 "max_num": 50 485 }, 486 "validator": { 487 "pub_key_types": [ 488 "ed25519" 489 ] 490 }, 491 "version": {} 492 }, 493 "validators": [ 494 { 495 "pub_key": { 496 "type": "tendermint/PubKeyEd25519", 497 "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" 498 }, 499 "power": "10", 500 "name": "" 501 } 502 ], 503 "app_hash": "" 504 }` 505 506 var testPrivValidatorKey = `{ 507 "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145", 508 "pub_key": { 509 "type": "tendermint/PubKeyEd25519", 510 "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" 511 }, 512 "priv_key": { 513 "type": "tendermint/PrivKeyEd25519", 514 "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ==" 515 } 516 }` 517 518 var testPrivValidatorState = `{ 519 "height": "0", 520 "round": "0", 521 "step": 0 522 }`