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 }