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