github.com/KYVENetwork/cometbft/v38@v38.0.3/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 "regexp" 11 "time" 12 13 "github.com/KYVENetwork/cometbft/v38/version" 14 ) 15 16 const ( 17 // FuzzModeDrop is a mode in which we randomly drop reads/writes, connections or sleep 18 FuzzModeDrop = iota 19 // FuzzModeDelay is a mode in which we randomly sleep 20 FuzzModeDelay 21 22 // LogFormatPlain is a format for colored text 23 LogFormatPlain = "plain" 24 // LogFormatJSON is a format for json output 25 LogFormatJSON = "json" 26 27 // DefaultLogLevel defines a default log level as INFO. 28 DefaultLogLevel = "info" 29 30 DefaultTendermintDir = ".cometbft" 31 DefaultConfigDir = "config" 32 DefaultDataDir = "data" 33 34 DefaultConfigFileName = "config.toml" 35 DefaultGenesisJSONName = "genesis.json" 36 37 DefaultPrivValKeyName = "priv_validator_key.json" 38 DefaultPrivValStateName = "priv_validator_state.json" 39 40 DefaultNodeKeyName = "node_key.json" 41 DefaultAddrBookName = "addrbook.json" 42 43 MempoolTypeFlood = "flood" 44 MempoolTypeNop = "nop" 45 ) 46 47 // NOTE: Most of the structs & relevant comments + the 48 // default configuration options were used to manually 49 // generate the config.toml. Please reflect any changes 50 // made here in the defaultConfigTemplate constant in 51 // config/toml.go 52 // NOTE: libs/cli must know to look in the config dir! 53 var ( 54 defaultConfigFilePath = filepath.Join(DefaultConfigDir, DefaultConfigFileName) 55 defaultGenesisJSONPath = filepath.Join(DefaultConfigDir, DefaultGenesisJSONName) 56 defaultPrivValKeyPath = filepath.Join(DefaultConfigDir, DefaultPrivValKeyName) 57 defaultPrivValStatePath = filepath.Join(DefaultDataDir, DefaultPrivValStateName) 58 59 defaultNodeKeyPath = filepath.Join(DefaultConfigDir, DefaultNodeKeyName) 60 defaultAddrBookPath = filepath.Join(DefaultConfigDir, DefaultAddrBookName) 61 62 minSubscriptionBufferSize = 100 63 defaultSubscriptionBufferSize = 200 64 65 // taken from https://semver.org/ 66 semverRegexp = regexp.MustCompile(`^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`) 67 ) 68 69 // Config defines the top level configuration for a CometBFT node 70 type Config struct { 71 // Top level options use an anonymous struct 72 BaseConfig `mapstructure:",squash"` 73 74 // Options for services 75 RPC *RPCConfig `mapstructure:"rpc"` 76 P2P *P2PConfig `mapstructure:"p2p"` 77 Mempool *MempoolConfig `mapstructure:"mempool"` 78 StateSync *StateSyncConfig `mapstructure:"statesync"` 79 BlockSync *BlockSyncConfig `mapstructure:"blocksync"` 80 Consensus *ConsensusConfig `mapstructure:"consensus"` 81 Storage *StorageConfig `mapstructure:"storage"` 82 TxIndex *TxIndexConfig `mapstructure:"tx_index"` 83 Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"` 84 } 85 86 // DefaultConfig returns a default configuration for a CometBFT node 87 func DefaultConfig() *Config { 88 return &Config{ 89 BaseConfig: DefaultBaseConfig(), 90 RPC: DefaultRPCConfig(), 91 P2P: DefaultP2PConfig(), 92 Mempool: DefaultMempoolConfig(), 93 StateSync: DefaultStateSyncConfig(), 94 BlockSync: DefaultBlockSyncConfig(), 95 Consensus: DefaultConsensusConfig(), 96 Storage: DefaultStorageConfig(), 97 TxIndex: DefaultTxIndexConfig(), 98 Instrumentation: DefaultInstrumentationConfig(), 99 } 100 } 101 102 // TestConfig returns a configuration that can be used for testing 103 func TestConfig() *Config { 104 return &Config{ 105 BaseConfig: TestBaseConfig(), 106 RPC: TestRPCConfig(), 107 P2P: TestP2PConfig(), 108 Mempool: TestMempoolConfig(), 109 StateSync: TestStateSyncConfig(), 110 BlockSync: TestBlockSyncConfig(), 111 Consensus: TestConsensusConfig(), 112 Storage: TestStorageConfig(), 113 TxIndex: TestTxIndexConfig(), 114 Instrumentation: TestInstrumentationConfig(), 115 } 116 } 117 118 // SetRoot sets the RootDir for all Config structs 119 func (cfg *Config) SetRoot(root string) *Config { 120 cfg.BaseConfig.RootDir = root 121 cfg.RPC.RootDir = root 122 cfg.P2P.RootDir = root 123 cfg.Mempool.RootDir = root 124 cfg.Consensus.RootDir = root 125 return cfg 126 } 127 128 // ValidateBasic performs basic validation (checking param bounds, etc.) and 129 // returns an error if any check fails. 130 func (cfg *Config) ValidateBasic() error { 131 if err := cfg.BaseConfig.ValidateBasic(); err != nil { 132 return err 133 } 134 if err := cfg.RPC.ValidateBasic(); err != nil { 135 return fmt.Errorf("error in [rpc] section: %w", err) 136 } 137 if err := cfg.P2P.ValidateBasic(); err != nil { 138 return fmt.Errorf("error in [p2p] section: %w", err) 139 } 140 if err := cfg.Mempool.ValidateBasic(); err != nil { 141 return fmt.Errorf("error in [mempool] section: %w", err) 142 } 143 if err := cfg.StateSync.ValidateBasic(); err != nil { 144 return fmt.Errorf("error in [statesync] section: %w", err) 145 } 146 if err := cfg.BlockSync.ValidateBasic(); err != nil { 147 return fmt.Errorf("error in [blocksync] section: %w", err) 148 } 149 if err := cfg.Consensus.ValidateBasic(); err != nil { 150 return fmt.Errorf("error in [consensus] section: %w", err) 151 } 152 if err := cfg.Instrumentation.ValidateBasic(); err != nil { 153 return fmt.Errorf("error in [instrumentation] section: %w", err) 154 } 155 if !cfg.Consensus.CreateEmptyBlocks && cfg.Mempool.Type == MempoolTypeNop { 156 return fmt.Errorf("`nop` mempool does not support create_empty_blocks = false") 157 } 158 return nil 159 } 160 161 // CheckDeprecated returns any deprecation warnings. These are printed to the operator on startup 162 func (cfg *Config) CheckDeprecated() []string { 163 var warnings []string 164 return warnings 165 } 166 167 //----------------------------------------------------------------------------- 168 // BaseConfig 169 170 // BaseConfig defines the base configuration for a CometBFT node 171 type BaseConfig struct { //nolint: maligned 172 173 // The version of the CometBFT binary that created 174 // or last modified the config file 175 Version string `mapstructure:"version"` 176 177 // The root directory for all data. 178 // This should be set in viper so it can unmarshal into this struct 179 RootDir string `mapstructure:"home"` 180 181 // TCP or UNIX socket address of the ABCI application, 182 // or the name of an ABCI application compiled in with the CometBFT binary 183 ProxyApp string `mapstructure:"proxy_app"` 184 185 // A custom human readable name for this node 186 Moniker string `mapstructure:"moniker"` 187 188 // Database backend: goleveldb | cleveldb | boltdb | rocksdb 189 // * goleveldb (github.com/syndtr/goleveldb - most popular implementation) 190 // - pure go 191 // - stable 192 // * cleveldb (uses levigo wrapper) 193 // - fast 194 // - requires gcc 195 // - use cleveldb build tag (go build -tags cleveldb) 196 // * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt) 197 // - EXPERIMENTAL 198 // - may be faster is some use-cases (random reads - indexer) 199 // - use boltdb build tag (go build -tags boltdb) 200 // * rocksdb (uses github.com/tecbot/gorocksdb) 201 // - EXPERIMENTAL 202 // - requires gcc 203 // - use rocksdb build tag (go build -tags rocksdb) 204 // * badgerdb (uses github.com/dgraph-io/badger) 205 // - EXPERIMENTAL 206 // - use badgerdb build tag (go build -tags badgerdb) 207 DBBackend string `mapstructure:"db_backend"` 208 209 // Database directory 210 DBPath string `mapstructure:"db_dir"` 211 212 // Output level for logging 213 LogLevel string `mapstructure:"log_level"` 214 215 // Output format: 'plain' (colored text) or 'json' 216 LogFormat string `mapstructure:"log_format"` 217 218 // Path to the JSON file containing the initial validator set and other meta data 219 Genesis string `mapstructure:"genesis_file"` 220 221 // Path to the JSON file containing the private key to use as a validator in the consensus protocol 222 PrivValidatorKey string `mapstructure:"priv_validator_key_file"` 223 224 // Path to the JSON file containing the last sign state of a validator 225 PrivValidatorState string `mapstructure:"priv_validator_state_file"` 226 227 // TCP or UNIX socket address for CometBFT to listen on for 228 // connections from an external PrivValidator process 229 PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` 230 231 // A JSON file containing the private key to use for p2p authenticated encryption 232 NodeKey string `mapstructure:"node_key_file"` 233 234 // Mechanism to connect to the ABCI application: socket | grpc 235 ABCI string `mapstructure:"abci"` 236 237 // If true, query the ABCI app on connecting to a new peer 238 // so the app can decide if we should keep the connection or not 239 FilterPeers bool `mapstructure:"filter_peers"` // false 240 } 241 242 // DefaultBaseConfig returns a default base configuration for a CometBFT node 243 func DefaultBaseConfig() BaseConfig { 244 return BaseConfig{ 245 Version: version.TMCoreSemVer, 246 Genesis: defaultGenesisJSONPath, 247 PrivValidatorKey: defaultPrivValKeyPath, 248 PrivValidatorState: defaultPrivValStatePath, 249 NodeKey: defaultNodeKeyPath, 250 Moniker: defaultMoniker, 251 ProxyApp: "tcp://127.0.0.1:26658", 252 ABCI: "socket", 253 LogLevel: DefaultLogLevel, 254 LogFormat: LogFormatPlain, 255 FilterPeers: false, 256 DBBackend: "goleveldb", 257 DBPath: DefaultDataDir, 258 } 259 } 260 261 // TestBaseConfig returns a base configuration for testing a CometBFT node 262 func TestBaseConfig() BaseConfig { 263 cfg := DefaultBaseConfig() 264 cfg.ProxyApp = "kvstore" 265 cfg.DBBackend = "memdb" 266 return cfg 267 } 268 269 // GenesisFile returns the full path to the genesis.json file 270 func (cfg BaseConfig) GenesisFile() string { 271 return rootify(cfg.Genesis, cfg.RootDir) 272 } 273 274 // PrivValidatorKeyFile returns the full path to the priv_validator_key.json file 275 func (cfg BaseConfig) PrivValidatorKeyFile() string { 276 return rootify(cfg.PrivValidatorKey, cfg.RootDir) 277 } 278 279 // PrivValidatorFile returns the full path to the priv_validator_state.json file 280 func (cfg BaseConfig) PrivValidatorStateFile() string { 281 return rootify(cfg.PrivValidatorState, cfg.RootDir) 282 } 283 284 // NodeKeyFile returns the full path to the node_key.json file 285 func (cfg BaseConfig) NodeKeyFile() string { 286 return rootify(cfg.NodeKey, cfg.RootDir) 287 } 288 289 // DBDir returns the full path to the database directory 290 func (cfg BaseConfig) DBDir() string { 291 return rootify(cfg.DBPath, cfg.RootDir) 292 } 293 294 // ValidateBasic performs basic validation (checking param bounds, etc.) and 295 // returns an error if any check fails. 296 func (cfg BaseConfig) ValidateBasic() error { 297 // version on old config files aren't set so we can't expect it 298 // always to exist 299 if cfg.Version != "" && !semverRegexp.MatchString(cfg.Version) { 300 return fmt.Errorf("invalid version string: %s", cfg.Version) 301 } 302 303 switch cfg.LogFormat { 304 case LogFormatPlain, LogFormatJSON: 305 default: 306 return errors.New("unknown log_format (must be 'plain' or 'json')") 307 } 308 return nil 309 } 310 311 //----------------------------------------------------------------------------- 312 // RPCConfig 313 314 // RPCConfig defines the configuration options for the CometBFT RPC server 315 type RPCConfig struct { 316 RootDir string `mapstructure:"home"` 317 318 // TCP or UNIX socket address for the RPC server to listen on 319 ListenAddress string `mapstructure:"laddr"` 320 321 // A list of origins a cross-domain request can be executed from. 322 // If the special '*' value is present in the list, all origins will be allowed. 323 // An origin may contain a wildcard (*) to replace 0 or more characters (i.e.: http://*.domain.com). 324 // Only one wildcard can be used per origin. 325 CORSAllowedOrigins []string `mapstructure:"cors_allowed_origins"` 326 327 // A list of methods the client is allowed to use with cross-domain requests. 328 CORSAllowedMethods []string `mapstructure:"cors_allowed_methods"` 329 330 // A list of non simple headers the client is allowed to use with cross-domain requests. 331 CORSAllowedHeaders []string `mapstructure:"cors_allowed_headers"` 332 333 // TCP or UNIX socket address for the gRPC server to listen on 334 // NOTE: This server only supports /broadcast_tx_commit 335 GRPCListenAddress string `mapstructure:"grpc_laddr"` 336 337 // Maximum number of simultaneous connections. 338 // Does not include RPC (HTTP&WebSocket) connections. See max_open_connections 339 // If you want to accept a larger number than the default, make sure 340 // you increase your OS limits. 341 // 0 - unlimited. 342 GRPCMaxOpenConnections int `mapstructure:"grpc_max_open_connections"` 343 344 // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool 345 Unsafe bool `mapstructure:"unsafe"` 346 347 // Maximum number of simultaneous connections (including WebSocket). 348 // Does not include gRPC connections. See grpc_max_open_connections 349 // If you want to accept a larger number than the default, make sure 350 // you increase your OS limits. 351 // 0 - unlimited. 352 // Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} 353 // 1024 - 40 - 10 - 50 = 924 = ~900 354 MaxOpenConnections int `mapstructure:"max_open_connections"` 355 356 // Maximum number of unique clientIDs that can /subscribe 357 // If you're using /broadcast_tx_commit, set to the estimated maximum number 358 // of broadcast_tx_commit calls per block. 359 MaxSubscriptionClients int `mapstructure:"max_subscription_clients"` 360 361 // Maximum number of unique queries a given client can /subscribe to 362 // If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set 363 // to the estimated maximum number of broadcast_tx_commit calls per block. 364 MaxSubscriptionsPerClient int `mapstructure:"max_subscriptions_per_client"` 365 366 // The number of events that can be buffered per subscription before 367 // returning `ErrOutOfCapacity`. 368 SubscriptionBufferSize int `mapstructure:"experimental_subscription_buffer_size"` 369 370 // The maximum number of responses that can be buffered per WebSocket 371 // client. If clients cannot read from the WebSocket endpoint fast enough, 372 // they will be disconnected, so increasing this parameter may reduce the 373 // chances of them being disconnected (but will cause the node to use more 374 // memory). 375 // 376 // Must be at least the same as `SubscriptionBufferSize`, otherwise 377 // connections may be dropped unnecessarily. 378 WebSocketWriteBufferSize int `mapstructure:"experimental_websocket_write_buffer_size"` 379 380 // If a WebSocket client cannot read fast enough, at present we may 381 // silently drop events instead of generating an error or disconnecting the 382 // client. 383 // 384 // Enabling this parameter will cause the WebSocket connection to be closed 385 // instead if it cannot read fast enough, allowing for greater 386 // predictability in subscription behavior. 387 CloseOnSlowClient bool `mapstructure:"experimental_close_on_slow_client"` 388 389 // How long to wait for a tx to be committed during /broadcast_tx_commit 390 // WARNING: Using a value larger than 10s will result in increasing the 391 // global HTTP write timeout, which applies to all connections and endpoints. 392 // See https://github.com/tendermint/tendermint/issues/3435 393 TimeoutBroadcastTxCommit time.Duration `mapstructure:"timeout_broadcast_tx_commit"` 394 395 // Maximum size of request body, in bytes 396 MaxBodyBytes int64 `mapstructure:"max_body_bytes"` 397 398 // Maximum size of request header, in bytes 399 MaxHeaderBytes int `mapstructure:"max_header_bytes"` 400 401 // The path to a file containing certificate that is used to create the HTTPS server. 402 // Might be either absolute path or path related to CometBFT's config directory. 403 // 404 // If the certificate is signed by a certificate authority, 405 // the certFile should be the concatenation of the server's certificate, any intermediates, 406 // and the CA's certificate. 407 // 408 // NOTE: both tls_cert_file and tls_key_file must be present for CometBFT to create HTTPS server. 409 // Otherwise, HTTP server is run. 410 TLSCertFile string `mapstructure:"tls_cert_file"` 411 412 // The path to a file containing matching private key that is used to create the HTTPS server. 413 // Might be either absolute path or path related to CometBFT's config directory. 414 // 415 // NOTE: both tls_cert_file and tls_key_file must be present for CometBFT to create HTTPS server. 416 // Otherwise, HTTP server is run. 417 TLSKeyFile string `mapstructure:"tls_key_file"` 418 419 // pprof listen address (https://golang.org/pkg/net/http/pprof) 420 // FIXME: This should be moved under the instrumentation section 421 PprofListenAddress string `mapstructure:"pprof_laddr"` 422 } 423 424 // DefaultRPCConfig returns a default configuration for the RPC server 425 func DefaultRPCConfig() *RPCConfig { 426 return &RPCConfig{ 427 ListenAddress: "tcp://127.0.0.1:26657", 428 CORSAllowedOrigins: []string{}, 429 CORSAllowedMethods: []string{http.MethodHead, http.MethodGet, http.MethodPost}, 430 CORSAllowedHeaders: []string{"Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time"}, 431 GRPCListenAddress: "", 432 GRPCMaxOpenConnections: 900, 433 434 Unsafe: false, 435 MaxOpenConnections: 900, 436 437 MaxSubscriptionClients: 100, 438 MaxSubscriptionsPerClient: 5, 439 SubscriptionBufferSize: defaultSubscriptionBufferSize, 440 TimeoutBroadcastTxCommit: 10 * time.Second, 441 WebSocketWriteBufferSize: defaultSubscriptionBufferSize, 442 443 MaxBodyBytes: int64(1000000), // 1MB 444 MaxHeaderBytes: 1 << 20, // same as the net/http default 445 446 TLSCertFile: "", 447 TLSKeyFile: "", 448 } 449 } 450 451 // TestRPCConfig returns a configuration for testing the RPC server 452 func TestRPCConfig() *RPCConfig { 453 cfg := DefaultRPCConfig() 454 cfg.ListenAddress = "tcp://127.0.0.1:36657" 455 cfg.GRPCListenAddress = "tcp://127.0.0.1:36658" 456 cfg.Unsafe = true 457 return cfg 458 } 459 460 // ValidateBasic performs basic validation (checking param bounds, etc.) and 461 // returns an error if any check fails. 462 func (cfg *RPCConfig) ValidateBasic() error { 463 if cfg.GRPCMaxOpenConnections < 0 { 464 return errors.New("grpc_max_open_connections can't be negative") 465 } 466 if cfg.MaxOpenConnections < 0 { 467 return errors.New("max_open_connections can't be negative") 468 } 469 if cfg.MaxSubscriptionClients < 0 { 470 return errors.New("max_subscription_clients can't be negative") 471 } 472 if cfg.MaxSubscriptionsPerClient < 0 { 473 return errors.New("max_subscriptions_per_client can't be negative") 474 } 475 if cfg.SubscriptionBufferSize < minSubscriptionBufferSize { 476 return fmt.Errorf( 477 "experimental_subscription_buffer_size must be >= %d", 478 minSubscriptionBufferSize, 479 ) 480 } 481 if cfg.WebSocketWriteBufferSize < cfg.SubscriptionBufferSize { 482 return fmt.Errorf( 483 "experimental_websocket_write_buffer_size must be >= experimental_subscription_buffer_size (%d)", 484 cfg.SubscriptionBufferSize, 485 ) 486 } 487 if cfg.TimeoutBroadcastTxCommit < 0 { 488 return errors.New("timeout_broadcast_tx_commit can't be negative") 489 } 490 if cfg.MaxBodyBytes < 0 { 491 return errors.New("max_body_bytes can't be negative") 492 } 493 if cfg.MaxHeaderBytes < 0 { 494 return errors.New("max_header_bytes can't be negative") 495 } 496 return nil 497 } 498 499 // IsCorsEnabled returns true if cross-origin resource sharing is enabled. 500 func (cfg *RPCConfig) IsCorsEnabled() bool { 501 return len(cfg.CORSAllowedOrigins) != 0 502 } 503 504 func (cfg *RPCConfig) IsPprofEnabled() bool { 505 return len(cfg.PprofListenAddress) != 0 506 } 507 508 func (cfg RPCConfig) KeyFile() string { 509 path := cfg.TLSKeyFile 510 if filepath.IsAbs(path) { 511 return path 512 } 513 return rootify(filepath.Join(DefaultConfigDir, path), cfg.RootDir) 514 } 515 516 func (cfg RPCConfig) CertFile() string { 517 path := cfg.TLSCertFile 518 if filepath.IsAbs(path) { 519 return path 520 } 521 return rootify(filepath.Join(DefaultConfigDir, path), cfg.RootDir) 522 } 523 524 func (cfg RPCConfig) IsTLSEnabled() bool { 525 return cfg.TLSCertFile != "" && cfg.TLSKeyFile != "" 526 } 527 528 //----------------------------------------------------------------------------- 529 // P2PConfig 530 531 // P2PConfig defines the configuration options for the CometBFT peer-to-peer networking layer 532 type P2PConfig struct { //nolint: maligned 533 RootDir string `mapstructure:"home"` 534 535 // Address to listen for incoming connections 536 ListenAddress string `mapstructure:"laddr"` 537 538 // Address to advertise to peers for them to dial 539 ExternalAddress string `mapstructure:"external_address"` 540 541 // Comma separated list of seed nodes to connect to 542 // We only use these if we can’t connect to peers in the addrbook 543 Seeds string `mapstructure:"seeds"` 544 545 // Comma separated list of nodes to keep persistent connections to 546 PersistentPeers string `mapstructure:"persistent_peers"` 547 548 // Path to address book 549 AddrBook string `mapstructure:"addr_book_file"` 550 551 // Set true for strict address routability rules 552 // Set false for private or local networks 553 AddrBookStrict bool `mapstructure:"addr_book_strict"` 554 555 // Maximum number of inbound peers 556 MaxNumInboundPeers int `mapstructure:"max_num_inbound_peers"` 557 558 // Maximum number of outbound peers to connect to, excluding persistent peers 559 MaxNumOutboundPeers int `mapstructure:"max_num_outbound_peers"` 560 561 // List of node IDs, to which a connection will be (re)established ignoring any existing limits 562 UnconditionalPeerIDs string `mapstructure:"unconditional_peer_ids"` 563 564 // Maximum pause when redialing a persistent peer (if zero, exponential backoff is used) 565 PersistentPeersMaxDialPeriod time.Duration `mapstructure:"persistent_peers_max_dial_period"` 566 567 // Time to wait before flushing messages out on the connection 568 FlushThrottleTimeout time.Duration `mapstructure:"flush_throttle_timeout"` 569 570 // Maximum size of a message packet payload, in bytes 571 MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` 572 573 // Rate at which packets can be sent, in bytes/second 574 SendRate int64 `mapstructure:"send_rate"` 575 576 // Rate at which packets can be received, in bytes/second 577 RecvRate int64 `mapstructure:"recv_rate"` 578 579 // Set true to enable the peer-exchange reactor 580 PexReactor bool `mapstructure:"pex"` 581 582 // Seed mode, in which node constantly crawls the network and looks for 583 // peers. If another node asks it for addresses, it responds and disconnects. 584 // 585 // Does not work if the peer-exchange reactor is disabled. 586 SeedMode bool `mapstructure:"seed_mode"` 587 588 // Comma separated list of peer IDs to keep private (will not be gossiped to 589 // other peers) 590 PrivatePeerIDs string `mapstructure:"private_peer_ids"` 591 592 // Toggle to disable guard against peers connecting from the same ip. 593 AllowDuplicateIP bool `mapstructure:"allow_duplicate_ip"` 594 595 // Peer connection configuration. 596 HandshakeTimeout time.Duration `mapstructure:"handshake_timeout"` 597 DialTimeout time.Duration `mapstructure:"dial_timeout"` 598 599 // Testing params. 600 // Force dial to fail 601 TestDialFail bool `mapstructure:"test_dial_fail"` 602 // Fuzz connection 603 TestFuzz bool `mapstructure:"test_fuzz"` 604 TestFuzzConfig *FuzzConnConfig `mapstructure:"test_fuzz_config"` 605 } 606 607 // DefaultP2PConfig returns a default configuration for the peer-to-peer layer 608 func DefaultP2PConfig() *P2PConfig { 609 return &P2PConfig{ 610 ListenAddress: "tcp://0.0.0.0:26656", 611 ExternalAddress: "", 612 AddrBook: defaultAddrBookPath, 613 AddrBookStrict: true, 614 MaxNumInboundPeers: 40, 615 MaxNumOutboundPeers: 10, 616 PersistentPeersMaxDialPeriod: 0 * time.Second, 617 FlushThrottleTimeout: 100 * time.Millisecond, 618 MaxPacketMsgPayloadSize: 1024, // 1 kB 619 SendRate: 5120000, // 5 mB/s 620 RecvRate: 5120000, // 5 mB/s 621 PexReactor: true, 622 SeedMode: false, 623 AllowDuplicateIP: false, 624 HandshakeTimeout: 20 * time.Second, 625 DialTimeout: 3 * time.Second, 626 TestDialFail: false, 627 TestFuzz: false, 628 TestFuzzConfig: DefaultFuzzConnConfig(), 629 } 630 } 631 632 // TestP2PConfig returns a configuration for testing the peer-to-peer layer 633 func TestP2PConfig() *P2PConfig { 634 cfg := DefaultP2PConfig() 635 cfg.ListenAddress = "tcp://127.0.0.1:36656" 636 cfg.FlushThrottleTimeout = 10 * time.Millisecond 637 cfg.AllowDuplicateIP = true 638 return cfg 639 } 640 641 // AddrBookFile returns the full path to the address book 642 func (cfg *P2PConfig) AddrBookFile() string { 643 return rootify(cfg.AddrBook, cfg.RootDir) 644 } 645 646 // ValidateBasic performs basic validation (checking param bounds, etc.) and 647 // returns an error if any check fails. 648 func (cfg *P2PConfig) ValidateBasic() error { 649 if cfg.MaxNumInboundPeers < 0 { 650 return errors.New("max_num_inbound_peers can't be negative") 651 } 652 if cfg.MaxNumOutboundPeers < 0 { 653 return errors.New("max_num_outbound_peers can't be negative") 654 } 655 if cfg.FlushThrottleTimeout < 0 { 656 return errors.New("flush_throttle_timeout can't be negative") 657 } 658 if cfg.PersistentPeersMaxDialPeriod < 0 { 659 return errors.New("persistent_peers_max_dial_period can't be negative") 660 } 661 if cfg.MaxPacketMsgPayloadSize < 0 { 662 return errors.New("max_packet_msg_payload_size can't be negative") 663 } 664 if cfg.SendRate < 0 { 665 return errors.New("send_rate can't be negative") 666 } 667 if cfg.RecvRate < 0 { 668 return errors.New("recv_rate can't be negative") 669 } 670 return nil 671 } 672 673 // FuzzConnConfig is a FuzzedConnection configuration. 674 type FuzzConnConfig struct { 675 Mode int 676 MaxDelay time.Duration 677 ProbDropRW float64 678 ProbDropConn float64 679 ProbSleep float64 680 } 681 682 // DefaultFuzzConnConfig returns the default config. 683 func DefaultFuzzConnConfig() *FuzzConnConfig { 684 return &FuzzConnConfig{ 685 Mode: FuzzModeDrop, 686 MaxDelay: 3 * time.Second, 687 ProbDropRW: 0.2, 688 ProbDropConn: 0.00, 689 ProbSleep: 0.00, 690 } 691 } 692 693 //----------------------------------------------------------------------------- 694 // MempoolConfig 695 696 // MempoolConfig defines the configuration options for the CometBFT mempool 697 // 698 // Note: Until v0.37 there was a `Version` field to select which implementation 699 // of the mempool to use. Two versions used to exist: the current, default 700 // implementation (previously called v0), and a prioritized mempool (v1), which 701 // was removed (see https://github.com/KYVENetwork/cometbft/v38/issues/260). 702 type MempoolConfig struct { 703 // The type of mempool for this node to use. 704 // 705 // Possible types: 706 // - "flood" : concurrent linked list mempool with flooding gossip protocol 707 // (default) 708 // - "nop" : nop-mempool (short for no operation; the ABCI app is 709 // responsible for storing, disseminating and proposing txs). 710 // "create_empty_blocks=false" is not supported. 711 Type string `mapstructure:"type"` 712 // RootDir is the root directory for all data. This should be configured via 713 // the $CMTHOME env variable or --home cmd flag rather than overriding this 714 // struct field. 715 RootDir string `mapstructure:"home"` 716 // Recheck (default: true) defines whether CometBFT should recheck the 717 // validity for all remaining transaction in the mempool after a block. 718 // Since a block affects the application state, some transactions in the 719 // mempool may become invalid. If this does not apply to your application, 720 // you can disable rechecking. 721 Recheck bool `mapstructure:"recheck"` 722 // Broadcast (default: true) defines whether the mempool should relay 723 // transactions to other peers. Setting this to false will stop the mempool 724 // from relaying transactions to other peers until they are included in a 725 // block. In other words, if Broadcast is disabled, only the peer you send 726 // the tx to will see it until it is included in a block. 727 Broadcast bool `mapstructure:"broadcast"` 728 // WalPath (default: "") configures the location of the Write Ahead Log 729 // (WAL) for the mempool. The WAL is disabled by default. To enable, set 730 // WalPath to where you want the WAL to be written (e.g. 731 // "data/mempool.wal"). 732 WalPath string `mapstructure:"wal_dir"` 733 // Maximum number of transactions in the mempool 734 Size int `mapstructure:"size"` 735 // Limit the total size of all txs in the mempool. 736 // This only accounts for raw transactions (e.g. given 1MB transactions and 737 // max_txs_bytes=5MB, mempool will only accept 5 transactions). 738 MaxTxsBytes int64 `mapstructure:"max_txs_bytes"` 739 // Size of the cache (used to filter transactions we saw earlier) in transactions 740 CacheSize int `mapstructure:"cache_size"` 741 // Do not remove invalid transactions from the cache (default: false) 742 // Set to true if it's not possible for any invalid transaction to become 743 // valid again in the future. 744 KeepInvalidTxsInCache bool `mapstructure:"keep-invalid-txs-in-cache"` 745 // Maximum size of a single transaction 746 // NOTE: the max size of a tx transmitted over the network is {max_tx_bytes}. 747 MaxTxBytes int `mapstructure:"max_tx_bytes"` 748 // Maximum size of a batch of transactions to send to a peer 749 // Including space needed by encoding (one varint per transaction). 750 // XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796 751 MaxBatchBytes int `mapstructure:"max_batch_bytes"` 752 // Experimental parameters to limit gossiping txs to up to the specified number of peers. 753 // We use two independent upper values for persistent and non-persistent peers. 754 // Unconditional peers are not affected by this feature. 755 // If we are connected to more than the specified number of persistent peers, only send txs to 756 // ExperimentalMaxGossipConnectionsToPersistentPeers of them. If one of those 757 // persistent peers disconnects, activate another persistent peer. 758 // Similarly for non-persistent peers, with an upper limit of 759 // ExperimentalMaxGossipConnectionsToNonPersistentPeers. 760 // If set to 0, the feature is disabled for the corresponding group of peers, that is, the 761 // number of active connections to that group of peers is not bounded. 762 // For non-persistent peers, if enabled, a value of 10 is recommended based on experimental 763 // performance results using the default P2P configuration. 764 ExperimentalMaxGossipConnectionsToPersistentPeers int `mapstructure:"experimental_max_gossip_connections_to_persistent_peers"` 765 ExperimentalMaxGossipConnectionsToNonPersistentPeers int `mapstructure:"experimental_max_gossip_connections_to_non_persistent_peers"` 766 } 767 768 // DefaultMempoolConfig returns a default configuration for the CometBFT mempool 769 func DefaultMempoolConfig() *MempoolConfig { 770 return &MempoolConfig{ 771 Type: MempoolTypeFlood, 772 Recheck: true, 773 Broadcast: true, 774 WalPath: "", 775 // Each signature verification takes .5ms, Size reduced until we implement 776 // ABCI Recheck 777 Size: 5000, 778 MaxTxsBytes: 1024 * 1024 * 1024, // 1GB 779 CacheSize: 10000, 780 MaxTxBytes: 1024 * 1024, // 1MB 781 ExperimentalMaxGossipConnectionsToNonPersistentPeers: 0, 782 ExperimentalMaxGossipConnectionsToPersistentPeers: 0, 783 } 784 } 785 786 // TestMempoolConfig returns a configuration for testing the CometBFT mempool 787 func TestMempoolConfig() *MempoolConfig { 788 cfg := DefaultMempoolConfig() 789 cfg.CacheSize = 1000 790 return cfg 791 } 792 793 // WalDir returns the full path to the mempool's write-ahead log 794 func (cfg *MempoolConfig) WalDir() string { 795 return rootify(cfg.WalPath, cfg.RootDir) 796 } 797 798 // WalEnabled returns true if the WAL is enabled. 799 func (cfg *MempoolConfig) WalEnabled() bool { 800 return cfg.WalPath != "" 801 } 802 803 // ValidateBasic performs basic validation (checking param bounds, etc.) and 804 // returns an error if any check fails. 805 func (cfg *MempoolConfig) ValidateBasic() error { 806 switch cfg.Type { 807 case MempoolTypeFlood, MempoolTypeNop: 808 case "": // allow empty string to be backwards compatible 809 default: 810 return fmt.Errorf("unknown mempool type: %q", cfg.Type) 811 } 812 if cfg.Size < 0 { 813 return errors.New("size can't be negative") 814 } 815 if cfg.MaxTxsBytes < 0 { 816 return errors.New("max_txs_bytes can't be negative") 817 } 818 if cfg.CacheSize < 0 { 819 return errors.New("cache_size can't be negative") 820 } 821 if cfg.MaxTxBytes < 0 { 822 return errors.New("max_tx_bytes can't be negative") 823 } 824 if cfg.ExperimentalMaxGossipConnectionsToPersistentPeers < 0 { 825 return errors.New("experimental_max_gossip_connections_to_persistent_peers can't be negative") 826 } 827 if cfg.ExperimentalMaxGossipConnectionsToNonPersistentPeers < 0 { 828 return errors.New("experimental_max_gossip_connections_to_non_persistent_peers can't be negative") 829 } 830 return nil 831 } 832 833 //----------------------------------------------------------------------------- 834 // StateSyncConfig 835 836 // StateSyncConfig defines the configuration for the CometBFT state sync service 837 type StateSyncConfig struct { 838 Enable bool `mapstructure:"enable"` 839 TempDir string `mapstructure:"temp_dir"` 840 RPCServers []string `mapstructure:"rpc_servers"` 841 TrustPeriod time.Duration `mapstructure:"trust_period"` 842 TrustHeight int64 `mapstructure:"trust_height"` 843 TrustHash string `mapstructure:"trust_hash"` 844 DiscoveryTime time.Duration `mapstructure:"discovery_time"` 845 ChunkRequestTimeout time.Duration `mapstructure:"chunk_request_timeout"` 846 ChunkFetchers int32 `mapstructure:"chunk_fetchers"` 847 } 848 849 func (cfg *StateSyncConfig) TrustHashBytes() []byte { 850 // validated in ValidateBasic, so we can safely panic here 851 bytes, err := hex.DecodeString(cfg.TrustHash) 852 if err != nil { 853 panic(err) 854 } 855 return bytes 856 } 857 858 // DefaultStateSyncConfig returns a default configuration for the state sync service 859 func DefaultStateSyncConfig() *StateSyncConfig { 860 return &StateSyncConfig{ 861 TrustPeriod: 168 * time.Hour, 862 DiscoveryTime: 15 * time.Second, 863 ChunkRequestTimeout: 10 * time.Second, 864 ChunkFetchers: 4, 865 } 866 } 867 868 // TestStateSyncConfig returns a default configuration for the state sync service 869 func TestStateSyncConfig() *StateSyncConfig { 870 return DefaultStateSyncConfig() 871 } 872 873 // ValidateBasic performs basic validation. 874 func (cfg *StateSyncConfig) ValidateBasic() error { 875 if cfg.Enable { 876 if len(cfg.RPCServers) == 0 { 877 return errors.New("rpc_servers is required") 878 } 879 880 if len(cfg.RPCServers) < 2 { 881 return errors.New("at least two rpc_servers entries is required") 882 } 883 884 for _, server := range cfg.RPCServers { 885 if len(server) == 0 { 886 return errors.New("found empty rpc_servers entry") 887 } 888 } 889 890 if cfg.DiscoveryTime != 0 && cfg.DiscoveryTime < 5*time.Second { 891 return errors.New("discovery time must be 0s or greater than five seconds") 892 } 893 894 if cfg.TrustPeriod <= 0 { 895 return errors.New("trusted_period is required") 896 } 897 898 if cfg.TrustHeight <= 0 { 899 return errors.New("trusted_height is required") 900 } 901 902 if len(cfg.TrustHash) == 0 { 903 return errors.New("trusted_hash is required") 904 } 905 906 _, err := hex.DecodeString(cfg.TrustHash) 907 if err != nil { 908 return fmt.Errorf("invalid trusted_hash: %w", err) 909 } 910 911 if cfg.ChunkRequestTimeout < 5*time.Second { 912 return errors.New("chunk_request_timeout must be at least 5 seconds") 913 } 914 915 if cfg.ChunkFetchers <= 0 { 916 return errors.New("chunk_fetchers is required") 917 } 918 } 919 920 return nil 921 } 922 923 //----------------------------------------------------------------------------- 924 // BlockSyncConfig 925 926 // BlockSyncConfig (formerly known as FastSync) defines the configuration for the CometBFT block sync service 927 type BlockSyncConfig struct { 928 Version string `mapstructure:"version"` 929 } 930 931 // DefaultBlockSyncConfig returns a default configuration for the block sync service 932 func DefaultBlockSyncConfig() *BlockSyncConfig { 933 return &BlockSyncConfig{ 934 Version: "v0", 935 } 936 } 937 938 // TestBlockSyncConfig returns a default configuration for the block sync. 939 func TestBlockSyncConfig() *BlockSyncConfig { 940 return DefaultBlockSyncConfig() 941 } 942 943 // ValidateBasic performs basic validation. 944 func (cfg *BlockSyncConfig) ValidateBasic() error { 945 switch cfg.Version { 946 case "v0": 947 return nil 948 case "v1", "v2": 949 return fmt.Errorf("blocksync version %s has been deprecated. Please use v0 instead", cfg.Version) 950 default: 951 return fmt.Errorf("unknown blocksync version %s", cfg.Version) 952 } 953 } 954 955 //----------------------------------------------------------------------------- 956 // ConsensusConfig 957 958 // ConsensusConfig defines the configuration for the Tendermint consensus algorithm, adopted by CometBFT, 959 // including timeouts and details about the WAL and the block structure. 960 type ConsensusConfig struct { 961 RootDir string `mapstructure:"home"` 962 WalPath string `mapstructure:"wal_file"` 963 walFile string // overrides WalPath if set 964 965 // How long we wait for a proposal block before prevoting nil 966 TimeoutPropose time.Duration `mapstructure:"timeout_propose"` 967 // How much timeout_propose increases with each round 968 TimeoutProposeDelta time.Duration `mapstructure:"timeout_propose_delta"` 969 // How long we wait after receiving +2/3 prevotes for “anything” (ie. not a single block or nil) 970 TimeoutPrevote time.Duration `mapstructure:"timeout_prevote"` 971 // How much the timeout_prevote increases with each round 972 TimeoutPrevoteDelta time.Duration `mapstructure:"timeout_prevote_delta"` 973 // How long we wait after receiving +2/3 precommits for “anything” (ie. not a single block or nil) 974 TimeoutPrecommit time.Duration `mapstructure:"timeout_precommit"` 975 // How much the timeout_precommit increases with each round 976 TimeoutPrecommitDelta time.Duration `mapstructure:"timeout_precommit_delta"` 977 // How long we wait after committing a block, before starting on the new 978 // height (this gives us a chance to receive some more precommits, even 979 // though we already have +2/3). 980 // NOTE: when modifying, make sure to update time_iota_ms genesis parameter 981 TimeoutCommit time.Duration `mapstructure:"timeout_commit"` 982 983 // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) 984 SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"` 985 986 // EmptyBlocks mode and possible interval between empty blocks 987 CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` 988 CreateEmptyBlocksInterval time.Duration `mapstructure:"create_empty_blocks_interval"` 989 990 // Reactor sleep duration parameters 991 PeerGossipSleepDuration time.Duration `mapstructure:"peer_gossip_sleep_duration"` 992 PeerQueryMaj23SleepDuration time.Duration `mapstructure:"peer_query_maj23_sleep_duration"` 993 994 DoubleSignCheckHeight int64 `mapstructure:"double_sign_check_height"` 995 } 996 997 // DefaultConsensusConfig returns a default configuration for the consensus service 998 func DefaultConsensusConfig() *ConsensusConfig { 999 return &ConsensusConfig{ 1000 WalPath: filepath.Join(DefaultDataDir, "cs.wal", "wal"), 1001 TimeoutPropose: 3000 * time.Millisecond, 1002 TimeoutProposeDelta: 500 * time.Millisecond, 1003 TimeoutPrevote: 1000 * time.Millisecond, 1004 TimeoutPrevoteDelta: 500 * time.Millisecond, 1005 TimeoutPrecommit: 1000 * time.Millisecond, 1006 TimeoutPrecommitDelta: 500 * time.Millisecond, 1007 TimeoutCommit: 1000 * time.Millisecond, 1008 SkipTimeoutCommit: false, 1009 CreateEmptyBlocks: true, 1010 CreateEmptyBlocksInterval: 0 * time.Second, 1011 PeerGossipSleepDuration: 100 * time.Millisecond, 1012 PeerQueryMaj23SleepDuration: 2000 * time.Millisecond, 1013 DoubleSignCheckHeight: int64(0), 1014 } 1015 } 1016 1017 // TestConsensusConfig returns a configuration for testing the consensus service 1018 func TestConsensusConfig() *ConsensusConfig { 1019 cfg := DefaultConsensusConfig() 1020 cfg.TimeoutPropose = 40 * time.Millisecond 1021 cfg.TimeoutProposeDelta = 1 * time.Millisecond 1022 cfg.TimeoutPrevote = 10 * time.Millisecond 1023 cfg.TimeoutPrevoteDelta = 1 * time.Millisecond 1024 cfg.TimeoutPrecommit = 10 * time.Millisecond 1025 cfg.TimeoutPrecommitDelta = 1 * time.Millisecond 1026 // NOTE: when modifying, make sure to update time_iota_ms (testGenesisFmt) in toml.go 1027 cfg.TimeoutCommit = 10 * time.Millisecond 1028 cfg.SkipTimeoutCommit = true 1029 cfg.PeerGossipSleepDuration = 5 * time.Millisecond 1030 cfg.PeerQueryMaj23SleepDuration = 250 * time.Millisecond 1031 cfg.DoubleSignCheckHeight = int64(0) 1032 return cfg 1033 } 1034 1035 // WaitForTxs returns true if the consensus should wait for transactions before entering the propose step 1036 func (cfg *ConsensusConfig) WaitForTxs() bool { 1037 return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 1038 } 1039 1040 // Propose returns the amount of time to wait for a proposal 1041 func (cfg *ConsensusConfig) Propose(round int32) time.Duration { 1042 return time.Duration( 1043 cfg.TimeoutPropose.Nanoseconds()+cfg.TimeoutProposeDelta.Nanoseconds()*int64(round), 1044 ) * time.Nanosecond 1045 } 1046 1047 // Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes 1048 func (cfg *ConsensusConfig) Prevote(round int32) time.Duration { 1049 return time.Duration( 1050 cfg.TimeoutPrevote.Nanoseconds()+cfg.TimeoutPrevoteDelta.Nanoseconds()*int64(round), 1051 ) * time.Nanosecond 1052 } 1053 1054 // Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits 1055 func (cfg *ConsensusConfig) Precommit(round int32) time.Duration { 1056 return time.Duration( 1057 cfg.TimeoutPrecommit.Nanoseconds()+cfg.TimeoutPrecommitDelta.Nanoseconds()*int64(round), 1058 ) * time.Nanosecond 1059 } 1060 1061 // Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits 1062 // for a single block (ie. a commit). 1063 func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { 1064 return t.Add(cfg.TimeoutCommit) 1065 } 1066 1067 // WalFile returns the full path to the write-ahead log file 1068 func (cfg *ConsensusConfig) WalFile() string { 1069 if cfg.walFile != "" { 1070 return cfg.walFile 1071 } 1072 return rootify(cfg.WalPath, cfg.RootDir) 1073 } 1074 1075 // SetWalFile sets the path to the write-ahead log file 1076 func (cfg *ConsensusConfig) SetWalFile(walFile string) { 1077 cfg.walFile = walFile 1078 } 1079 1080 // ValidateBasic performs basic validation (checking param bounds, etc.) and 1081 // returns an error if any check fails. 1082 func (cfg *ConsensusConfig) ValidateBasic() error { 1083 if cfg.TimeoutPropose < 0 { 1084 return errors.New("timeout_propose can't be negative") 1085 } 1086 if cfg.TimeoutProposeDelta < 0 { 1087 return errors.New("timeout_propose_delta can't be negative") 1088 } 1089 if cfg.TimeoutPrevote < 0 { 1090 return errors.New("timeout_prevote can't be negative") 1091 } 1092 if cfg.TimeoutPrevoteDelta < 0 { 1093 return errors.New("timeout_prevote_delta can't be negative") 1094 } 1095 if cfg.TimeoutPrecommit < 0 { 1096 return errors.New("timeout_precommit can't be negative") 1097 } 1098 if cfg.TimeoutPrecommitDelta < 0 { 1099 return errors.New("timeout_precommit_delta can't be negative") 1100 } 1101 if cfg.TimeoutCommit < 0 { 1102 return errors.New("timeout_commit can't be negative") 1103 } 1104 if cfg.CreateEmptyBlocksInterval < 0 { 1105 return errors.New("create_empty_blocks_interval can't be negative") 1106 } 1107 if cfg.PeerGossipSleepDuration < 0 { 1108 return errors.New("peer_gossip_sleep_duration can't be negative") 1109 } 1110 if cfg.PeerQueryMaj23SleepDuration < 0 { 1111 return errors.New("peer_query_maj23_sleep_duration can't be negative") 1112 } 1113 if cfg.DoubleSignCheckHeight < 0 { 1114 return errors.New("double_sign_check_height can't be negative") 1115 } 1116 return nil 1117 } 1118 1119 //----------------------------------------------------------------------------- 1120 // StorageConfig 1121 1122 // StorageConfig allows more fine-grained control over certain storage-related 1123 // behavior. 1124 type StorageConfig struct { 1125 // Set to false to ensure ABCI responses are persisted. ABCI responses are 1126 // required for `/block_results` RPC queries, and to reindex events in the 1127 // command-line tool. 1128 DiscardABCIResponses bool `mapstructure:"discard_abci_responses"` 1129 } 1130 1131 // DefaultStorageConfig returns the default configuration options relating to 1132 // CometBFT storage optimization. 1133 func DefaultStorageConfig() *StorageConfig { 1134 return &StorageConfig{ 1135 DiscardABCIResponses: false, 1136 } 1137 } 1138 1139 // TestStorageConfig returns storage configuration that can be used for 1140 // testing. 1141 func TestStorageConfig() *StorageConfig { 1142 return &StorageConfig{ 1143 DiscardABCIResponses: false, 1144 } 1145 } 1146 1147 // ----------------------------------------------------------------------------- 1148 // TxIndexConfig 1149 // Remember that Event has the following structure: 1150 // type: [ 1151 // 1152 // key: value, 1153 // ... 1154 // 1155 // ] 1156 // 1157 // CompositeKeys are constructed by `type.key` 1158 // TxIndexConfig defines the configuration for the transaction indexer, 1159 // including composite keys to index. 1160 type TxIndexConfig struct { 1161 // What indexer to use for transactions 1162 // 1163 // Options: 1164 // 1) "null" 1165 // 2) "kv" (default) - the simplest possible indexer, 1166 // backed by key-value storage (defaults to levelDB; see DBBackend). 1167 // 3) "psql" - the indexer services backed by PostgreSQL. 1168 Indexer string `mapstructure:"indexer"` 1169 1170 // The PostgreSQL connection configuration, the connection format: 1171 // postgresql://<user>:<password>@<host>:<port>/<db>?<opts> 1172 PsqlConn string `mapstructure:"psql-conn"` 1173 } 1174 1175 // DefaultTxIndexConfig returns a default configuration for the transaction indexer. 1176 func DefaultTxIndexConfig() *TxIndexConfig { 1177 return &TxIndexConfig{ 1178 Indexer: "kv", 1179 } 1180 } 1181 1182 // TestTxIndexConfig returns a default configuration for the transaction indexer. 1183 func TestTxIndexConfig() *TxIndexConfig { 1184 return DefaultTxIndexConfig() 1185 } 1186 1187 //----------------------------------------------------------------------------- 1188 // InstrumentationConfig 1189 1190 // InstrumentationConfig defines the configuration for metrics reporting. 1191 type InstrumentationConfig struct { 1192 // When true, Prometheus metrics are served under /metrics on 1193 // PrometheusListenAddr. 1194 // Check out the documentation for the list of available metrics. 1195 Prometheus bool `mapstructure:"prometheus"` 1196 1197 // Address to listen for Prometheus collector(s) connections. 1198 PrometheusListenAddr string `mapstructure:"prometheus_listen_addr"` 1199 1200 // Maximum number of simultaneous connections. 1201 // If you want to accept a larger number than the default, make sure 1202 // you increase your OS limits. 1203 // 0 - unlimited. 1204 MaxOpenConnections int `mapstructure:"max_open_connections"` 1205 1206 // Instrumentation namespace. 1207 Namespace string `mapstructure:"namespace"` 1208 } 1209 1210 // DefaultInstrumentationConfig returns a default configuration for metrics 1211 // reporting. 1212 func DefaultInstrumentationConfig() *InstrumentationConfig { 1213 return &InstrumentationConfig{ 1214 Prometheus: false, 1215 PrometheusListenAddr: ":26660", 1216 MaxOpenConnections: 3, 1217 Namespace: "cometbft", 1218 } 1219 } 1220 1221 // TestInstrumentationConfig returns a default configuration for metrics 1222 // reporting. 1223 func TestInstrumentationConfig() *InstrumentationConfig { 1224 return DefaultInstrumentationConfig() 1225 } 1226 1227 // ValidateBasic performs basic validation (checking param bounds, etc.) and 1228 // returns an error if any check fails. 1229 func (cfg *InstrumentationConfig) ValidateBasic() error { 1230 if cfg.MaxOpenConnections < 0 { 1231 return errors.New("max_open_connections can't be negative") 1232 } 1233 return nil 1234 } 1235 1236 func (cfg *InstrumentationConfig) IsPrometheusEnabled() bool { 1237 return cfg.Prometheus && cfg.PrometheusListenAddr != "" 1238 } 1239 1240 //----------------------------------------------------------------------------- 1241 // Utils 1242 1243 // helper function to make config creation independent of root dir 1244 func rootify(path, root string) string { 1245 if filepath.IsAbs(path) { 1246 return path 1247 } 1248 return filepath.Join(root, path) 1249 } 1250 1251 //----------------------------------------------------------------------------- 1252 // Moniker 1253 1254 var defaultMoniker = getDefaultMoniker() 1255 1256 // getDefaultMoniker returns a default moniker, which is the host name. If runtime 1257 // fails to get the host name, "anonymous" will be returned. 1258 func getDefaultMoniker() string { 1259 moniker, err := os.Hostname() 1260 if err != nil { 1261 moniker = "anonymous" 1262 } 1263 return moniker 1264 }