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