github.com/Finschia/finschia-sdk@v0.48.1/server/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"strings"
     7  
     8  	"github.com/spf13/viper"
     9  
    10  	"github.com/Finschia/finschia-sdk/store/cache"
    11  	"github.com/Finschia/finschia-sdk/store/iavl"
    12  
    13  	storetypes "github.com/Finschia/finschia-sdk/store/types"
    14  	"github.com/Finschia/finschia-sdk/telemetry"
    15  	sdk "github.com/Finschia/finschia-sdk/types"
    16  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    17  )
    18  
    19  const (
    20  	defaultMinGasPrices = ""
    21  
    22  	// DefaultGRPCAddress defines the default address to bind the gRPC server to.
    23  	DefaultGRPCAddress = "0.0.0.0:9090"
    24  
    25  	// DefaultGRPCWebAddress defines the default address to bind the gRPC-web server to.
    26  	DefaultGRPCWebAddress = "0.0.0.0:9091"
    27  
    28  	// DefaultChanCheckTxSize defines the default size of channel check tx in Baseapp
    29  	DefaultChanCheckTxSize = 10000
    30  
    31  	// DefaultGRPCMaxRecvMsgSize defines the default gRPC max message size in
    32  	// bytes the server can receive.
    33  	DefaultGRPCMaxRecvMsgSize = 1024 * 1024 * 10
    34  
    35  	// DefaultGRPCMaxSendMsgSize defines the default gRPC max message size in
    36  	// bytes the server can send.
    37  	DefaultGRPCMaxSendMsgSize = math.MaxInt32
    38  )
    39  
    40  // BaseConfig defines the server's basic configuration
    41  type BaseConfig struct {
    42  	// The minimum gas prices a validator is willing to accept for processing a
    43  	// transaction. A transaction's fees must meet the minimum of any denomination
    44  	// specified in this config (e.g. 0.25token1;0.0001token2).
    45  	MinGasPrices string `mapstructure:"minimum-gas-prices"`
    46  
    47  	Pruning           string `mapstructure:"pruning"`
    48  	PruningKeepRecent string `mapstructure:"pruning-keep-recent"`
    49  	PruningKeepEvery  string `mapstructure:"pruning-keep-every"`
    50  	PruningInterval   string `mapstructure:"pruning-interval"`
    51  
    52  	// HaltHeight contains a non-zero block height at which a node will gracefully
    53  	// halt and shutdown that can be used to assist upgrades and testing.
    54  	//
    55  	// Note: Commitment of state will be attempted on the corresponding block.
    56  	HaltHeight uint64 `mapstructure:"halt-height"`
    57  
    58  	// HaltTime contains a non-zero minimum block time (in Unix seconds) at which
    59  	// a node will gracefully halt and shutdown that can be used to assist
    60  	// upgrades and testing.
    61  	//
    62  	// Note: Commitment of state will be attempted on the corresponding block.
    63  	HaltTime uint64 `mapstructure:"halt-time"`
    64  
    65  	// MinRetainBlocks defines the minimum block height offset from the current
    66  	// block being committed, such that blocks past this offset may be pruned
    67  	// from Tendermint. It is used as part of the process of determining the
    68  	// ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates
    69  	// that no blocks should be pruned.
    70  	//
    71  	// This configuration value is only responsible for pruning Tendermint blocks.
    72  	// It has no bearing on application state pruning which is determined by the
    73  	// "pruning-*" configurations.
    74  	//
    75  	// Note: Tendermint block pruning is dependant on this parameter in conunction
    76  	// with the unbonding (safety threshold) period, state pruning and state sync
    77  	// snapshot parameters to determine the correct minimum value of
    78  	// ResponseCommit.RetainHeight.
    79  	MinRetainBlocks uint64 `mapstructure:"min-retain-blocks"`
    80  
    81  	// InterBlockCache enables inter-block caching.
    82  	InterBlockCache bool `mapstructure:"inter-block-cache"`
    83  
    84  	// IndexEvents defines the set of events in the form {eventType}.{attributeKey},
    85  	// which informs Tendermint what to index. If empty, all events will be indexed.
    86  	IndexEvents []string `mapstructure:"index-events"`
    87  
    88  	// Interblock cache size; bytes size unit
    89  	InterBlockCacheSize int `mapstructure:"inter-block-cache-size"`
    90  
    91  	// IAVL cache size; bytes size unit
    92  	IAVLCacheSize uint64 `mapstructure:"iavl-cache-size"`
    93  
    94  	// IAVLDisableFastNode enables or disables the fast sync node.
    95  	IAVLDisableFastNode bool `mapstructure:"iavl-disable-fastnode"`
    96  
    97  	// When true, Prometheus metrics are served under /metrics on prometheus_listen_addr in config.toml.
    98  	// It works when tendermint's prometheus option (config.toml) is set to true.
    99  	Prometheus bool `mapstructure:"prometheus"`
   100  
   101  	// ChanCheckTxSize is the size of RequestCheckTxAsync of BaseApp
   102  	ChanCheckTxSize uint `mapstructure:"chan-check-tx-size"`
   103  }
   104  
   105  // APIConfig defines the API listener configuration.
   106  type APIConfig struct {
   107  	// Enable defines if the API server should be enabled.
   108  	Enable bool `mapstructure:"enable"`
   109  
   110  	// Swagger defines if swagger documentation should automatically be registered.
   111  	Swagger bool `mapstructure:"swagger"`
   112  
   113  	// EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk)
   114  	EnableUnsafeCORS bool `mapstructure:"enabled-unsafe-cors"`
   115  
   116  	// Address defines the API server to listen on
   117  	Address string `mapstructure:"address"`
   118  
   119  	// MaxOpenConnections defines the number of maximum open connections
   120  	MaxOpenConnections uint `mapstructure:"max-open-connections"`
   121  
   122  	// RPCReadTimeout defines the Ostracon RPC read timeout (in seconds)
   123  	RPCReadTimeout uint `mapstructure:"rpc-read-timeout"`
   124  
   125  	// RPCWriteTimeout defines the Ostracon RPC write timeout (in seconds)
   126  	RPCWriteTimeout uint `mapstructure:"rpc-write-timeout"`
   127  
   128  	// RPCIdleTimeout defines the Ostracon RPC idle timeout (in seconds)
   129  	RPCIdleTimeout uint `mapstructure:"rpc-idle-timeout"`
   130  
   131  	// RPCMaxBodyBytes defines the Ostracon maximum response body (in bytes)
   132  	RPCMaxBodyBytes uint `mapstructure:"rpc-max-body-bytes"`
   133  
   134  	// TODO: TLS/Proxy configuration.
   135  	//
   136  	// Ref: https://github.com/cosmos/cosmos-sdk/issues/6420
   137  }
   138  
   139  // RosettaConfig defines the Rosetta API listener configuration.
   140  type RosettaConfig struct {
   141  	// Address defines the API server to listen on
   142  	Address string `mapstructure:"address"`
   143  
   144  	// Blockchain defines the blockchain name
   145  	// defaults to DefaultBlockchain
   146  	Blockchain string `mapstructure:"blockchain"`
   147  
   148  	// Network defines the network name
   149  	Network string `mapstructure:"network"`
   150  
   151  	// Retries defines the maximum number of retries
   152  	// rosetta will do before quitting
   153  	Retries int `mapstructure:"retries"`
   154  
   155  	// Enable defines if the API server should be enabled.
   156  	Enable bool `mapstructure:"enable"`
   157  
   158  	// Offline defines if the server must be run in offline mode
   159  	Offline bool `mapstructure:"offline"`
   160  }
   161  
   162  // GRPCConfig defines configuration for the gRPC server.
   163  type GRPCConfig struct {
   164  	// Enable defines if the gRPC server should be enabled.
   165  	Enable bool `mapstructure:"enable"`
   166  
   167  	// Address defines the API server to listen on
   168  	Address string `mapstructure:"address"`
   169  
   170  	// MaxRecvMsgSize defines the max message size in bytes the server can receive.
   171  	// The default value is 10MB.
   172  	MaxRecvMsgSize int `mapstructure:"max-recv-msg-size"`
   173  
   174  	// MaxSendMsgSize defines the max message size in bytes the server can send.
   175  	// The default value is math.MaxInt32.
   176  	MaxSendMsgSize int `mapstructure:"max-send-msg-size"`
   177  }
   178  
   179  // GRPCWebConfig defines configuration for the gRPC-web server.
   180  type GRPCWebConfig struct {
   181  	// Enable defines if the gRPC-web should be enabled.
   182  	Enable bool `mapstructure:"enable"`
   183  
   184  	// Address defines the gRPC-web server to listen on
   185  	Address string `mapstructure:"address"`
   186  
   187  	// EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk)
   188  	EnableUnsafeCORS bool `mapstructure:"enable-unsafe-cors"`
   189  }
   190  
   191  // StateSyncConfig defines the state sync snapshot configuration.
   192  type StateSyncConfig struct {
   193  	// SnapshotInterval sets the interval at which state sync snapshots are taken.
   194  	// 0 disables snapshots. Must be a multiple of PruningKeepEvery.
   195  	SnapshotInterval uint64 `mapstructure:"snapshot-interval"`
   196  
   197  	// SnapshotKeepRecent sets the number of recent state sync snapshots to keep.
   198  	// 0 keeps all snapshots.
   199  	SnapshotKeepRecent uint32 `mapstructure:"snapshot-keep-recent"`
   200  }
   201  
   202  // Config defines the server's top level configuration
   203  type Config struct {
   204  	BaseConfig `mapstructure:",squash"`
   205  
   206  	// Telemetry defines the application telemetry configuration
   207  	Telemetry telemetry.Config `mapstructure:"telemetry"`
   208  	API       APIConfig        `mapstructure:"api"`
   209  	GRPC      GRPCConfig       `mapstructure:"grpc"`
   210  	Rosetta   RosettaConfig    `mapstructure:"rosetta"`
   211  	GRPCWeb   GRPCWebConfig    `mapstructure:"grpc-web"`
   212  	StateSync StateSyncConfig  `mapstructure:"state-sync"`
   213  }
   214  
   215  // SetMinGasPrices sets the validator's minimum gas prices.
   216  func (c *Config) SetMinGasPrices(gasPrices sdk.DecCoins) {
   217  	c.MinGasPrices = gasPrices.String()
   218  }
   219  
   220  // GetMinGasPrices returns the validator's minimum gas prices based on the set
   221  // configuration.
   222  func (c *Config) GetMinGasPrices() sdk.DecCoins {
   223  	if c.MinGasPrices == "" {
   224  		return sdk.DecCoins{}
   225  	}
   226  
   227  	gasPricesStr := strings.Split(c.MinGasPrices, ";")
   228  	gasPrices := make(sdk.DecCoins, len(gasPricesStr))
   229  
   230  	for i, s := range gasPricesStr {
   231  		gasPrice, err := sdk.ParseDecCoin(s)
   232  		if err != nil {
   233  			panic(fmt.Errorf("failed to parse minimum gas price coin (%s): %s", s, err))
   234  		}
   235  
   236  		gasPrices[i] = gasPrice
   237  	}
   238  
   239  	return gasPrices
   240  }
   241  
   242  // DefaultConfig returns server's default configuration.
   243  func DefaultConfig() *Config {
   244  	return &Config{
   245  		BaseConfig: BaseConfig{
   246  			MinGasPrices:        defaultMinGasPrices,
   247  			InterBlockCache:     true,
   248  			Pruning:             storetypes.PruningOptionDefault,
   249  			PruningKeepRecent:   "0",
   250  			PruningKeepEvery:    "0",
   251  			PruningInterval:     "0",
   252  			MinRetainBlocks:     0,
   253  			IndexEvents:         make([]string, 0),
   254  			InterBlockCacheSize: cache.DefaultCommitKVStoreCacheSize,
   255  			IAVLCacheSize:       iavl.DefaultIAVLCacheSize,
   256  			IAVLDisableFastNode: true,
   257  			ChanCheckTxSize:     DefaultChanCheckTxSize,
   258  		},
   259  		Telemetry: telemetry.Config{
   260  			Enabled:      false,
   261  			GlobalLabels: [][]string{},
   262  		},
   263  		API: APIConfig{
   264  			Enable:             false,
   265  			Swagger:            false,
   266  			Address:            "tcp://0.0.0.0:1317",
   267  			MaxOpenConnections: 1000,
   268  			RPCReadTimeout:     10,
   269  			RPCWriteTimeout:    10,
   270  			RPCIdleTimeout:     60,
   271  			RPCMaxBodyBytes:    1000000,
   272  		},
   273  		GRPC: GRPCConfig{
   274  			Enable:         true,
   275  			Address:        DefaultGRPCAddress,
   276  			MaxRecvMsgSize: DefaultGRPCMaxRecvMsgSize,
   277  			MaxSendMsgSize: DefaultGRPCMaxSendMsgSize,
   278  		},
   279  		Rosetta: RosettaConfig{
   280  			Enable:     false,
   281  			Address:    ":8080",
   282  			Blockchain: "app",
   283  			Network:    "network",
   284  			Retries:    3,
   285  			Offline:    false,
   286  		},
   287  		GRPCWeb: GRPCWebConfig{
   288  			Enable:  true,
   289  			Address: DefaultGRPCWebAddress,
   290  		},
   291  		StateSync: StateSyncConfig{
   292  			SnapshotInterval:   0,
   293  			SnapshotKeepRecent: 2,
   294  		},
   295  	}
   296  }
   297  
   298  // GetConfig returns a fully parsed Config object.
   299  func GetConfig(v *viper.Viper) (Config, error) {
   300  	globalLabelsRaw, ok := v.Get("telemetry.global-labels").([]interface{})
   301  	if !ok {
   302  		return Config{}, fmt.Errorf("failed to parse global-labels config")
   303  	}
   304  
   305  	globalLabels := make([][]string, 0, len(globalLabelsRaw))
   306  	for idx, glr := range globalLabelsRaw {
   307  		labelsRaw, ok := glr.([]interface{})
   308  		if !ok {
   309  			return Config{}, fmt.Errorf("failed to parse global label number %d from config", idx)
   310  		}
   311  		if len(labelsRaw) == 2 {
   312  			globalLabels = append(globalLabels, []string{labelsRaw[0].(string), labelsRaw[1].(string)})
   313  		}
   314  	}
   315  
   316  	return Config{
   317  		BaseConfig: BaseConfig{
   318  			MinGasPrices:        v.GetString("minimum-gas-prices"),
   319  			InterBlockCache:     v.GetBool("inter-block-cache"),
   320  			Pruning:             v.GetString("pruning"),
   321  			PruningKeepRecent:   v.GetString("pruning-keep-recent"),
   322  			PruningKeepEvery:    v.GetString("pruning-keep-every"),
   323  			PruningInterval:     v.GetString("pruning-interval"),
   324  			HaltHeight:          v.GetUint64("halt-height"),
   325  			HaltTime:            v.GetUint64("halt-time"),
   326  			IndexEvents:         v.GetStringSlice("index-events"),
   327  			MinRetainBlocks:     v.GetUint64("min-retain-blocks"),
   328  			IAVLDisableFastNode: v.GetBool("iavl-disable-fastnode"),
   329  			IAVLCacheSize:       v.GetUint64("iavl-cache-size"),
   330  			ChanCheckTxSize:     v.GetUint("chan-check-tx-size"),
   331  		},
   332  		Telemetry: telemetry.Config{
   333  			ServiceName:             v.GetString("telemetry.service-name"),
   334  			Enabled:                 v.GetBool("telemetry.enabled"),
   335  			EnableHostname:          v.GetBool("telemetry.enable-hostname"),
   336  			EnableHostnameLabel:     v.GetBool("telemetry.enable-hostname-label"),
   337  			EnableServiceLabel:      v.GetBool("telemetry.enable-service-label"),
   338  			PrometheusRetentionTime: v.GetInt64("telemetry.prometheus-retention-time"),
   339  			GlobalLabels:            globalLabels,
   340  		},
   341  		API: APIConfig{
   342  			Enable:             v.GetBool("api.enable"),
   343  			Swagger:            v.GetBool("api.swagger"),
   344  			Address:            v.GetString("api.address"),
   345  			MaxOpenConnections: v.GetUint("api.max-open-connections"),
   346  			RPCReadTimeout:     v.GetUint("api.rpc-read-timeout"),
   347  			RPCWriteTimeout:    v.GetUint("api.rpc-write-timeout"),
   348  			RPCIdleTimeout:     v.GetUint("api.rpc-idle-timeout"),
   349  			RPCMaxBodyBytes:    v.GetUint("api.rpc-max-body-bytes"),
   350  			EnableUnsafeCORS:   v.GetBool("api.enabled-unsafe-cors"),
   351  		},
   352  		Rosetta: RosettaConfig{
   353  			Enable:     v.GetBool("rosetta.enable"),
   354  			Address:    v.GetString("rosetta.address"),
   355  			Blockchain: v.GetString("rosetta.blockchain"),
   356  			Network:    v.GetString("rosetta.network"),
   357  			Retries:    v.GetInt("rosetta.retries"),
   358  			Offline:    v.GetBool("rosetta.offline"),
   359  		},
   360  		GRPC: GRPCConfig{
   361  			Enable:         v.GetBool("grpc.enable"),
   362  			Address:        v.GetString("grpc.address"),
   363  			MaxRecvMsgSize: v.GetInt("grpc.max-recv-msg-size"),
   364  			MaxSendMsgSize: v.GetInt("grpc.max-send-msg-size"),
   365  		},
   366  		GRPCWeb: GRPCWebConfig{
   367  			Enable:           v.GetBool("grpc-web.enable"),
   368  			Address:          v.GetString("grpc-web.address"),
   369  			EnableUnsafeCORS: v.GetBool("grpc-web.enable-unsafe-cors"),
   370  		},
   371  		StateSync: StateSyncConfig{
   372  			SnapshotInterval:   v.GetUint64("state-sync.snapshot-interval"),
   373  			SnapshotKeepRecent: v.GetUint32("state-sync.snapshot-keep-recent"),
   374  		},
   375  	}, nil
   376  }
   377  
   378  // ValidateBasic returns an error if min-gas-prices field is empty in BaseConfig. Otherwise, it returns nil.
   379  func (c Config) ValidateBasic() error {
   380  	if c.BaseConfig.MinGasPrices == "" {
   381  		return sdkerrors.ErrAppConfig.Wrap("set min gas price in app.toml or flag or env variable")
   382  	}
   383  	if c.Pruning == storetypes.PruningOptionEverything && c.StateSync.SnapshotInterval > 0 {
   384  		return sdkerrors.ErrAppConfig.Wrapf(
   385  			"cannot enable state sync snapshots with '%s' pruning setting", storetypes.PruningOptionEverything,
   386  		)
   387  	}
   388  
   389  	return nil
   390  }