Skip to content

Commit

Permalink
use nodeID filter and uptimePerc (#1390)
Browse files Browse the repository at this point in the history
* use nodeID filter and uptimePerc

* add uptime seconds
  • Loading branch information
ceyonur authored Nov 19, 2024
1 parent 4ef3c47 commit 6083668
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 23 deletions.
9 changes: 6 additions & 3 deletions plugin/evm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"golang.org/x/exp/slog"

"github.com/ava-labs/avalanchego/api"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/rpc"
)

Expand All @@ -24,7 +25,7 @@ type Client interface {
LockProfile(ctx context.Context, options ...rpc.Option) error
SetLogLevel(ctx context.Context, level slog.Level, options ...rpc.Option) error
GetVMConfig(ctx context.Context, options ...rpc.Option) (*Config, error)
GetCurrentValidators(ctx context.Context, options ...rpc.Option) ([]CurrentValidator, error)
GetCurrentValidators(ctx context.Context, nodeIDs []ids.NodeID, options ...rpc.Option) ([]CurrentValidator, error)
}

// Client implementation for interacting with EVM [chain]
Expand Down Expand Up @@ -77,8 +78,10 @@ func (c *client) GetVMConfig(ctx context.Context, options ...rpc.Option) (*Confi
}

// GetCurrentValidators returns the current validators
func (c *client) GetCurrentValidators(ctx context.Context, options ...rpc.Option) ([]CurrentValidator, error) {
func (c *client) GetCurrentValidators(ctx context.Context, nodeIDs []ids.NodeID, options ...rpc.Option) ([]CurrentValidator, error) {
res := &GetCurrentValidatorsResponse{}
err := c.validatorsRequester.SendRequest(ctx, "validators.getCurrentValidators", struct{}{}, res, options...)
err := c.validatorsRequester.SendRequest(ctx, "validators.getCurrentValidators", &GetCurrentValidatorsRequest{
NodeIDs: nodeIDs,
}, res, options...)
return res.Validators, err
}
72 changes: 52 additions & 20 deletions plugin/evm/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,93 @@
package evm

import (
"fmt"
"net/http"
"time"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/set"
)

type ValidatorsAPI struct {
vm *VM
}

type GetCurrentValidatorsRequest struct {
NodeIDs []ids.NodeID `json:"nodeIDs"`
}

type GetCurrentValidatorsResponse struct {
Validators []CurrentValidator `json:"validators"`
}

type CurrentValidator struct {
ValidationID ids.ID `json:"validationID"`
NodeID ids.NodeID `json:"nodeID"`
Weight uint64 `json:"weight"`
StartTimestamp uint64 `json:"startTimestamp"`
IsActive bool `json:"isActive"`
IsL1Validator bool `json:"isL1Validator"`
IsConnected bool `json:"isConnected"`
Uptime time.Duration `json:"uptime"`
ValidationID ids.ID `json:"validationID"`
NodeID ids.NodeID `json:"nodeID"`
Weight uint64 `json:"weight"`
StartTimestamp uint64 `json:"startTimestamp"`
IsActive bool `json:"isActive"`
IsL1Validator bool `json:"isL1Validator"`
IsConnected bool `json:"isConnected"`
UptimePercentage float32 `json:"uptimePercentage"`
UptimeSeconds uint64 `json:"uptimeSeconds"`
}

func (api *ValidatorsAPI) GetCurrentValidators(_ *http.Request, _ *struct{}, reply *GetCurrentValidatorsResponse) error {
func (api *ValidatorsAPI) GetCurrentValidators(_ *http.Request, req *GetCurrentValidatorsRequest, reply *GetCurrentValidatorsResponse) error {
api.vm.ctx.Lock.RLock()
defer api.vm.ctx.Lock.RUnlock()

vIDs := api.vm.validatorsManager.GetValidationIDs()
var vIDs set.Set[ids.ID]
if len(req.NodeIDs) > 0 {
vIDs = set.NewSet[ids.ID](len(req.NodeIDs))
for _, nodeID := range req.NodeIDs {
vID, err := api.vm.validatorsManager.GetValidationID(nodeID)
if err != nil {
return fmt.Errorf("couldn't find validator with node ID %s", nodeID)
}
vIDs.Add(vID)
}
} else {
vIDs = api.vm.validatorsManager.GetValidationIDs()
}

reply.Validators = make([]CurrentValidator, 0, vIDs.Len())

for _, vID := range vIDs.List() {
validator, err := api.vm.validatorsManager.GetValidator(vID)
if err != nil {
return err
return fmt.Errorf("couldn't find validator with validation ID %s", vID)
}

isConnected := api.vm.validatorsManager.IsConnected(validator.NodeID)

uptime, _, err := api.vm.validatorsManager.CalculateUptime(validator.NodeID)
upDuration, lastUpdated, err := api.vm.validatorsManager.CalculateUptime(validator.NodeID)
if err != nil {
return err
}
var uptimeFloat float64
startTime := time.Unix(int64(validator.StartTimestamp), 0)
bestPossibleUpDuration := lastUpdated.Sub(startTime)
if bestPossibleUpDuration == 0 {
uptimeFloat = 1
} else {
uptimeFloat = float64(upDuration) / float64(bestPossibleUpDuration)
}

// Transform this to a percentage (0-100) to make it consistent
// with currentValidators in PlatformVM API
uptimePercentage := float32(uptimeFloat * 100)

reply.Validators = append(reply.Validators, CurrentValidator{
ValidationID: validator.ValidationID,
NodeID: validator.NodeID,
StartTimestamp: validator.StartTimestamp,
Weight: validator.Weight,
IsActive: validator.IsActive,
IsL1Validator: validator.IsL1Validator,
IsConnected: isConnected,
Uptime: time.Duration(uptime.Seconds()),
ValidationID: validator.ValidationID,
NodeID: validator.NodeID,
StartTimestamp: validator.StartTimestamp,
Weight: validator.Weight,
IsActive: validator.IsActive,
IsL1Validator: validator.IsL1Validator,
IsConnected: isConnected,
UptimePercentage: uptimePercentage,
UptimeSeconds: uint64(upDuration.Seconds()),
})
}
return nil
Expand Down
2 changes: 2 additions & 0 deletions plugin/evm/validators/state/interfaces/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type StateReader interface {
GetValidationIDs() set.Set[ids.ID]
// GetNodeIDs returns the validator node IDs in the state
GetNodeIDs() set.Set[ids.NodeID]
// GetValidationID returns the validation ID for the given node ID
GetValidationID(nodeID ids.NodeID) (ids.ID, error)
}

type State interface {
Expand Down
9 changes: 9 additions & 0 deletions plugin/evm/validators/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,15 @@ func (s *state) GetNodeIDs() set.Set[ids.NodeID] {
return ids
}

// GetValidationID returns the validation ID for the given nodeID
func (s *state) GetValidationID(nodeID ids.NodeID) (ids.ID, error) {
vID, exists := s.index[nodeID]
if !exists {
return ids.ID{}, database.ErrNotFound
}
return vID, nil
}

// GetValidator returns the validator data for the given validationID
func (s *state) GetValidator(vID ids.ID) (interfaces.Validator, error) {
data, ok := s.data[vID]
Expand Down

0 comments on commit 6083668

Please sign in to comment.