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