diff --git a/vochain/ist/validators.go b/vochain/ist/validators.go index db38b9947..54cca5ffb 100644 --- a/vochain/ist/validators.go +++ b/vochain/ist/validators.go @@ -102,7 +102,7 @@ func (c *Controller) updateValidatorScore(voteAddresses [][]byte, proposer []byt // cannot remove the last 3 validators validators[idx].Power = 1 } else { - if err := c.state.RemoveValidator(validators[idx].Address); err != nil { + if err := c.state.RemoveValidator(validators[idx]); err != nil { return fmt.Errorf("cannot remove validator: %w", err) } continue diff --git a/vochain/state/validators.go b/vochain/state/validators.go index bd544a797..0918de868 100644 --- a/vochain/state/validators.go +++ b/vochain/state/validators.go @@ -5,12 +5,32 @@ import ( "errors" "fmt" + "github.com/VictoriaMetrics/metrics" "github.com/ethereum/go-ethereum/common" "go.vocdoni.io/dvote/tree/arbo" "go.vocdoni.io/proto/build/go/models" "google.golang.org/protobuf/proto" ) +func labelsFrom(v *models.Validator) string { + return fmt.Sprintf(`{address="%x",validator_address="%X",name=%q}`, + v.GetAddress(), v.GetValidatorAddress(), v.GetName()) +} + +func metricsUpdateValidator(validator *models.Validator) { + metrics.GetOrCreateCounter("vochain_validator_power" + labelsFrom(validator)).Set(validator.GetPower()) + metrics.GetOrCreateCounter("vochain_validator_proposals" + labelsFrom(validator)).Set(validator.GetProposals()) + metrics.GetOrCreateCounter("vochain_validator_score" + labelsFrom(validator)).Set(uint64(validator.GetScore())) + metrics.GetOrCreateCounter("vochain_validator_votes" + labelsFrom(validator)).Set(validator.GetVotes()) +} + +func metricsDeleteValidator(validator *models.Validator) { + metrics.UnregisterMetric("vochain_validator_power" + labelsFrom(validator)) + metrics.UnregisterMetric("vochain_validator_proposals" + labelsFrom(validator)) + metrics.UnregisterMetric("vochain_validator_score" + labelsFrom(validator)) + metrics.UnregisterMetric("vochain_validator_votes" + labelsFrom(validator)) +} + // AddValidator adds a tendemint validator. If it exists, it will be updated. func (v *State) AddValidator(validator *models.Validator) error { v.tx.Lock() @@ -19,23 +39,31 @@ func (v *State) AddValidator(validator *models.Validator) error { if err != nil { return err } - return v.tx.DeepSet(validator.Address, validatorBytes, StateTreeCfg(TreeValidators)) + if err := v.tx.DeepSet(validator.GetAddress(), validatorBytes, StateTreeCfg(TreeValidators)); err != nil { + return err + } + go metricsUpdateValidator(validator) + return nil } -// RemoveValidator removes a tendermint validator identified by its address -func (v *State) RemoveValidator(address []byte) error { +// RemoveValidator removes a tendermint validator identified by its validator.Address +func (v *State) RemoveValidator(validator *models.Validator) error { v.tx.Lock() defer v.tx.Unlock() validators, err := v.tx.SubTree(StateTreeCfg(TreeValidators)) if err != nil { return err } - if _, err := validators.Get(address); errors.Is(err, arbo.ErrKeyNotFound) { + if _, err := validators.Get(validator.GetAddress()); errors.Is(err, arbo.ErrKeyNotFound) { return fmt.Errorf("validator not found: %w", err) } else if err != nil { return err } - return validators.Set(address, nil) + if err := validators.Set(validator.GetAddress(), nil); err != nil { + return err + } + go metricsDeleteValidator(validator) + return nil } // Validators returns a list of the chain validators diff --git a/vocone/vocone.go b/vocone/vocone.go index 07c331b5a..e84dc878b 100644 --- a/vocone/vocone.go +++ b/vocone/vocone.go @@ -257,7 +257,7 @@ func (vc *Vocone) SetKeyKeeper(key *ethereum.SignKeys) error { return err } for _, v := range validators { - if err := vc.App.State.RemoveValidator(v.Address); err != nil { + if err := vc.App.State.RemoveValidator(v); err != nil { log.Warnf("could not remove validator %x", v.Address) } }