github.com/vipernet-xyz/tendermint-core@v0.32.0/config/config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "github.com/syndtr/goleveldb/leveldb/opt" 6 "net/http" 7 "os" 8 "path/filepath" 9 "time" 10 11 "github.com/pkg/errors" 12 ) 13 14 const ( 15 // FuzzModeDrop is a mode in which we randomly drop reads/writes, connections or sleep 16 FuzzModeDrop = iota 17 // FuzzModeDelay is a mode in which we randomly sleep 18 FuzzModeDelay 19 20 // LogFormatPlain is a format for colored text 21 LogFormatPlain = "plain" 22 // LogFormatJSON is a format for json output 23 LogFormatJSON = "json" 24 25 KiB = 1024 26 MiB = KiB * 1024 27 GiB = MiB * 1024 28 ) 29 30 // NOTE: Most of the structs & relevant comments + the 31 // default configuration options were used to manually 32 // generate the config.toml. Please reflect any changes 33 // made here in the defaultConfigTemplate constant in 34 // config/toml.go 35 // NOTE: libs/cli must know to look in the config dir! 36 var ( 37 DefaultTendermintDir = ".tendermint" 38 defaultConfigDir = "config" 39 defaultDataDir = "data" 40 41 defaultConfigFileName = "config.toml" 42 defaultGenesisJSONName = "genesis.json" 43 44 defaultPrivValKeyName = "priv_validator_key.json" 45 defaultPrivValStateName = "priv_validator_state.json" 46 47 defaultNodeKeyName = "node_key.json" 48 defaultAddrBookName = "addrbook.json" 49 50 defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) 51 defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) 52 defaultPrivValKeyPath = filepath.Join(defaultConfigDir, defaultPrivValKeyName) 53 defaultPrivValStatePath = filepath.Join(defaultDataDir, defaultPrivValStateName) 54 55 defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) 56 defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) 57 ) 58 59 var ( 60 oldPrivVal = "priv_validator.json" 61 oldPrivValPath = filepath.Join(defaultConfigDir, oldPrivVal) 62 ) 63 64 // Config defines the top level configuration for a Tendermint node 65 type Config struct { 66 // Top level options use an anonymous struct 67 BaseConfig `mapstructure:",squash"` 68 69 // Options for services 70 RPC *RPCConfig `mapstructure:"rpc"` 71 P2P *P2PConfig `mapstructure:"p2p"` 72 Mempool *MempoolConfig `mapstructure:"mempool"` 73 FastSync *FastSyncConfig `mapstructure:"fastsync"` 74 Consensus *ConsensusConfig `mapstructure:"consensus"` 75 TxIndex *TxIndexConfig `mapstructure:"tx_index"` 76 Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"` 77 } 78 79 // DefaultConfig returns a default configuration for a Tendermint node 80 func DefaultConfig() *Config { 81 return &Config{ 82 BaseConfig: DefaultBaseConfig(), 83 RPC: DefaultRPCConfig(), 84 P2P: DefaultP2PConfig(), 85 Mempool: DefaultMempoolConfig(), 86 FastSync: DefaultFastSyncConfig(), 87 Consensus: DefaultConsensusConfig(), 88 TxIndex: DefaultTxIndexConfig(), 89 Instrumentation: DefaultInstrumentationConfig(), 90 } 91 } 92 93 // TestConfig returns a configuration that can be used for testing 94 func TestConfig() *Config { 95 return &Config{ 96 BaseConfig: TestBaseConfig(), 97 RPC: TestRPCConfig(), 98 P2P: TestP2PConfig(), 99 Mempool: TestMempoolConfig(), 100 FastSync: TestFastSyncConfig(), 101 Consensus: TestConsensusConfig(), 102 TxIndex: TestTxIndexConfig(), 103 Instrumentation: TestInstrumentationConfig(), 104 } 105 } 106 107 // SetRoot sets the RootDir for all Config structs 108 func (cfg *Config) SetRoot(root string) *Config { 109 cfg.BaseConfig.RootDir = root 110 cfg.RPC.RootDir = root 111 cfg.P2P.RootDir = root 112 cfg.Mempool.RootDir = root 113 cfg.Consensus.RootDir = root 114 return cfg 115 } 116 117 // ValidateBasic performs basic validation (checking param bounds, etc.) and 118 // returns an error if any check fails. 119 func (cfg *Config) ValidateBasic() error { 120 if err := cfg.BaseConfig.ValidateBasic(); err != nil { 121 return err 122 } 123 if err := cfg.RPC.ValidateBasic(); err != nil { 124 return errors.Wrap(err, "Error in [rpc] section") 125 } 126 if err := cfg.P2P.ValidateBasic(); err != nil { 127 return errors.Wrap(err, "Error in [p2p] section") 128 } 129 if err := cfg.Mempool.ValidateBasic(); err != nil { 130 return errors.Wrap(err, "Error in [mempool] section") 131 } 132 if err := cfg.FastSync.ValidateBasic(); err != nil { 133 return errors.Wrap(err, "Error in [fastsync] section") 134 } 135 if err := cfg.Consensus.ValidateBasic(); err != nil { 136 return errors.Wrap(err, "Error in [consensus] section") 137 } 138 return errors.Wrap( 139 cfg.Instrumentation.ValidateBasic(), 140 "Error in [instrumentation] section", 141 ) 142 } 143 144 //----------------------------------------------------------------------------- 145 // BaseConfig 146 147 // BaseConfig defines the base configuration for a Tendermint node 148 type BaseConfig struct { //nolint: maligned 149 // chainID is unexposed and immutable but here for convenience 150 chainID string 151 152 // The root directory for all data. 153 // This should be set in viper so it can unmarshal into this struct 154 RootDir string `mapstructure:"home"` 155 156 // TCP or UNIX socket address of the ABCI application, 157 // or the name of an ABCI application compiled in with the Tendermint binary 158 ProxyApp string `mapstructure:"proxy_app"` 159 160 // A custom human readable name for this node 161 Moniker string `mapstructure:"moniker"` 162 163 // If this node is many blocks behind the tip of the chain, FastSync 164 // allows them to catchup quickly by downloading blocks in parallel 165 // and verifying their commits 166 FastSyncMode bool `mapstructure:"fast_sync"` 167 168 // Database backend: goleveldb | cleveldb | boltdb | rocksdb 169 // * goleveldb (github.com/syndtr/goleveldb - most popular implementation) 170 // - pure go 171 // - stable 172 // * cleveldb (uses levigo wrapper) 173 // - fast 174 // - requires gcc 175 // - use cleveldb build tag (go build -tags cleveldb) 176 // * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt) 177 // - EXPERIMENTAL 178 // - may be faster is some use-cases (random reads - indexer) 179 // - use boltdb build tag (go build -tags boltdb) 180 // * rocksdb (uses github.com/tecbot/gorocksdb) 181 // - EXPERIMENTAL 182 // - requires gcc 183 // - use rocksdb build tag (go build -tags rocksdb) 184 DBBackend string 185 186 LevelDBOptions LevelDBOptions `mapstructure:"leveldb_opts"` 187 188 // Database directory 189 DBPath string `mapstructure:"db_dir"` 190 191 // Output level for logging 192 LogLevel string `mapstructure:"log_level"` 193 194 // Output format: 'plain' (colored text) or 'json' 195 LogFormat string `mapstructure:"log_format"` 196 197 // Path to the JSON file containing the initial validator set and other meta data 198 Genesis string `mapstructure:"genesis_file"` 199 200 // Path to the JSON file containing the private key to use as a validator in the consensus protocol 201 PrivValidatorKey string `mapstructure:"priv_validator_key_file"` 202 203 // Path to the JSON file containing the last sign state of a validator 204 PrivValidatorState string `mapstructure:"priv_validator_state_file"` 205 206 // TCP or UNIX socket address for Tendermint to listen on for 207 // connections from an external PrivValidator process 208 PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` 209 210 // A JSON file containing the private key to use for p2p authenticated encryption 211 NodeKey string `mapstructure:"node_key_file"` 212 213 // Mechanism to connect to the ABCI application: socket | grpc 214 ABCI string `mapstructure:"abci"` 215 216 // TCP or UNIX socket address for the profiling server to listen on 217 ProfListenAddress string `mapstructure:"prof_laddr"` 218 219 // If true, query the ABCI app on connecting to a new peer 220 // so the app can decide if we should keep the connection or not 221 FilterPeers bool `mapstructure:"filter_peers"` // false 222 223 } 224 225 // DefaultBaseConfig returns a default base configuration for a Tendermint node 226 func DefaultBaseConfig() BaseConfig { 227 return BaseConfig{ 228 Genesis: defaultGenesisJSONPath, 229 PrivValidatorKey: defaultPrivValKeyPath, 230 PrivValidatorState: defaultPrivValStatePath, 231 NodeKey: defaultNodeKeyPath, 232 Moniker: defaultMoniker, 233 ProxyApp: "tcp://127.0.0.1:26658", 234 ABCI: "socket", 235 LogLevel: DefaultPackageLogLevels(), 236 LogFormat: LogFormatPlain, 237 ProfListenAddress: "", 238 FastSyncMode: true, 239 FilterPeers: false, 240 DBBackend: "goleveldb", 241 DBPath: "data", 242 } 243 } 244 245 // TestBaseConfig returns a base configuration for testing a Tendermint node 246 func TestBaseConfig() BaseConfig { 247 cfg := DefaultBaseConfig() 248 cfg.chainID = "tendermint_test" 249 cfg.ProxyApp = "kvstore" 250 cfg.FastSyncMode = false 251 cfg.DBBackend = "memdb" 252 return cfg 253 } 254 255 func (cfg BaseConfig) ChainID() string { 256 return cfg.chainID 257 } 258 259 // GenesisFile returns the full path to the genesis.json file 260 func (cfg BaseConfig) GenesisFile() string { 261 return rootify(cfg.Genesis, cfg.RootDir) 262 } 263 264 // PrivValidatorKeyFile returns the full path to the priv_validator_key.json file 265 func (cfg BaseConfig) PrivValidatorKeyFile() string { 266 return rootify(cfg.PrivValidatorKey, cfg.RootDir) 267 } 268 269 // PrivValidatorFile returns the full path to the priv_validator_state.json file 270 func (cfg BaseConfig) PrivValidatorStateFile() string { 271 return rootify(cfg.PrivValidatorState, cfg.RootDir) 272 } 273 274 // NodeKeyFile returns the full path to the node_key.json file 275 func (cfg BaseConfig) NodeKeyFile() string { 276 return rootify(cfg.NodeKey, cfg.RootDir) 277 } 278 279 // DBDir returns the full path to the database directory 280 func (cfg BaseConfig) DBDir() string { 281 return rootify(cfg.DBPath, cfg.RootDir) 282 } 283 284 // ValidateBasic performs basic validation (checking param bounds, etc.) and 285 // returns an error if any check fails. 286 func (cfg BaseConfig) ValidateBasic() error { 287 switch cfg.LogFormat { 288 case LogFormatPlain, LogFormatJSON: 289 default: 290 return errors.New("unknown log_format (must be 'plain' or 'json')") 291 } 292 return nil 293 } 294 295 // DefaultLogLevel returns a default log level of "error" 296 func DefaultLogLevel() string { 297 return "error" 298 } 299 300 // DefaultPackageLogLevels returns a default log level setting so all packages 301 // log at "error", while the `state` and `main` packages log at "info" 302 func DefaultPackageLogLevels() string { 303 return fmt.Sprintf("main:info,state:info,*:%s", DefaultLogLevel()) 304 } 305 306 //----------------------------------------------------------------------------- 307 // RPCConfig 308 309 // RPCConfig defines the configuration options for the Tendermint RPC server 310 type RPCConfig struct { 311 RootDir string `mapstructure:"home"` 312 313 // TCP or UNIX socket address for the RPC server to listen on 314 ListenAddress string `mapstructure:"laddr"` 315 316 // A list of origins a cross-domain request can be executed from. 317 // If the special '*' value is present in the list, all origins will be allowed. 318 // An origin may contain a wildcard (*) to replace 0 or more characters (i.e.: http://*.domain.com). 319 // Only one wildcard can be used per origin. 320 CORSAllowedOrigins []string `mapstructure:"cors_allowed_origins"` 321 322 // A list of methods the client is allowed to use with cross-domain requests. 323 CORSAllowedMethods []string `mapstructure:"cors_allowed_methods"` 324 325 // A list of non simple headers the client is allowed to use with cross-domain requests. 326 CORSAllowedHeaders []string `mapstructure:"cors_allowed_headers"` 327 328 // TCP or UNIX socket address for the gRPC server to listen on 329 // NOTE: This server only supports /broadcast_tx_commit 330 GRPCListenAddress string `mapstructure:"grpc_laddr"` 331 332 // Maximum number of simultaneous connections. 333 // Does not include RPC (HTTP&WebSocket) connections. See max_open_connections 334 // If you want to accept a larger number than the default, make sure 335 // you increase your OS limits. 336 // 0 - unlimited. 337 GRPCMaxOpenConnections int `mapstructure:"grpc_max_open_connections"` 338 339 // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool 340 Unsafe bool `mapstructure:"unsafe"` 341 342 // Maximum number of simultaneous connections (including WebSocket). 343 // Does not include gRPC connections. See grpc_max_open_connections 344 // If you want to accept a larger number than the default, make sure 345 // you increase your OS limits. 346 // 0 - unlimited. 347 // Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} 348 // 1024 - 40 - 10 - 50 = 924 = ~900 349 MaxOpenConnections int `mapstructure:"max_open_connections"` 350 351 // Maximum number of unique clientIDs that can /subscribe 352 // If you're using /broadcast_tx_commit, set to the estimated maximum number 353 // of broadcast_tx_commit calls per block. 354 MaxSubscriptionClients int `mapstructure:"max_subscription_clients"` 355 356 // Maximum number of unique queries a given client can /subscribe to 357 // If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set 358 // to the estimated maximum number of broadcast_tx_commit calls per block. 359 MaxSubscriptionsPerClient int `mapstructure:"max_subscriptions_per_client"` 360 361 // How long to wait for a tx to be committed during /broadcast_tx_commit 362 // WARNING: Using a value larger than 10s will result in increasing the 363 // global HTTP write timeout, which applies to all connections and endpoints. 364 // See https://github.com/tendermint/tendermint/issues/3435 365 TimeoutBroadcastTxCommit time.Duration `mapstructure:"timeout_broadcast_tx_commit"` 366 367 // Maximum size of request body, in bytes 368 MaxBodyBytes int64 `mapstructure:"max_body_bytes"` 369 370 // Maximum size of request header, in bytes 371 MaxHeaderBytes int `mapstructure:"max_header_bytes"` 372 373 // The path to a file containing certificate that is used to create the HTTPS server. 374 // Migth be either absolute path or path related to tendermint's config directory. 375 // 376 // If the certificate is signed by a certificate authority, 377 // the certFile should be the concatenation of the server's certificate, any intermediates, 378 // and the CA's certificate. 379 // 380 // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. 381 // Otherwise, HTTP server is run. 382 TLSCertFile string `mapstructure:"tls_cert_file"` 383 384 // The path to a file containing matching private key that is used to create the HTTPS server. 385 // Migth be either absolute path or path related to tendermint's config directory. 386 // 387 // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. 388 // Otherwise, HTTP server is run. 389 TLSKeyFile string `mapstructure:"tls_key_file"` 390 } 391 392 // DefaultRPCConfig returns a default configuration for the RPC server 393 func DefaultRPCConfig() *RPCConfig { 394 return &RPCConfig{ 395 ListenAddress: "tcp://127.0.0.1:26657", 396 CORSAllowedOrigins: []string{}, 397 CORSAllowedMethods: []string{http.MethodHead, http.MethodGet, http.MethodPost}, 398 CORSAllowedHeaders: []string{"Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time"}, 399 GRPCListenAddress: "", 400 GRPCMaxOpenConnections: 900, 401 402 Unsafe: false, 403 MaxOpenConnections: 900, 404 405 MaxSubscriptionClients: 100, 406 MaxSubscriptionsPerClient: 5, 407 TimeoutBroadcastTxCommit: 10 * time.Second, 408 409 MaxBodyBytes: int64(1000000), // 1MB 410 MaxHeaderBytes: 1 << 20, // same as the net/http default 411 412 TLSCertFile: "", 413 TLSKeyFile: "", 414 } 415 } 416 417 // TestRPCConfig returns a configuration for testing the RPC server 418 func TestRPCConfig() *RPCConfig { 419 cfg := DefaultRPCConfig() 420 cfg.ListenAddress = "tcp://127.0.0.1:36657" 421 cfg.GRPCListenAddress = "tcp://127.0.0.1:36658" 422 cfg.Unsafe = true 423 return cfg 424 } 425 426 // ValidateBasic performs basic validation (checking param bounds, etc.) and 427 // returns an error if any check fails. 428 func (cfg *RPCConfig) ValidateBasic() error { 429 if cfg.GRPCMaxOpenConnections < 0 { 430 return errors.New("grpc_max_open_connections can't be negative") 431 } 432 if cfg.MaxOpenConnections < 0 { 433 return errors.New("max_open_connections can't be negative") 434 } 435 if cfg.MaxSubscriptionClients < 0 { 436 return errors.New("max_subscription_clients can't be negative") 437 } 438 if cfg.MaxSubscriptionsPerClient < 0 { 439 return errors.New("max_subscriptions_per_client can't be negative") 440 } 441 if cfg.TimeoutBroadcastTxCommit < 0 { 442 return errors.New("timeout_broadcast_tx_commit can't be negative") 443 } 444 if cfg.MaxBodyBytes < 0 { 445 return errors.New("max_body_bytes can't be negative") 446 } 447 if cfg.MaxHeaderBytes < 0 { 448 return errors.New("max_header_bytes can't be negative") 449 } 450 return nil 451 } 452 453 // IsCorsEnabled returns true if cross-origin resource sharing is enabled. 454 func (cfg *RPCConfig) IsCorsEnabled() bool { 455 return len(cfg.CORSAllowedOrigins) != 0 456 } 457 458 func (cfg RPCConfig) KeyFile() string { 459 path := cfg.TLSKeyFile 460 if filepath.IsAbs(path) { 461 return path 462 } 463 return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir) 464 } 465 466 func (cfg RPCConfig) CertFile() string { 467 path := cfg.TLSCertFile 468 if filepath.IsAbs(path) { 469 return path 470 } 471 return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir) 472 } 473 474 func (cfg RPCConfig) IsTLSEnabled() bool { 475 return cfg.TLSCertFile != "" && cfg.TLSKeyFile != "" 476 } 477 478 //----------------------------------------------------------------------------- 479 // P2PConfig 480 481 // P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer 482 type P2PConfig struct { //nolint: maligned 483 RootDir string `mapstructure:"home"` 484 485 // Address to listen for incoming connections 486 ListenAddress string `mapstructure:"laddr"` 487 488 // Address to advertise to peers for them to dial 489 ExternalAddress string `mapstructure:"external_address"` 490 491 // Comma separated list of seed nodes to connect to 492 // We only use these if we can’t connect to peers in the addrbook 493 Seeds string `mapstructure:"seeds"` 494 495 // Comma separated list of nodes to keep persistent connections to 496 PersistentPeers string `mapstructure:"persistent_peers"` 497 498 // UPNP port forwarding 499 UPNP bool `mapstructure:"upnp"` 500 501 // Path to address book 502 AddrBook string `mapstructure:"addr_book_file"` 503 504 // Set true for strict address routability rules 505 // Set false for private or local networks 506 AddrBookStrict bool `mapstructure:"addr_book_strict"` 507 508 // Maximum number of inbound peers 509 MaxNumInboundPeers int `mapstructure:"max_num_inbound_peers"` 510 511 // Maximum number of outbound peers to connect to, excluding persistent peers 512 MaxNumOutboundPeers int `mapstructure:"max_num_outbound_peers"` 513 514 // List of node IDs, to which a connection will be (re)established ignoring any existing limits 515 UnconditionalPeerIDs string `mapstructure:"unconditional_peer_ids"` 516 517 // Maximum pause when redialing a persistent peer (if zero, exponential backoff is used) 518 PersistentPeersMaxDialPeriod time.Duration `mapstructure:"persistent_peers_max_dial_period"` 519 520 // Time to wait before flushing messages out on the connection 521 FlushThrottleTimeout time.Duration `mapstructure:"flush_throttle_timeout"` 522 523 // Maximum size of a message packet payload, in bytes 524 MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` 525 526 // Rate at which packets can be sent, in bytes/second 527 SendRate int64 `mapstructure:"send_rate"` 528 529 // Rate at which packets can be received, in bytes/second 530 RecvRate int64 `mapstructure:"recv_rate"` 531 532 // Set true to enable the peer-exchange reactor 533 PexReactor bool `mapstructure:"pex"` 534 535 // Seed mode, in which node constantly crawls the network and looks for 536 // peers. If another node asks it for addresses, it responds and disconnects. 537 // 538 // Does not work if the peer-exchange reactor is disabled. 539 SeedMode bool `mapstructure:"seed_mode"` 540 541 // Comma separated list of peer IDs to keep private (will not be gossiped to 542 // other peers) 543 PrivatePeerIDs string `mapstructure:"private_peer_ids"` 544 545 // Toggle to disable guard against peers connecting from the same ip. 546 AllowDuplicateIP bool `mapstructure:"allow_duplicate_ip"` 547 548 // Peer connection configuration. 549 HandshakeTimeout time.Duration `mapstructure:"handshake_timeout"` 550 DialTimeout time.Duration `mapstructure:"dial_timeout"` 551 552 // Testing params. 553 // Force dial to fail 554 TestDialFail bool `mapstructure:"test_dial_fail"` 555 // FUzz connection 556 TestFuzz bool `mapstructure:"test_fuzz"` 557 TestFuzzConfig *FuzzConnConfig `mapstructure:"test_fuzz_config"` 558 } 559 560 // DefaultP2PConfig returns a default configuration for the peer-to-peer layer 561 func DefaultP2PConfig() *P2PConfig { 562 return &P2PConfig{ 563 ListenAddress: "tcp://0.0.0.0:26656", 564 ExternalAddress: "", 565 UPNP: false, 566 AddrBook: defaultAddrBookPath, 567 AddrBookStrict: true, 568 MaxNumInboundPeers: 40, 569 MaxNumOutboundPeers: 10, 570 PersistentPeersMaxDialPeriod: 0 * time.Second, 571 FlushThrottleTimeout: 100 * time.Millisecond, 572 MaxPacketMsgPayloadSize: 1024, // 1 kB 573 SendRate: 5120000, // 5 mB/s 574 RecvRate: 5120000, // 5 mB/s 575 PexReactor: true, 576 SeedMode: false, 577 AllowDuplicateIP: false, 578 HandshakeTimeout: 20 * time.Second, 579 DialTimeout: 3 * time.Second, 580 TestDialFail: false, 581 TestFuzz: false, 582 TestFuzzConfig: DefaultFuzzConnConfig(), 583 } 584 } 585 586 // TestP2PConfig returns a configuration for testing the peer-to-peer layer 587 func TestP2PConfig() *P2PConfig { 588 cfg := DefaultP2PConfig() 589 cfg.ListenAddress = "tcp://127.0.0.1:36656" 590 cfg.FlushThrottleTimeout = 10 * time.Millisecond 591 cfg.AllowDuplicateIP = true 592 return cfg 593 } 594 595 // AddrBookFile returns the full path to the address book 596 func (cfg *P2PConfig) AddrBookFile() string { 597 return rootify(cfg.AddrBook, cfg.RootDir) 598 } 599 600 // ValidateBasic performs basic validation (checking param bounds, etc.) and 601 // returns an error if any check fails. 602 func (cfg *P2PConfig) ValidateBasic() error { 603 if cfg.MaxNumInboundPeers < 0 { 604 return errors.New("max_num_inbound_peers can't be negative") 605 } 606 if cfg.MaxNumOutboundPeers < 0 { 607 return errors.New("max_num_outbound_peers can't be negative") 608 } 609 if cfg.FlushThrottleTimeout < 0 { 610 return errors.New("flush_throttle_timeout can't be negative") 611 } 612 if cfg.PersistentPeersMaxDialPeriod < 0 { 613 return errors.New("persistent_peers_max_dial_period can't be negative") 614 } 615 if cfg.MaxPacketMsgPayloadSize < 0 { 616 return errors.New("max_packet_msg_payload_size can't be negative") 617 } 618 if cfg.SendRate < 0 { 619 return errors.New("send_rate can't be negative") 620 } 621 if cfg.RecvRate < 0 { 622 return errors.New("recv_rate can't be negative") 623 } 624 return nil 625 } 626 627 // FuzzConnConfig is a FuzzedConnection configuration. 628 type FuzzConnConfig struct { 629 Mode int 630 MaxDelay time.Duration 631 ProbDropRW float64 632 ProbDropConn float64 633 ProbSleep float64 634 } 635 636 // DefaultFuzzConnConfig returns the default config. 637 func DefaultFuzzConnConfig() *FuzzConnConfig { 638 return &FuzzConnConfig{ 639 Mode: FuzzModeDrop, 640 MaxDelay: 3 * time.Second, 641 ProbDropRW: 0.2, 642 ProbDropConn: 0.00, 643 ProbSleep: 0.00, 644 } 645 } 646 647 //----------------------------------------------------------------------------- 648 // MempoolConfig 649 650 // MempoolConfig defines the configuration options for the Tendermint mempool 651 type MempoolConfig struct { 652 RootDir string `mapstructure:"home"` 653 Recheck bool `mapstructure:"recheck"` 654 Broadcast bool `mapstructure:"broadcast"` 655 WalPath string `mapstructure:"wal_dir"` 656 Size int `mapstructure:"size"` 657 MaxTxsBytes int64 `mapstructure:"max_txs_bytes"` 658 CacheSize int `mapstructure:"cache_size"` 659 MaxTxBytes int `mapstructure:"max_tx_bytes"` 660 } 661 662 // DefaultMempoolConfig returns a default configuration for the Tendermint mempool 663 func DefaultMempoolConfig() *MempoolConfig { 664 return &MempoolConfig{ 665 Recheck: true, 666 Broadcast: true, 667 WalPath: "", 668 // Each signature verification takes .5ms, Size reduced until we implement 669 // ABCI Recheck 670 Size: 5000, 671 MaxTxsBytes: 1024 * 1024 * 1024, // 1GB 672 CacheSize: 10000, 673 MaxTxBytes: 1024 * 1024, // 1MB 674 } 675 } 676 677 // TestMempoolConfig returns a configuration for testing the Tendermint mempool 678 func TestMempoolConfig() *MempoolConfig { 679 cfg := DefaultMempoolConfig() 680 cfg.CacheSize = 1000 681 return cfg 682 } 683 684 // WalDir returns the full path to the mempool's write-ahead log 685 func (cfg *MempoolConfig) WalDir() string { 686 return rootify(cfg.WalPath, cfg.RootDir) 687 } 688 689 // WalEnabled returns true if the WAL is enabled. 690 func (cfg *MempoolConfig) WalEnabled() bool { 691 return cfg.WalPath != "" 692 } 693 694 // ValidateBasic performs basic validation (checking param bounds, etc.) and 695 // returns an error if any check fails. 696 func (cfg *MempoolConfig) ValidateBasic() error { 697 if cfg.Size < 0 { 698 return errors.New("size can't be negative") 699 } 700 if cfg.MaxTxsBytes < 0 { 701 return errors.New("max_txs_bytes can't be negative") 702 } 703 if cfg.CacheSize < 0 { 704 return errors.New("cache_size can't be negative") 705 } 706 if cfg.MaxTxBytes < 0 { 707 return errors.New("max_tx_bytes can't be negative") 708 } 709 return nil 710 } 711 712 //----------------------------------------------------------------------------- 713 // FastSyncConfig 714 715 // FastSyncConfig defines the configuration for the Tendermint fast sync service 716 type FastSyncConfig struct { 717 Version string `mapstructure:"version"` 718 } 719 720 // DefaultFastSyncConfig returns a default configuration for the fast sync service 721 func DefaultFastSyncConfig() *FastSyncConfig { 722 return &FastSyncConfig{ 723 Version: "v0", 724 } 725 } 726 727 // TestFastSyncConfig returns a default configuration for the fast sync. 728 func TestFastSyncConfig() *FastSyncConfig { 729 return DefaultFastSyncConfig() 730 } 731 732 // ValidateBasic performs basic validation. 733 func (cfg *FastSyncConfig) ValidateBasic() error { 734 switch cfg.Version { 735 case "v0": 736 return nil 737 case "v1": 738 return nil 739 case "v2": 740 return nil 741 default: 742 return fmt.Errorf("unknown fastsync version %s", cfg.Version) 743 } 744 } 745 746 //----------------------------------------------------------------------------- 747 // ConsensusConfig 748 749 // ConsensusConfig defines the configuration for the Tendermint consensus service, 750 // including timeouts and details about the WAL and the block structure. 751 type ConsensusConfig struct { 752 RootDir string `mapstructure:"home"` 753 WalPath string `mapstructure:"wal_file"` 754 walFile string // overrides WalPath if set 755 756 TimeoutPropose time.Duration `mapstructure:"timeout_propose"` 757 TimeoutProposeDelta time.Duration `mapstructure:"timeout_propose_delta"` 758 TimeoutPrevote time.Duration `mapstructure:"timeout_prevote"` 759 TimeoutPrevoteDelta time.Duration `mapstructure:"timeout_prevote_delta"` 760 TimeoutPrecommit time.Duration `mapstructure:"timeout_precommit"` 761 TimeoutPrecommitDelta time.Duration `mapstructure:"timeout_precommit_delta"` 762 TimeoutCommit time.Duration `mapstructure:"timeout_commit"` 763 764 // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) 765 SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"` 766 767 // EmptyBlocks mode and possible interval between empty blocks 768 CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` 769 CreateEmptyBlocksInterval time.Duration `mapstructure:"create_empty_blocks_interval"` 770 771 // Reactor sleep duration parameters 772 PeerGossipSleepDuration time.Duration `mapstructure:"peer_gossip_sleep_duration"` 773 PeerQueryMaj23SleepDuration time.Duration `mapstructure:"peer_query_maj23_sleep_duration"` 774 } 775 776 // DefaultConsensusConfig returns a default configuration for the consensus service 777 func DefaultConsensusConfig() *ConsensusConfig { 778 return &ConsensusConfig{ 779 WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"), 780 TimeoutPropose: 3000 * time.Millisecond, 781 TimeoutProposeDelta: 500 * time.Millisecond, 782 TimeoutPrevote: 1000 * time.Millisecond, 783 TimeoutPrevoteDelta: 500 * time.Millisecond, 784 TimeoutPrecommit: 1000 * time.Millisecond, 785 TimeoutPrecommitDelta: 500 * time.Millisecond, 786 TimeoutCommit: 1000 * time.Millisecond, 787 SkipTimeoutCommit: false, 788 CreateEmptyBlocks: true, 789 CreateEmptyBlocksInterval: 0 * time.Second, 790 PeerGossipSleepDuration: 100 * time.Millisecond, 791 PeerQueryMaj23SleepDuration: 2000 * time.Millisecond, 792 } 793 } 794 795 // TestConsensusConfig returns a configuration for testing the consensus service 796 func TestConsensusConfig() *ConsensusConfig { 797 cfg := DefaultConsensusConfig() 798 cfg.TimeoutPropose = 40 * time.Millisecond 799 cfg.TimeoutProposeDelta = 1 * time.Millisecond 800 cfg.TimeoutPrevote = 10 * time.Millisecond 801 cfg.TimeoutPrevoteDelta = 1 * time.Millisecond 802 cfg.TimeoutPrecommit = 10 * time.Millisecond 803 cfg.TimeoutPrecommitDelta = 1 * time.Millisecond 804 cfg.TimeoutCommit = 10 * time.Millisecond 805 cfg.SkipTimeoutCommit = true 806 cfg.PeerGossipSleepDuration = 5 * time.Millisecond 807 cfg.PeerQueryMaj23SleepDuration = 250 * time.Millisecond 808 return cfg 809 } 810 811 // WaitForTxs returns true if the consensus should wait for transactions before entering the propose step 812 func (cfg *ConsensusConfig) WaitForTxs() bool { 813 return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 814 } 815 816 // Propose returns the amount of time to wait for a proposal 817 func (cfg *ConsensusConfig) Propose(round int) time.Duration { 818 return time.Duration( 819 cfg.TimeoutPropose.Nanoseconds()+cfg.TimeoutProposeDelta.Nanoseconds()*int64(round), 820 ) * time.Nanosecond 821 } 822 823 // Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes 824 func (cfg *ConsensusConfig) Prevote(round int) time.Duration { 825 return time.Duration( 826 cfg.TimeoutPrevote.Nanoseconds()+cfg.TimeoutPrevoteDelta.Nanoseconds()*int64(round), 827 ) * time.Nanosecond 828 } 829 830 // Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits 831 func (cfg *ConsensusConfig) Precommit(round int) time.Duration { 832 return time.Duration( 833 cfg.TimeoutPrecommit.Nanoseconds()+cfg.TimeoutPrecommitDelta.Nanoseconds()*int64(round), 834 ) * time.Nanosecond 835 } 836 837 // Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits 838 // for a single block (ie. a commit). 839 func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { 840 return t.Add(cfg.TimeoutCommit) 841 } 842 843 // WalFile returns the full path to the write-ahead log file 844 func (cfg *ConsensusConfig) WalFile() string { 845 if cfg.walFile != "" { 846 return cfg.walFile 847 } 848 return rootify(cfg.WalPath, cfg.RootDir) 849 } 850 851 // SetWalFile sets the path to the write-ahead log file 852 func (cfg *ConsensusConfig) SetWalFile(walFile string) { 853 cfg.walFile = walFile 854 } 855 856 // ValidateBasic performs basic validation (checking param bounds, etc.) and 857 // returns an error if any check fails. 858 func (cfg *ConsensusConfig) ValidateBasic() error { 859 if cfg.TimeoutPropose < 0 { 860 return errors.New("timeout_propose can't be negative") 861 } 862 if cfg.TimeoutProposeDelta < 0 { 863 return errors.New("timeout_propose_delta can't be negative") 864 } 865 if cfg.TimeoutPrevote < 0 { 866 return errors.New("timeout_prevote can't be negative") 867 } 868 if cfg.TimeoutPrevoteDelta < 0 { 869 return errors.New("timeout_prevote_delta can't be negative") 870 } 871 if cfg.TimeoutPrecommit < 0 { 872 return errors.New("timeout_precommit can't be negative") 873 } 874 if cfg.TimeoutPrecommitDelta < 0 { 875 return errors.New("timeout_precommit_delta can't be negative") 876 } 877 if cfg.TimeoutCommit < 0 { 878 return errors.New("timeout_commit can't be negative") 879 } 880 if cfg.CreateEmptyBlocksInterval < 0 { 881 return errors.New("create_empty_blocks_interval can't be negative") 882 } 883 if cfg.PeerGossipSleepDuration < 0 { 884 return errors.New("peer_gossip_sleep_duration can't be negative") 885 } 886 if cfg.PeerQueryMaj23SleepDuration < 0 { 887 return errors.New("peer_query_maj23_sleep_duration can't be negative") 888 } 889 return nil 890 } 891 892 //----------------------------------------------------------------------------- 893 // TxIndexConfig 894 // Remember that Event has the following structure: 895 // type: [ 896 // key: value, 897 // ... 898 // ] 899 // 900 // CompositeKeys are constructed by `type.key` 901 // TxIndexConfig defines the configuration for the transaction indexer, 902 // including composite keys to index. 903 type TxIndexConfig struct { 904 // What indexer to use for transactions 905 // 906 // Options: 907 // 1) "null" 908 // 2) "kv" (default) - the simplest possible indexer, 909 // backed by key-value storage (defaults to levelDB; see DBBackend). 910 Indexer string `mapstructure:"indexer"` 911 912 // Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") 913 // 914 // You can also index transactions by height by adding "tx.height" key here. 915 // 916 // It's recommended to index only a subset of keys due to possible memory 917 // bloat. This is, of course, depends on the indexer's DB and the volume of 918 // transactions. 919 IndexKeys string `mapstructure:"index_keys"` 920 921 // When set to true, tells indexer to index all compositeKeys (predefined keys: 922 // "tx.hash", "tx.height" and all keys from DeliverTx responses). 923 // 924 // Note this may be not desirable (see the comment above). IndexKeys has a 925 // precedence over IndexAllKeys (i.e. when given both, IndexKeys will be 926 // indexed). 927 IndexAllKeys bool `mapstructure:"index_all_keys"` 928 } 929 930 // DefaultTxIndexConfig returns a default configuration for the transaction indexer. 931 func DefaultTxIndexConfig() *TxIndexConfig { 932 return &TxIndexConfig{ 933 Indexer: "kv", 934 IndexKeys: "", 935 IndexAllKeys: false, 936 } 937 } 938 939 // TestTxIndexConfig returns a default configuration for the transaction indexer. 940 func TestTxIndexConfig() *TxIndexConfig { 941 return DefaultTxIndexConfig() 942 } 943 944 //----------------------------------------------------------------------------- 945 // InstrumentationConfig 946 947 // InstrumentationConfig defines the configuration for metrics reporting. 948 type InstrumentationConfig struct { 949 // When true, Prometheus metrics are served under /metrics on 950 // PrometheusListenAddr. 951 // Check out the documentation for the list of available metrics. 952 Prometheus bool `mapstructure:"prometheus"` 953 954 // Address to listen for Prometheus collector(s) connections. 955 PrometheusListenAddr string `mapstructure:"prometheus_listen_addr"` 956 957 // Maximum number of simultaneous connections. 958 // If you want to accept a larger number than the default, make sure 959 // you increase your OS limits. 960 // 0 - unlimited. 961 MaxOpenConnections int `mapstructure:"max_open_connections"` 962 963 // Instrumentation namespace. 964 Namespace string `mapstructure:"namespace"` 965 } 966 967 // DefaultInstrumentationConfig returns a default configuration for metrics 968 // reporting. 969 func DefaultInstrumentationConfig() *InstrumentationConfig { 970 return &InstrumentationConfig{ 971 Prometheus: false, 972 PrometheusListenAddr: ":26660", 973 MaxOpenConnections: 3, 974 Namespace: "tendermint", 975 } 976 } 977 978 // TestInstrumentationConfig returns a default configuration for metrics 979 // reporting. 980 func TestInstrumentationConfig() *InstrumentationConfig { 981 return DefaultInstrumentationConfig() 982 } 983 984 // ValidateBasic performs basic validation (checking param bounds, etc.) and 985 // returns an error if any check fails. 986 func (cfg *InstrumentationConfig) ValidateBasic() error { 987 if cfg.MaxOpenConnections < 0 { 988 return errors.New("max_open_connections can't be negative") 989 } 990 return nil 991 } 992 993 //----------------------------------------------------------------------------- 994 // Utils 995 996 // helper function to make config creation independent of root dir 997 func rootify(path, root string) string { 998 if filepath.IsAbs(path) { 999 return path 1000 } 1001 return filepath.Join(root, path) 1002 } 1003 1004 //----------------------------------------------------------------------------- 1005 // Moniker 1006 1007 var defaultMoniker = getDefaultMoniker() 1008 1009 // getDefaultMoniker returns a default moniker, which is the host name. If runtime 1010 // fails to get the host name, "anonymous" will be returned. 1011 func getDefaultMoniker() string { 1012 moniker, err := os.Hostname() 1013 if err != nil { 1014 moniker = "anonymous" 1015 } 1016 return moniker 1017 } 1018 1019 // Options holds the optional parameters for the DB at large. 1020 type LevelDBOptions struct { 1021 // BlockCacheCapacity defines the capacity of the 'sorted table' block caching. 1022 // Use -1 for zero, this has same effect as specifying NoCacher to BlockCacher. 1023 // 1024 // The default value is 8MiB. 1025 BlockCacheCapacity int `json:"block_cache_capacity"` 1026 1027 // BlockCacheEvictRemoved allows enable forced-eviction on cached block belonging 1028 // to removed 'sorted table'. 1029 // 1030 // The default if false. 1031 BlockCacheEvictRemoved bool `json:"block_cache_evict_removed"` 1032 1033 // BlockSize is the minimum uncompressed size in bytes of each 'sorted table' 1034 // block. 1035 // 1036 // The default value is 4KiB. 1037 BlockSize int `json:"block_size"` 1038 1039 // DisableBufferPool allows disable use of util.BufferPool functionality. 1040 // 1041 // The default value is false. 1042 DisableBufferPool bool `json:"disable_buffer_pool"` 1043 1044 // OpenFilesCacheCapacity defines the capacity of the open files caching. 1045 // Use -1 for zero, this has same effect as specifying NoCacher to OpenFilesCacher. 1046 // 1047 // The default value is 500. 1048 OpenFilesCacheCapacity int `json:"open_files_cache_capacity"` 1049 1050 // WriteBuffer defines maximum size of a 'memdb' before flushed to 1051 // 'sorted table'. 'memdb' is an in-memory DB backed by an on-disk 1052 // unsorted journal. 1053 // 1054 // LevelDB may held up to two 'memdb' at the same time. 1055 // 1056 // The default value is 4MiB. 1057 WriteBuffer int `json:"write_buffer"` 1058 } 1059 1060 func DefaultLevelDBOpts() LevelDBOptions { 1061 return LevelDBOptions{ 1062 BlockCacheCapacity: opt.DefaultBlockCacheCapacity / 100, 1063 BlockCacheEvictRemoved: false, 1064 BlockSize: opt.DefaultBlockSize, 1065 DisableBufferPool: true, 1066 OpenFilesCacheCapacity: -1, 1067 WriteBuffer: opt.DefaultWriteBuffer / 5, 1068 } 1069 } 1070 1071 func (ldb LevelDBOptions) ToGoLevelDBOpts() *opt.Options { 1072 return &opt.Options{ 1073 BlockCacheCapacity: ldb.BlockCacheCapacity, 1074 BlockCacheEvictRemoved: ldb.BlockCacheEvictRemoved, 1075 BlockSize: ldb.BlockSize, 1076 DisableBufferPool: ldb.DisableBufferPool, 1077 OpenFilesCacheCapacity: ldb.OpenFilesCacheCapacity, 1078 WriteBuffer: ldb.WriteBuffer, 1079 } 1080 }