Skip to content

Commit

Permalink
feat: refactor consumers config (#55)
Browse files Browse the repository at this point in the history
* feat: refactor consumers config

* chore: refactor balances fetcher

* chore: refactor node_info fetcher

* chore: refactor node_signing_info fetcher

* chore: refactor slashing_params fetcher

* chore: validate fix

* chore: allow disabling queries
  • Loading branch information
freak12techno authored Jun 16, 2024
1 parent ec959b4 commit e384ec1
Show file tree
Hide file tree
Showing 29 changed files with 802 additions and 421 deletions.
12 changes: 1 addition & 11 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,11 @@ linters:
enable-all: true
disable:
- funlen
- scopelint
- interfacer
- exhaustivestruct
- maligned
- golint
- nlreturn
- wrapcheck
- gomnd
- cyclop
- goerr113
- err113
- exhaustruct
- wsl
- lll
Expand All @@ -44,14 +39,9 @@ linters:
- stylecheck
- gosimple
- ireturn
- nosnakecase
- ifshort
- gci
- promlinter
- gocyclo
- maintidx
- deadcode
- depguard
- structcheck
- varcheck
- mnd
6 changes: 3 additions & 3 deletions pkg/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type App struct {
Config *config.Config
Logger *zerolog.Logger

RPCs map[string]*tendermint.RPC
RPCs map[string]*tendermint.RPCWithConsumers

// Fetcher is a class that fetch data and is later stored in state.
// It doesn't provide any metrics, only data to generate them later.
Expand Down Expand Up @@ -66,10 +66,10 @@ func NewApp(configPath string, version string) *App {
coingecko := coingeckoPkg.NewCoingecko(appConfig, logger, tracer)
dexScreener := dexScreenerPkg.NewDexScreener(logger)

rpcs := make(map[string]*tendermint.RPC, len(appConfig.Chains))
rpcs := make(map[string]*tendermint.RPCWithConsumers, len(appConfig.Chains))

for _, chain := range appConfig.Chains {
rpcs[chain.Name] = tendermint.NewRPC(chain, appConfig.Timeout, *logger, tracer)
rpcs[chain.Name] = tendermint.RPCWithConsumersFromChain(chain, appConfig.Timeout, *logger, tracer)
}

fetchers := []fetchersPkg.Fetcher{
Expand Down
78 changes: 78 additions & 0 deletions pkg/config/chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package config

import (
"errors"
"fmt"

"github.com/rs/zerolog"
)

type Chain struct {
Name string `toml:"name"`
LCDEndpoint string `toml:"lcd-endpoint"`
BaseDenom string `toml:"base-denom"`
Denoms DenomInfos `toml:"denoms"`
BechWalletPrefix string `toml:"bech-wallet-prefix"`
Validators []Validator `toml:"validators"`
Queries Queries `toml:"queries"`

ConsumerChains []*ConsumerChain `toml:"consumers"`
}

func (c *Chain) GetQueries() Queries {
return c.Queries
}

func (c *Chain) GetHost() string {
return c.LCDEndpoint
}

func (c *Chain) GetName() string {
return c.Name
}

func (c *Chain) Validate() error {
if c.Name == "" {
return errors.New("empty chain name")
}

if c.LCDEndpoint == "" {
return errors.New("no LCD endpoint provided")
}

if len(c.Validators) == 0 {
return errors.New("no validators provided")
}

for index, validator := range c.Validators {
if err := validator.Validate(); err != nil {
return fmt.Errorf("error in validator #%d: %s", index, err)
}
}

for index, denomInfo := range c.Denoms {
if err := denomInfo.Validate(); err != nil {
return fmt.Errorf("error in denom #%d: %s", index, err)
}
}

for index, chain := range c.ConsumerChains {
if err := chain.Validate(); err != nil {
return fmt.Errorf("error in consumer chain #%d: %s", index, err)
}
}

return nil
}

func (c *Chain) DisplayWarnings(logger *zerolog.Logger) {
if c.BaseDenom == "" {
logger.Warn().
Str("chain", c.Name).
Msg("Base denom is not set")
}

for _, denom := range c.Denoms {
denom.DisplayWarnings(c, logger)
}
}
7 changes: 7 additions & 0 deletions pkg/config/chain_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package config

type ChainInfo interface {
GetQueries() Queries
GetHost() string
GetName() string
}
127 changes: 2 additions & 125 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/BurntSushi/toml"
"github.com/creasty/defaults"
"github.com/guregu/null/v5"
)

type Validator struct {
Expand All @@ -25,141 +24,19 @@ func (v *Validator) Validate() error {
return nil
}

type DenomInfo struct {
Denom string `toml:"denom"`
DenomCoefficient int64 `default:"1000000" toml:"denom-coefficient"`
DisplayDenom string `toml:"display-denom"`
CoingeckoCurrency string `toml:"coingecko-currency"`
DexScreenerChainID string `toml:"dex-screener-chain-id"`
DexScreenerPair string `toml:"dex-screener-pair"`
}

func (d *DenomInfo) Validate() error {
if d.Denom == "" {
return errors.New("empty denom name")
}

if d.Denom == "" {
return errors.New("empty display denom name")
}

return nil
}

func (d *DenomInfo) DisplayWarnings(chain *Chain, logger *zerolog.Logger) {
if d.CoingeckoCurrency == "" && (d.DexScreenerPair == "" || d.DexScreenerChainID == "") {
logger.Warn().
Str("chain", chain.Name).
Str("denom", d.Denom).
Msg("Currency code not set, not fetching exchange rate.")
}
}

type DenomInfos []*DenomInfo

func (d DenomInfos) Find(denom string) *DenomInfo {
for _, info := range d {
if denom == info.Denom {
return info
}
}

return nil
}

type Chain struct {
Name string `toml:"name"`
LCDEndpoint string `toml:"lcd-endpoint"`
BaseDenom string `toml:"base-denom"`
Denoms DenomInfos `toml:"denoms"`
BechWalletPrefix string `toml:"bech-wallet-prefix"`
Validators []Validator `toml:"validators"`
Queries map[string]bool `toml:"queries"`

ProviderChainLCD string `toml:"provider-lcd-endpoint"`
}

func (c *Chain) IsConsumer() bool {
return c.ProviderChainLCD != ""
}

func (c *Chain) Validate() error {
if c.Name == "" {
return errors.New("empty chain name")
}

if c.LCDEndpoint == "" {
return errors.New("no LCD endpoint provided")
}

if len(c.Validators) == 0 {
return errors.New("no validators provided")
}

for index, validator := range c.Validators {
if err := validator.Validate(); err != nil {
return fmt.Errorf("error in validator #%d: %s", index, err)
}
}

for index, denomInfo := range c.Denoms {
if err := denomInfo.Validate(); err != nil {
return fmt.Errorf("error in denom #%d: %s", index, err)
}
}

return nil
}

func (c *Chain) DisplayWarnings(logger *zerolog.Logger) {
if c.BaseDenom == "" {
logger.Warn().
Str("chain", c.Name).
Msg("Base denom is not set")
}

for _, denom := range c.Denoms {
denom.DisplayWarnings(c, logger)
}
}

func (c *Chain) QueryEnabled(query string) bool {
if value, ok := c.Queries[query]; !ok {
return true // all queries are enabled by default
} else {
return value
}
}

type Config struct {
LogConfig LogConfig `toml:"log"`
TracingConfig TracingConfig `toml:"tracing"`
ListenAddress string `default:":9550" toml:"listen-address"`
ListenAddress string `default:":9560" toml:"listen-address"`
Timeout int `default:"10" toml:"timeout"`
Chains []Chain `toml:"chains"`
Chains []*Chain `toml:"chains"`
}

type LogConfig struct {
LogLevel string `default:"info" toml:"level"`
JSONOutput bool `default:"false" toml:"json"`
}

type TracingConfig struct {
Enabled null.Bool `default:"false" toml:"enabled"`
OpenTelemetryHTTPHost string `toml:"open-telemetry-http-host"`
OpenTelemetryHTTPInsecure null.Bool `default:"true" toml:"open-telemetry-http-insecure"`
OpenTelemetryHTTPUser string `toml:"open-telemetry-http-user"`
OpenTelemetryHTTPPassword string `toml:"open-telemetry-http-password"`
}

func (c *TracingConfig) Validate() error {
if c.Enabled.Bool && c.OpenTelemetryHTTPHost == "" {
return errors.New("tracing is enabled, but open-telemetry-http-host is not provided")
}

return nil
}

func (c *Config) Validate() error {
if err := c.TracingConfig.Validate(); err != nil {
return fmt.Errorf("error in tracing config: %s", err)
Expand Down
52 changes: 52 additions & 0 deletions pkg/config/consumer_chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package config

import (
"errors"
"fmt"
)

type ConsumerChain struct {
Name string `toml:"name"`
LCDEndpoint string `toml:"lcd-endpoint"`
BaseDenom string `toml:"base-denom"`
Denoms DenomInfos `toml:"denoms"`
ChainID string `toml:"chain-id"`
BechWalletPrefix string `toml:"bech-wallet-prefix"`
BechValidatorPrefix string `toml:"bech-validator-prefix"`
BechConsensusPrefix string `toml:"bech-consensus-prefix"`
Queries Queries `toml:"queries"`
}

func (c *ConsumerChain) GetQueries() Queries {
return c.Queries
}

func (c *ConsumerChain) GetHost() string {
return c.LCDEndpoint
}

func (c *ConsumerChain) GetName() string {
return c.Name
}

func (c *ConsumerChain) Validate() error {
if c.Name == "" {
return errors.New("empty chain name")
}

if c.LCDEndpoint == "" {
return errors.New("no LCD endpoint provided")
}

if c.ChainID == "" {
return errors.New("no chain-id provided")
}

for index, denomInfo := range c.Denoms {
if err := denomInfo.Validate(); err != nil {
return fmt.Errorf("error in denom #%d: %s", index, err)
}
}

return nil
}
49 changes: 49 additions & 0 deletions pkg/config/denom_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package config

import (
"errors"

"github.com/rs/zerolog"
)

type DenomInfo struct {
Denom string `toml:"denom"`
DenomCoefficient int64 `default:"1000000" toml:"denom-coefficient"`
DisplayDenom string `toml:"display-denom"`
CoingeckoCurrency string `toml:"coingecko-currency"`
DexScreenerChainID string `toml:"dex-screener-chain-id"`
DexScreenerPair string `toml:"dex-screener-pair"`
}

func (d *DenomInfo) Validate() error {
if d.Denom == "" {
return errors.New("empty denom name")
}

if d.DisplayDenom == "" {
return errors.New("empty display denom name")
}

return nil
}

func (d *DenomInfo) DisplayWarnings(chain *Chain, logger *zerolog.Logger) {
if d.CoingeckoCurrency == "" && (d.DexScreenerPair == "" || d.DexScreenerChainID == "") {
logger.Warn().
Str("chain", chain.Name).
Str("denom", d.Denom).
Msg("Currency code not set, not fetching exchange rate.")
}
}

type DenomInfos []*DenomInfo

func (d DenomInfos) Find(denom string) *DenomInfo {
for _, info := range d {
if denom == info.Denom {
return info
}
}

return nil
}
Loading

0 comments on commit e384ec1

Please sign in to comment.