Skip to content

Commit 31a1f35

Browse files
authored
feat: expose validators rank (#3)
1 parent f68bcdb commit 31a1f35

6 files changed

Lines changed: 36 additions & 24 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/avast/retry-go/v4 v4.5.0
77
github.com/fatih/color v1.15.0
88
github.com/prometheus/client_golang v1.16.0
9-
github.com/rs/zerolog v1.31.0
9+
github.com/shopspring/decimal v1.3.1
1010
github.com/sirupsen/logrus v1.9.0
1111
github.com/urfave/cli/v2 v2.25.7
1212
golang.org/x/sync v0.3.0

go.sum

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
44
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
55
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
66
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
7-
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
87
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
98
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
109
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1110
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1211
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1312
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
1413
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
15-
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
1614
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
1715
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
1816
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -27,7 +25,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
2725
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
2826
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
2927
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
30-
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
3128
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3229
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3330
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
@@ -38,11 +35,10 @@ github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI
3835
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
3936
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
4037
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
41-
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
42-
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
43-
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
4438
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
4539
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
40+
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
41+
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
4642
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
4743
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
4844
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

pkg/app/run.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package app
22

33
import (
44
"context"
5-
"fmt"
65
"net/http"
76
"os"
87
"os/signal"
@@ -14,7 +13,6 @@ import (
1413
"github.com/kilnfi/near-validator-watcher/pkg/near"
1514
"github.com/kilnfi/near-validator-watcher/pkg/watcher"
1615
"github.com/prometheus/client_golang/prometheus"
17-
"github.com/rs/zerolog/log"
1816
"github.com/sirupsen/logrus"
1917
"github.com/urfave/cli/v2"
2018
"golang.org/x/sync/errgroup"
@@ -101,7 +99,7 @@ func RunFunc(cCtx *cli.Context) error {
10199
defer cancel()
102100

103101
if err := httpServer.Shutdown(ctx); err != nil {
104-
log.Error().Err(fmt.Errorf("failed to stop http server: %w", err)).Msg("")
102+
logrus.WithError(err).Errorf("failed to stop http server")
105103
}
106104

107105
// Wait for all goroutines to finish

pkg/metrics/metrics.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Metrics struct {
2222
ValidatorProducedChunks *prometheus.GaugeVec
2323
ValidatorSlashed *prometheus.GaugeVec
2424
ValidatorStake *prometheus.GaugeVec
25+
ValidatorRank *prometheus.GaugeVec
2526
VersionBuild *prometheus.GaugeVec
2627
}
2728

@@ -117,6 +118,12 @@ func New(namespace string) *Metrics {
117118
Help: "Current amount of validator stake"},
118119
[]string{"account_id", "public_key", "epoch_start_height", "tracked"},
119120
),
121+
ValidatorRank: prometheus.NewGaugeVec(prometheus.GaugeOpts{
122+
Namespace: namespace,
123+
Name: "validator_rank",
124+
Help: "Current rank of validator based on stake"},
125+
[]string{"account_id", "public_key", "epoch_start_height", "tracked"},
126+
),
120127
VersionBuild: prometheus.NewGaugeVec(prometheus.GaugeOpts{
121128
Namespace: namespace,
122129
Name: "version_build",
@@ -146,5 +153,6 @@ func (m *Metrics) Register(reg prometheus.Registerer) {
146153
reg.MustRegister(m.ValidatorProducedChunks)
147154
reg.MustRegister(m.ValidatorSlashed)
148155
reg.MustRegister(m.ValidatorStake)
156+
reg.MustRegister(m.ValidatorRank)
149157
reg.MustRegister(m.VersionBuild)
150158
}

pkg/near/validators.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package near
22

3-
import "context"
3+
import (
4+
"context"
5+
6+
"github.com/shopspring/decimal"
7+
)
48

59
type ValidatorsResponse struct {
610
CurrentValidators []struct {
@@ -29,9 +33,9 @@ type ValidatorsResponse struct {
2933
}
3034

3135
type Validator struct {
32-
AccountId string `json:"account_id"`
33-
PublicKey string `json:"public_key"`
34-
Stake string `json:"stake"`
36+
AccountId string `json:"account_id"`
37+
PublicKey string `json:"public_key"`
38+
Stake decimal.Decimal `json:"stake"`
3539
}
3640

3741
func (c *Client) Validators(ctx context.Context, params interface{}) (ValidatorsResponse, error) {

pkg/watcher/watcher.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"sort"
78
"strconv"
89
"strings"
910
"sync/atomic"
@@ -138,23 +139,28 @@ func (w *Watcher) collectValidators(ctx context.Context) (near.ValidatorsRespons
138139

139140
var seatPrice float64
140141

141-
for _, v := range validators.CurrentValidators {
142-
isSlashed := 0
143-
if v.IsSlashed {
144-
isSlashed = 1
145-
}
142+
// Sort validators by stake to be able to calculate their rank
143+
rankedValidator := validators.CurrentValidators
144+
sort.SliceStable(rankedValidator, func(i, j int) bool {
145+
return rankedValidator[i].Stake.GreaterThan(rankedValidator[j].Stake)
146+
})
146147

148+
for i, v := range rankedValidator {
147149
labels := []string{v.AccountId, v.PublicKey, labelEpochStartHeight, w.isTracked(v.AccountId)}
148150

151+
w.metrics.ValidatorRank.
152+
WithLabelValues(v.AccountId, v.PublicKey, labelEpochStartHeight, w.isTracked(v.AccountId)).
153+
Set(float64(i + 1))
154+
149155
w.metrics.ValidatorExpectedBlocks.WithLabelValues(labels...).Set(float64(v.NumExpectedBlocks))
150156
w.metrics.ValidatorExpectedChunks.WithLabelValues(labels...).Set(float64(v.NumExpectedChunks))
151157
w.metrics.ValidatorProducedBlocks.WithLabelValues(labels...).Set(float64(v.NumProducedBlocks))
152158
w.metrics.ValidatorProducedChunks.WithLabelValues(labels...).Set(float64(v.NumProducedChunks))
153159

154-
w.metrics.ValidatorSlashed.WithLabelValues(labels...).Set(float64(isSlashed))
155-
w.metrics.ValidatorStake.WithLabelValues(labels...).Set(float64(GetStakeFromString(v.Stake)))
160+
w.metrics.ValidatorSlashed.WithLabelValues(labels...).Set(metrics.BoolToFloat64(v.IsSlashed))
161+
w.metrics.ValidatorStake.WithLabelValues(labels...).Set(v.Stake.InexactFloat64())
156162

157-
t := GetStakeFromString(v.Stake)
163+
t := v.Stake.InexactFloat64()
158164
if seatPrice == 0 {
159165
seatPrice = t
160166
}
@@ -168,13 +174,13 @@ func (w *Watcher) collectValidators(ctx context.Context) (near.ValidatorsRespons
168174
for _, v := range validators.NextValidators {
169175
w.metrics.NextValidatorStake.
170176
WithLabelValues(v.AccountId, v.PublicKey, labelEpochStartHeight, w.isTracked(v.AccountId)).
171-
Set(float64(GetStakeFromString(v.Stake)))
177+
Set(v.Stake.InexactFloat64())
172178
}
173179

174180
for _, v := range validators.CurrentProposals {
175181
w.metrics.CurrentProposals.
176182
WithLabelValues(v.AccountId, v.PublicKey, labelEpochStartHeight, w.isTracked(v.AccountId)).
177-
Set(float64(GetStakeFromString(v.Stake)))
183+
Set(v.Stake.InexactFloat64())
178184
}
179185

180186
for _, v := range validators.PrevEpochKickOut {

0 commit comments

Comments
 (0)