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