Skip to content

Commit

Permalink
JSON output for validator expectation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdee committed May 18, 2023
1 parent c963ea8 commit dbe45d5
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ dev:
- add "--generate-keystore" option for "account derive"
- update "validator exit" command to be able to generate multiple exits
- support for 12-word and 18-word mnemonics with single-word (no whitespace) passphrases
- add JSON output for "validator expectation"

1.30.0:
- add "chain spec" command
Expand Down
33 changes: 31 additions & 2 deletions cmd/validator/expectation/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ package validatorexpectation

import (
"context"
"encoding/json"
"fmt"
"time"

eth2client "github.com/attestantio/go-eth2-client"
"github.com/hako/durafmt"
"github.com/pkg/errors"
"github.com/spf13/viper"
)
Expand All @@ -26,6 +29,7 @@ type command struct {
quiet bool
verbose bool
debug bool
json bool

// Beacon node connection.
timeout time.Duration
Expand All @@ -38,18 +42,43 @@ type command struct {
// Data access.
eth2Client eth2client.Service
validatorsProvider eth2client.ValidatorsProvider
activeValidators int

// Output.
// Results.
res *results
}

type results struct {
activeValidators uint64
timeBetweenProposals time.Duration
timeBetweenSyncCommittees time.Duration
}

type resultsJSON struct {
ActiveValidators string `json:"active_validators"`
TimeBetweenProposals string `json:"time_between_proposals"`
SecsBetweenProposals string `json:"secs_between_proposals"`
TimeBetweenSyncCommittees string `json:"time_between_sync_committees"`
SecsBetweenSyncCommittees string `json:"secs_between_sync_committees"`
}

func (r *results) MarshalJSON() ([]byte, error) {
data := &resultsJSON{
ActiveValidators: fmt.Sprintf("%d", r.activeValidators),
TimeBetweenProposals: durafmt.Parse(r.timeBetweenProposals).LimitFirstN(2).String(),
SecsBetweenProposals: fmt.Sprintf("%d", int64(r.timeBetweenProposals.Seconds())),
TimeBetweenSyncCommittees: durafmt.Parse(r.timeBetweenSyncCommittees).LimitFirstN(2).String(),
SecsBetweenSyncCommittees: fmt.Sprintf("%d", int64(r.timeBetweenSyncCommittees.Seconds())),
}
return json.Marshal(data)
}

func newCommand(_ context.Context) (*command, error) {
c := &command{
quiet: viper.GetBool("quiet"),
verbose: viper.GetBool("verbose"),
debug: viper.GetBool("debug"),
json: viper.GetBool("json"),
res: &results{},
}

// Timeout.
Expand Down
26 changes: 22 additions & 4 deletions cmd/validator/expectation/output.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2021 Weald Technology Trading.
// Copyright © 2021, 2023 Weald Technology Trading.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -15,24 +15,42 @@ package validatorexpectation

import (
"context"
"encoding/json"
"fmt"
"strings"

"github.com/hako/durafmt"
)

func (c *command) output(_ context.Context) (string, error) {
func (c *command) output(ctx context.Context) (string, error) {
if c.quiet {
return "", nil
}

if c.json {
return c.outputJSON(ctx)
}
return c.outputTxt(ctx)
}

func (c *command) outputJSON(_ context.Context) (string, error) {
data, err := json.Marshal(c.res)
if err != nil {
return "", err
}

return fmt.Sprintf("%s\n", string(data)), nil
}

func (c *command) outputTxt(_ context.Context) (string, error) {
builder := strings.Builder{}

builder.WriteString("Expected time between block proposals: ")
builder.WriteString(durafmt.Parse(c.timeBetweenProposals).LimitFirstN(2).String())
builder.WriteString(durafmt.Parse(c.res.timeBetweenProposals).LimitFirstN(2).String())
builder.WriteString("\n")

builder.WriteString("Expected time between sync committees: ")
builder.WriteString(durafmt.Parse(c.timeBetweenSyncCommittees).LimitFirstN(2).String())
builder.WriteString(durafmt.Parse(c.res.timeBetweenSyncCommittees).LimitFirstN(2).String())
builder.WriteString("\n")

return builder.String(), nil
Expand Down
12 changes: 6 additions & 6 deletions cmd/validator/expectation/process.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2021 Weald Technology Trading.
// Copyright © 2021, 2023 Weald Technology Trading.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand Down Expand Up @@ -31,7 +31,7 @@ func (c *command) process(ctx context.Context) error {
}

if c.debug {
fmt.Printf("Active validators: %d\n", c.activeValidators)
fmt.Printf("Active validators: %d\n", c.res.activeValidators)
}

if err := c.calculateProposalChance(ctx); err != nil {
Expand Down Expand Up @@ -59,7 +59,7 @@ func (c *command) calculateProposalChance(ctx context.Context) error {
return errors.New("SECONDS_PER_SLOT of incorrect type")
}

c.timeBetweenProposals = slotDuration * time.Duration(c.activeValidators) / time.Duration(c.validators)
c.res.timeBetweenProposals = slotDuration * time.Duration(c.res.activeValidators) / time.Duration(c.validators)

return nil
}
Expand Down Expand Up @@ -109,12 +109,12 @@ func (c *command) calculateSyncCommitteeChance(ctx context.Context) error {
return errors.New("EPOCHS_PER_SYNC_COMMITTEE_PERIOD of incorrect type")
}

periodsBetweenSyncCommittees := uint64(c.activeValidators) / syncCommitteeSize
periodsBetweenSyncCommittees := c.res.activeValidators / syncCommitteeSize
if c.debug {
fmt.Printf("Sync committee periods between inclusion: %d\n", periodsBetweenSyncCommittees)
}

c.timeBetweenSyncCommittees = slotDuration * time.Duration(slotsPerEpoch*epochsPerPeriod) * time.Duration(periodsBetweenSyncCommittees) / time.Duration(c.validators)
c.res.timeBetweenSyncCommittees = slotDuration * time.Duration(slotsPerEpoch*epochsPerPeriod) * time.Duration(periodsBetweenSyncCommittees) / time.Duration(c.validators)

return nil
}
Expand Down Expand Up @@ -157,7 +157,7 @@ func (c *command) setup(ctx context.Context) error {
for _, validator := range validators {
if validator.Validator.ActivationEpoch <= currentEpoch &&
validator.Validator.ExitEpoch > currentEpoch {
c.activeValidators++
c.res.activeValidators++
}
}

Expand Down

0 comments on commit dbe45d5

Please sign in to comment.