diff --git a/pkg/app.go b/pkg/app.go index 595d80b..642f521 100644 --- a/pkg/app.go +++ b/pkg/app.go @@ -77,7 +77,6 @@ func NewApp(configPath string, filesystem fs.FS, version string) *App { fetchers := []fetchersPkg.Fetcher{ fetchersPkg.NewSlashingParamsFetcher(logger, appConfig.Chains, rpcs, tracer), - fetchersPkg.NewSoftOptOutThresholdFetcher(logger, appConfig.Chains, rpcs, tracer), fetchersPkg.NewCommissionFetcher(logger, appConfig.Chains, rpcs, tracer), fetchersPkg.NewDelegationsFetcher(logger, appConfig.Chains, rpcs, tracer), fetchersPkg.NewUnbondsFetcher(logger, appConfig.Chains, rpcs, tracer), @@ -99,7 +98,6 @@ func NewApp(configPath string, filesystem fs.FS, version string) *App { generators := []generatorsPkg.Generator{ generatorsPkg.NewSlashingParamsGenerator(), - generatorsPkg.NewSoftOptOutThresholdGenerator(), generatorsPkg.NewIsConsumerGenerator(appConfig.Chains), generatorsPkg.NewUptimeGenerator(), generatorsPkg.NewCommissionGenerator(appConfig.Chains), diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index f822391..3e0b742 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -5,12 +5,11 @@ type FetcherName string type PriceFetcherName string const ( - FetcherNameSlashingParams FetcherName = "slashing-params" - FetcherNameSoftOptOutThreshold FetcherName = "soft-opt-out-threshold" - FetcherNameCommission FetcherName = "commission" - FetcherNameDelegations FetcherName = "delegations" - FetcherNameValidatorConsumers FetcherName = "validator-consumers" - FetcherNameConsumerCommission FetcherName = "consumer-commission" + FetcherNameSlashingParams FetcherName = "slashing-params" + FetcherNameCommission FetcherName = "commission" + FetcherNameDelegations FetcherName = "delegations" + FetcherNameValidatorConsumers FetcherName = "validator-consumers" + FetcherNameConsumerCommission FetcherName = "consumer-commission" FetcherNameUnbonds FetcherName = "unbonds" FetcherNameSigningInfo FetcherName = "signing-info" diff --git a/pkg/fetchers/soft_opt_out_threshold.go b/pkg/fetchers/soft_opt_out_threshold.go deleted file mode 100644 index 935ce72..0000000 --- a/pkg/fetchers/soft_opt_out_threshold.go +++ /dev/null @@ -1,92 +0,0 @@ -package fetchers - -import ( - "context" - "main/pkg/config" - "main/pkg/constants" - "main/pkg/tendermint" - "main/pkg/types" - "sync" - - "github.com/rs/zerolog" - "go.opentelemetry.io/otel/trace" -) - -type SoftOptOutThresholdFetcher struct { - Logger zerolog.Logger - Chains []*config.Chain - RPCs map[string]*tendermint.RPCWithConsumers - Tracer trace.Tracer -} - -type SoftOptOutThresholdData struct { - Thresholds map[string]float64 -} - -func NewSoftOptOutThresholdFetcher( - logger *zerolog.Logger, - chains []*config.Chain, - rpcs map[string]*tendermint.RPCWithConsumers, - tracer trace.Tracer, -) *SoftOptOutThresholdFetcher { - return &SoftOptOutThresholdFetcher{ - Logger: logger.With().Str("component", "soft_opt_out_threshold_fetcher").Logger(), - Chains: chains, - RPCs: rpcs, - Tracer: tracer, - } -} - -func (q *SoftOptOutThresholdFetcher) Fetch( - ctx context.Context, -) (interface{}, []*types.QueryInfo) { - var queryInfos []*types.QueryInfo - - allThresholds := map[string]float64{} - - var wg sync.WaitGroup - var mutex sync.Mutex - - for _, chain := range q.Chains { - rpc, _ := q.RPCs[chain.Name] - - for consumerIndex, consumerChain := range chain.ConsumerChains { - consumerRPC := rpc.Consumers[consumerIndex] - - wg.Add(1) - - go func(chain *config.ConsumerChain, rpc *tendermint.RPC) { - defer wg.Done() - - threshold, queried, query, err := rpc.GetConsumerSoftOutOutThreshold(ctx) - - mutex.Lock() - defer mutex.Unlock() - - if query != nil { - queryInfos = append(queryInfos, query) - } - - if err != nil { - q.Logger.Error(). - Err(err). - Str("chain", chain.Name). - Msg("Error querying soft opt-out threshold") - return - } - - if queried { - allThresholds[chain.Name] = threshold - } - }(consumerChain, consumerRPC) - } - } - - wg.Wait() - - return SoftOptOutThresholdData{Thresholds: allThresholds}, queryInfos -} - -func (q *SoftOptOutThresholdFetcher) Name() constants.FetcherName { - return constants.FetcherNameSoftOptOutThreshold -} diff --git a/pkg/fetchers/soft_opt_out_threshold_test.go b/pkg/fetchers/soft_opt_out_threshold_test.go deleted file mode 100644 index 189b3ed..0000000 --- a/pkg/fetchers/soft_opt_out_threshold_test.go +++ /dev/null @@ -1,280 +0,0 @@ -package fetchers - -import ( - "context" - "errors" - "main/assets" - "main/pkg/config" - "main/pkg/constants" - "main/pkg/logger" - "main/pkg/tendermint" - "main/pkg/tracing" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/jarcoal/httpmock" -) - -func TestSoftOptOutThresholdFetcherBase(t *testing.T) { - t.Parallel() - - chains := []*config.Chain{ - {Name: "chain1", LCDEndpoint: "example1"}, - {Name: "chain2", LCDEndpoint: "example2"}, - } - rpcs := map[string]*tendermint.RPCWithConsumers{ - "chain1": tendermint.RPCWithConsumersFromChain( - chains[0], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - "chain2": tendermint.RPCWithConsumersFromChain( - chains[1], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - } - fetcher := NewSoftOptOutThresholdFetcher( - logger.GetNopLogger(), - chains, - rpcs, - tracing.InitNoopTracer(), - ) - - assert.NotNil(t, fetcher) - assert.Equal(t, constants.FetcherNameSoftOptOutThreshold, fetcher.Name()) -} - -func TestSoftOptOutThresholdFetcherQueryDisabled(t *testing.T) { - t.Parallel() - - chains := []*config.Chain{{ - Name: "chain", - LCDEndpoint: "example", - BechWalletPrefix: "test", - Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, - ConsumerChains: []*config.ConsumerChain{ - { - Name: "consumer", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "neutron", - Queries: map[string]bool{"params": false}, - }, - }, - }} - rpcs := map[string]*tendermint.RPCWithConsumers{ - "chain": tendermint.RPCWithConsumersFromChain( - chains[0], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - } - fetcher := &SoftOptOutThresholdFetcher{ - Logger: *logger.GetNopLogger(), - Chains: chains, - RPCs: rpcs, - Tracer: tracing.InitNoopTracer(), - } - data, queries := fetcher.Fetch(context.Background()) - assert.Empty(t, queries) - - paramsData, ok := data.(SoftOptOutThresholdData) - assert.True(t, ok) - assert.Empty(t, paramsData.Thresholds) -} - -//nolint:paralleltest // disabled due to httpmock usage -func TestSoftOptOutThresholdFetcherQueryInvalidJson(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - - httpmock.RegisterResponder( - "GET", - "https://api.neutron.quokkastake.io/cosmos/params/v1beta1/params?subspace=ccvconsumer&key=SoftOptOutThreshold", - httpmock.NewBytesResponder(200, assets.GetBytesOrPanic("soft-opt-out-threshold-invalid.json")), - ) - - chains := []*config.Chain{{ - Name: "chain", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "cosmos", - Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, - ConsumerChains: []*config.ConsumerChain{ - { - Name: "consumer", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "neutron", - }, - }, - }} - rpcs := map[string]*tendermint.RPCWithConsumers{ - "chain": tendermint.RPCWithConsumersFromChain( - chains[0], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - } - fetcher := &SoftOptOutThresholdFetcher{ - Logger: *logger.GetNopLogger(), - Chains: chains, - RPCs: rpcs, - Tracer: tracing.InitNoopTracer(), - } - data, queries := fetcher.Fetch(context.Background()) - assert.Len(t, queries, 1) - assert.False(t, queries[0].Success) - - paramsData, ok := data.(SoftOptOutThresholdData) - assert.True(t, ok) - assert.Empty(t, paramsData.Thresholds) -} - -//nolint:paralleltest // disabled due to httpmock usage -func TestSoftOptOutThresholdFetcherQueryError(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - - httpmock.RegisterResponder( - "GET", - "https://api.neutron.quokkastake.io/cosmos/params/v1beta1/params?subspace=ccvconsumer&key=SoftOptOutThreshold", - httpmock.NewErrorResponder(errors.New("error")), - ) - - chains := []*config.Chain{{ - Name: "chain", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "cosmos", - Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, - ConsumerChains: []*config.ConsumerChain{ - { - Name: "consumer", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "neutron", - }, - }, - }} - rpcs := map[string]*tendermint.RPCWithConsumers{ - "chain": tendermint.RPCWithConsumersFromChain( - chains[0], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - } - fetcher := &SoftOptOutThresholdFetcher{ - Logger: *logger.GetNopLogger(), - Chains: chains, - RPCs: rpcs, - Tracer: tracing.InitNoopTracer(), - } - data, queries := fetcher.Fetch(context.Background()) - assert.Len(t, queries, 1) - assert.False(t, queries[0].Success) - - paramsData, ok := data.(SoftOptOutThresholdData) - assert.True(t, ok) - assert.Empty(t, paramsData.Thresholds) -} - -//nolint:paralleltest // disabled due to httpmock usage -func TestSoftOptOutThresholdFetcherNodeError(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - - httpmock.RegisterResponder( - "GET", - "https://api.neutron.quokkastake.io/cosmos/params/v1beta1/params?subspace=ccvconsumer&key=SoftOptOutThreshold", - httpmock.NewBytesResponder(200, assets.GetBytesOrPanic("error.json")), - ) - - chains := []*config.Chain{{ - Name: "chain", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "cosmos", - Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, - ConsumerChains: []*config.ConsumerChain{ - { - Name: "consumer", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "neutron", - }, - }, - }} - rpcs := map[string]*tendermint.RPCWithConsumers{ - "chain": tendermint.RPCWithConsumersFromChain( - chains[0], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - } - fetcher := &SoftOptOutThresholdFetcher{ - Logger: *logger.GetNopLogger(), - Chains: chains, - RPCs: rpcs, - Tracer: tracing.InitNoopTracer(), - } - data, queries := fetcher.Fetch(context.Background()) - assert.Len(t, queries, 1) - assert.False(t, queries[0].Success) - - paramsData, ok := data.(SoftOptOutThresholdData) - assert.True(t, ok) - assert.Empty(t, paramsData.Thresholds) -} - -//nolint:paralleltest // disabled due to httpmock usage -func TestSoftOptOutThresholdFetcherSuccess(t *testing.T) { - httpmock.Activate() - defer httpmock.DeactivateAndReset() - - httpmock.RegisterResponder( - "GET", - "https://api.neutron.quokkastake.io/cosmos/params/v1beta1/params?subspace=ccvconsumer&key=SoftOptOutThreshold", - httpmock.NewBytesResponder(200, assets.GetBytesOrPanic("soft-opt-out-threshold.json")), - ) - - chains := []*config.Chain{{ - Name: "chain", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "cosmos", - Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, - Queries: map[string]bool{"params": false}, - ConsumerChains: []*config.ConsumerChain{ - { - Name: "consumer", - LCDEndpoint: "https://api.neutron.quokkastake.io", - BechWalletPrefix: "neutron", - }, - }, - }} - rpcs := map[string]*tendermint.RPCWithConsumers{ - "chain": tendermint.RPCWithConsumersFromChain( - chains[0], - 10, - *logger.GetNopLogger(), - tracing.InitNoopTracer(), - ), - } - fetcher := &SoftOptOutThresholdFetcher{ - Logger: *logger.GetNopLogger(), - Chains: chains, - RPCs: rpcs, - Tracer: tracing.InitNoopTracer(), - } - data, queries := fetcher.Fetch(context.Background()) - assert.Len(t, queries, 1) - assert.True(t, queries[0].Success) - - paramsData, ok := data.(SoftOptOutThresholdData) - assert.True(t, ok) - - chainData, ok := paramsData.Thresholds["consumer"] - assert.True(t, ok) - assert.InEpsilon(t, 0.05, chainData, 0.01) -} diff --git a/pkg/generators/soft_opt_out_threshold.go b/pkg/generators/soft_opt_out_threshold.go deleted file mode 100644 index da8557f..0000000 --- a/pkg/generators/soft_opt_out_threshold.go +++ /dev/null @@ -1,41 +0,0 @@ -package generators - -import ( - "main/pkg/constants" - fetchersPkg "main/pkg/fetchers" - statePkg "main/pkg/state" - - "github.com/prometheus/client_golang/prometheus" -) - -type SoftOptOutThresholdGenerator struct { -} - -func NewSoftOptOutThresholdGenerator() *SoftOptOutThresholdGenerator { - return &SoftOptOutThresholdGenerator{} -} - -func (g *SoftOptOutThresholdGenerator) Generate(state *statePkg.State) []prometheus.Collector { - dataRaw, ok := state.Get(constants.FetcherNameSoftOptOutThreshold) - if !ok { - return []prometheus.Collector{} - } - - softOptOutThresholdGauge := prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: constants.MetricsPrefix + "soft_opt_out_threshold", - Help: "Consumer chain's soft opt-out threshold", - }, - []string{"chain"}, - ) - - data, _ := dataRaw.(fetchersPkg.SoftOptOutThresholdData) - - for chain, threshold := range data.Thresholds { - softOptOutThresholdGauge.With(prometheus.Labels{ - "chain": chain, - }).Set(threshold) - } - - return []prometheus.Collector{softOptOutThresholdGauge} -} diff --git a/pkg/generators/soft_opt_out_threshold_test.go b/pkg/generators/soft_opt_out_threshold_test.go deleted file mode 100644 index d14d3a7..0000000 --- a/pkg/generators/soft_opt_out_threshold_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package generators - -import ( - "main/pkg/constants" - "main/pkg/fetchers" - statePkg "main/pkg/state" - "testing" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/testutil" - - "github.com/stretchr/testify/assert" -) - -func TestSoftOptOutThresholdGeneratorNoState(t *testing.T) { - t.Parallel() - - state := statePkg.NewState() - generator := NewSoftOptOutThresholdGenerator() - results := generator.Generate(state) - assert.Empty(t, results) -} - -func TestSoftOptOutThresholdGeneratorNotEmptyState(t *testing.T) { - t.Parallel() - - state := statePkg.NewState() - state.Set(constants.FetcherNameSoftOptOutThreshold, fetchers.SoftOptOutThresholdData{ - Thresholds: map[string]float64{ - "chain": 0.5, - }, - }) - - generator := NewSoftOptOutThresholdGenerator() - results := generator.Generate(state) - assert.NotEmpty(t, results) - - gauge, ok := results[0].(*prometheus.GaugeVec) - assert.True(t, ok) - assert.InEpsilon(t, 0.5, testutil.ToFloat64(gauge.With(prometheus.Labels{ - "chain": "chain", - })), 0.01) -} diff --git a/pkg/tendermint/rpc.go b/pkg/tendermint/rpc.go index e62cf0f..0d48c51 100644 --- a/pkg/tendermint/rpc.go +++ b/pkg/tendermint/rpc.go @@ -7,8 +7,6 @@ import ( "main/pkg/http" "main/pkg/types" "main/pkg/utils" - "strconv" - "strings" "sync" "go.opentelemetry.io/otel/attribute" @@ -464,44 +462,6 @@ func (rpc *RPC) GetSlashingParams( return response, &info, nil } -func (rpc *RPC) GetConsumerSoftOutOutThreshold( - ctx context.Context, -) (float64, bool, *types.QueryInfo, error) { - if !rpc.ChainQueries.Enabled("params") { - return 0, false, nil, nil - } - - childQuerierCtx, span := rpc.Tracer.Start( - ctx, - "Fetching soft opt-out threshold params", - ) - defer span.End() - - var response *types.ParamsResponse - info, err := rpc.Get( - rpc.ChainHost+"/cosmos/params/v1beta1/params?subspace=ccvconsumer&key=SoftOptOutThreshold", - &response, - childQuerierCtx, - ) - if err != nil { - return 0.0, false, &info, err - } - - if response.Code != 0 { - info.Success = false - return 0, false, &info, fmt.Errorf("expected code 0, but got %d", response.Code) - } - - valueStripped := strings.ReplaceAll(response.Param.Value, "\"", "") - value, err := strconv.ParseFloat(valueStripped, 64) - if err != nil { - info.Success = false - return 0, false, &info, err - } - - return value, true, &info, nil -} - func (rpc *RPC) GetStakingParams( ctx context.Context, ) (*types.StakingParamsResponse, *types.QueryInfo, error) {