github.com/516108736/tendermint@v0.36.0/config/config.go (about)

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