github.com/vipernet-xyz/tendermint-core@v0.32.0/config/config.go (about)

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