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