diff --git a/grpc.go b/grpc.go
index 3757b7b..7377de2 100644
--- a/grpc.go
+++ b/grpc.go
@@ -20,7 +20,11 @@ type TendermintGRPC struct {
Registry codectypes.InterfaceRegistry
}
-func NewTendermintGRPC(nodeConfig NodeConfig, registry codectypes.InterfaceRegistry, logger *zerolog.Logger) *TendermintGRPC {
+func NewTendermintGRPC(
+ nodeConfig NodeConfig,
+ registry codectypes.InterfaceRegistry,
+ logger *zerolog.Logger,
+) *TendermintGRPC {
grpcConn, err := grpc.Dial(
nodeConfig.GrpcAddress,
grpc.WithInsecure(),
@@ -68,7 +72,7 @@ func (grpc *TendermintGRPC) GetSlashingParams() SlashingParams {
}
}
-func (grpc *TendermintGRPC) GetSigningInfos() ([]slashingtypes.ValidatorSigningInfo, error) {
+func (grpc *TendermintGRPC) GetValidatorsState() (ValidatorsState, error) {
slashingClient := slashingtypes.NewQueryClient(grpc.Client)
signingInfos, err := slashingClient.SigningInfos(
context.Background(),
@@ -83,10 +87,6 @@ func (grpc *TendermintGRPC) GetSigningInfos() ([]slashingtypes.ValidatorSigningI
return nil, err
}
- return signingInfos.Info, nil
-}
-
-func (grpc *TendermintGRPC) GetValidators() ([]stakingtypes.Validator, error) {
stakingClient := stakingtypes.NewQueryClient(grpc.Client)
validatorsResult, err := stakingClient.Validators(
context.Background(),
@@ -101,7 +101,36 @@ func (grpc *TendermintGRPC) GetValidators() ([]stakingtypes.Validator, error) {
return nil, err
}
- return validatorsResult.Validators, nil
+ validatorsMap := make(map[string]stakingtypes.Validator, len(validatorsResult.Validators))
+ for _, validator := range validatorsResult.Validators {
+ err := validator.UnpackInterfaces(grpc.Registry)
+ if err != nil {
+ grpc.Logger.Error().Err(err).Msg("Could not unpack interface")
+ return nil, err
+ }
+
+ pubKey, err := validator.GetConsAddr()
+ if err != nil {
+ grpc.Logger.Error().Err(err).Msg("Could not get cons addr")
+ return nil, err
+ }
+
+ validatorsMap[pubKey.String()] = validator
+ }
+
+ newState := make(ValidatorsState, len(signingInfos.Info))
+
+ for _, info := range signingInfos.Info {
+ validator, ok := validatorsMap[info.Address]
+ if !ok {
+ grpc.Logger.Warn().Str("address", info.Address).Msg("Could not find validator by pubkey")
+ continue
+ }
+
+ newState[info.Address] = NewValidatorState(validator, info)
+ }
+
+ return newState, nil
}
func (grpc *TendermintGRPC) GetValidator(address string) (stakingtypes.Validator, error) {
@@ -118,16 +147,27 @@ func (grpc *TendermintGRPC) GetValidator(address string) (stakingtypes.Validator
return validatorResponse.Validator, nil
}
-func (grpc *TendermintGRPC) GetSigningInfo(validator stakingtypes.Validator) (slashingtypes.ValidatorSigningInfo, error) {
+func (grpc *TendermintGRPC) GetValidatorState(address string) (ValidatorState, error) {
+ stakingClient := stakingtypes.NewQueryClient(grpc.Client)
+
+ validatorResponse, err := stakingClient.Validator(
+ context.Background(),
+ &stakingtypes.QueryValidatorRequest{ValidatorAddr: address},
+ )
+ if err != nil {
+ return ValidatorState{}, err
+ }
+
+ validator := validatorResponse.Validator
slashingClient := slashingtypes.NewQueryClient(grpc.Client)
- err := validator.UnpackInterfaces(grpc.Registry) // Unpack interfaces, to populate the Anys' cached values
+ err = validator.UnpackInterfaces(grpc.Registry) // Unpack interfaces, to populate the Anys' cached values
if err != nil {
grpc.Logger.Error().
Str("address", validator.OperatorAddress).
Err(err).
Msg("Could not get unpack validator inferfaces")
- return slashingtypes.ValidatorSigningInfo{}, err
+ return ValidatorState{}, err
}
pubKey, err := validator.GetConsAddr()
@@ -136,7 +176,7 @@ func (grpc *TendermintGRPC) GetSigningInfo(validator stakingtypes.Validator) (sl
Str("address", validator.OperatorAddress).
Err(err).
Msg("Could not get validator pubkey")
- return slashingtypes.ValidatorSigningInfo{}, err
+ return ValidatorState{}, err
}
signingInfosResponse, err := slashingClient.SigningInfo(
@@ -148,8 +188,8 @@ func (grpc *TendermintGRPC) GetSigningInfo(validator stakingtypes.Validator) (sl
Str("address", validator.OperatorAddress).
Err(err).
Msg("Could not get signing info")
- return slashingtypes.ValidatorSigningInfo{}, err
+ return ValidatorState{}, err
}
- return signingInfosResponse.ValSigningInfo, nil
+ return NewValidatorState(validator, signingInfosResponse.ValSigningInfo), nil
}
diff --git a/report_generator.go b/report_generator.go
index e6d4384..6070e85 100644
--- a/report_generator.go
+++ b/report_generator.go
@@ -4,7 +4,6 @@ import (
"fmt"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
- stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/rs/zerolog"
)
@@ -36,60 +35,15 @@ func NewReportGenerator(
func (g *ReportGenerator) GetNewState() (ValidatorsState, error) {
g.Logger.Debug().Msg("Querying for signing infos...")
- signingInfos, err := g.gRPC.GetSigningInfos()
+ state, err := g.gRPC.GetValidatorsState()
if err != nil {
g.Logger.Error().Err(err).Msg("Could not query for signing infos")
return nil, err
}
- validators, err := g.gRPC.GetValidators()
- if err != nil {
- g.Logger.Error().Err(err).Msg("Could not query for validators")
- return nil, err
- }
-
- validatorsMap := make(map[string]stakingtypes.Validator, len(validators))
- for _, validator := range validators {
- err := validator.UnpackInterfaces(g.Registry)
- if err != nil {
- g.Logger.Error().Err(err).Msg("Could not unpack interface")
- return nil, err
- }
-
- pubKey, err := validator.GetConsAddr()
- if err != nil {
- g.Logger.Error().Err(err).Msg("Could not get cons addr")
- return nil, err
- }
-
- validatorsMap[pubKey.String()] = validator
- }
-
- newState := make(ValidatorsState, len(signingInfos))
-
- for _, info := range signingInfos {
- validator, ok := validatorsMap[info.Address]
- if !ok {
- g.Logger.Warn().Str("address", info.Address).Msg("Could not find validator by pubkey")
- continue
- }
-
- if !g.Config.IsValidatorMonitored(validator.OperatorAddress) {
- g.Logger.Trace().Str("address", info.Address).Msg("Not monitoring this validator, skipping.")
- continue
- }
-
- newState[info.Address] = ValidatorState{
- Address: validator.OperatorAddress,
- Moniker: validator.Description.Moniker,
- ConsensusAddress: info.Address,
- MissedBlocks: info.MissedBlocksCounter,
- Jailed: validator.Jailed,
- Tombstoned: info.Tombstoned,
- }
- }
-
- return newState, nil
+ return FilterMap(state, func(v ValidatorState) bool {
+ return g.Config.IsValidatorMonitored(v.Address)
+ }), nil
}
func (g *ReportGenerator) GetValidatorReportEntry(oldState, newState ValidatorState) (*ReportEntry, bool) {
diff --git a/telegram.go b/telegram.go
index 0345de6..3c2d1ca 100644
--- a/telegram.go
+++ b/telegram.go
@@ -9,8 +9,6 @@ import (
"time"
"github.com/BurntSushi/toml"
- slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
- stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/rs/zerolog"
tb "gopkg.in/tucnak/telebot.v2"
)
@@ -256,7 +254,7 @@ func (r *TelegramReporter) getValidatorStatus(message *tb.Message) {
address := args[1]
r.Logger.Debug().Str("address", address).Msg("getValidatorStatus: address")
- validator, err := r.Client.GetValidator(address)
+ state, err := r.Client.GetValidatorState(address)
if err != nil {
r.Logger.Error().
Str("address", address).
@@ -266,13 +264,7 @@ func (r *TelegramReporter) getValidatorStatus(message *tb.Message) {
return
}
- signingInfo, err := r.Client.GetSigningInfo(validator)
- if err != nil {
- r.sendMessage(message, "Could not get missed blocks info")
- return
- }
-
- r.sendMessage(message, r.getValidatorWithMissedBlocksSerialized(validator, signingInfo))
+ r.sendMessage(message, r.getValidatorWithMissedBlocksSerialized(state))
r.Logger.Info().
Str("user", message.Sender.Username).
Str("address", address).
@@ -291,7 +283,7 @@ func (r *TelegramReporter) getSubscribedValidatorsStatuses(message *tb.Message)
var sb strings.Builder
for _, address := range subscribedValidators {
- validator, err := r.Client.GetValidator(address)
+ state, err := r.Client.GetValidatorState(address)
if err != nil {
r.Logger.Error().
Str("address", address).
@@ -301,13 +293,7 @@ func (r *TelegramReporter) getSubscribedValidatorsStatuses(message *tb.Message)
return
}
- signingInfo, err := r.Client.GetSigningInfo(validator)
- if err != nil {
- r.sendMessage(message, "Could not get missed blocks info")
- return
- }
-
- sb.WriteString(r.getValidatorWithMissedBlocksSerialized(validator, signingInfo))
+ sb.WriteString(r.getValidatorWithMissedBlocksSerialized(state))
sb.WriteString("\n")
}
@@ -317,22 +303,19 @@ func (r *TelegramReporter) getSubscribedValidatorsStatuses(message *tb.Message)
Msg("Successfully returned subscribed validator statuses")
}
-func (r *TelegramReporter) getValidatorWithMissedBlocksSerialized(
- validator stakingtypes.Validator,
- signingInfo slashingtypes.ValidatorSigningInfo,
-) string {
+func (r *TelegramReporter) getValidatorWithMissedBlocksSerialized(state ValidatorState) string {
var sb strings.Builder
- sb.WriteString(fmt.Sprintf("%s
\n", validator.Description.Moniker))
+ sb.WriteString(fmt.Sprintf("%s
\n", state.Moniker))
sb.WriteString(fmt.Sprintf(
"Missed blocks: %d/%d (%.2f%%)\n",
- signingInfo.MissedBlocksCounter,
+ state.MissedBlocks,
r.Params.SignedBlocksWindow,
- float64(signingInfo.MissedBlocksCounter)/float64(r.Params.SignedBlocksWindow)*100,
+ float64(state.MissedBlocks)/float64(r.Params.SignedBlocksWindow)*100,
))
sb.WriteString(fmt.Sprintf(
"Mintscan\n",
r.ChainInfoConfig.MintscanPrefix,
- validator.OperatorAddress,
+ state.Address,
))
return sb.String()
diff --git a/types.go b/types.go
index 6cd45f5..fcd171e 100644
--- a/types.go
+++ b/types.go
@@ -2,6 +2,9 @@ package main
import (
"time"
+
+ slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
type Direction int
@@ -35,6 +38,20 @@ type ValidatorState struct {
Tombstoned bool
}
+func NewValidatorState(
+ validator stakingtypes.Validator,
+ info slashingtypes.ValidatorSigningInfo,
+) ValidatorState {
+ return ValidatorState{
+ Address: validator.OperatorAddress,
+ Moniker: validator.Description.Moniker,
+ ConsensusAddress: info.Address,
+ MissedBlocks: info.MissedBlocksCounter,
+ Jailed: validator.Jailed,
+ Tombstoned: info.Tombstoned,
+ }
+}
+
type ValidatorsState map[string]ValidatorState
type ReportEntry struct {
diff --git a/utils.go b/utils.go
index 6292610..ae3e541 100644
--- a/utils.go
+++ b/utils.go
@@ -17,3 +17,13 @@ func removeFromSlice(slice []string, r string) []string {
}
return slice
}
+
+func FilterMap[T any](source map[string]T, f func(T) bool) map[string]T {
+ var n map[string]T
+ for key, value := range source {
+ if f(value) {
+ n[key] = value
+ }
+ }
+ return n
+}