mirror of
https://github.com/wealdtech/ethdo.git
synced 2026-01-13 07:57:56 -05:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc59ab618d | ||
|
|
9794949e8a |
@@ -1,4 +1,4 @@
|
||||
1.7.4:
|
||||
1.7.5:
|
||||
- add "slot time"
|
||||
- add "attester duties"
|
||||
- add "node events"
|
||||
|
||||
@@ -15,18 +15,13 @@ package attesterduties
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wealdtech/ethdo/util"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
type dataIn struct {
|
||||
@@ -39,10 +34,10 @@ type dataIn struct {
|
||||
// Chain information.
|
||||
slotsPerEpoch uint64
|
||||
// Operation.
|
||||
validator *api.Validator
|
||||
account string
|
||||
pubKey string
|
||||
eth2Client eth2client.Service
|
||||
epoch spec.Epoch
|
||||
account e2wtypes.Account
|
||||
}
|
||||
|
||||
func input(ctx context.Context) (*dataIn, error) {
|
||||
@@ -57,14 +52,15 @@ func input(ctx context.Context) (*dataIn, error) {
|
||||
data.debug = viper.GetBool("debug")
|
||||
data.json = viper.GetBool("json")
|
||||
|
||||
// Account.
|
||||
var err error
|
||||
data.account, err = attesterDutiesAccount()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account")
|
||||
// Account or pubkey.
|
||||
if viper.GetString("account") == "" && viper.GetString("pubkey") == "" {
|
||||
return nil, errors.New("account or pubkey is required")
|
||||
}
|
||||
data.account = viper.GetString("account")
|
||||
data.pubKey = viper.GetString("pubkey")
|
||||
|
||||
// Ethereum 2 client.
|
||||
var err error
|
||||
data.eth2Client, err = util.ConnectToBeaconNode(ctx, viper.GetString("connection"), viper.GetDuration("timeout"), viper.GetBool("allow-insecure-connections"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to connect to Ethereum 2 beacon node")
|
||||
@@ -87,45 +83,5 @@ func input(ctx context.Context) (*dataIn, error) {
|
||||
}
|
||||
data.epoch = spec.Epoch(epoch)
|
||||
|
||||
pubKeys := make([]spec.BLSPubKey, 1)
|
||||
pubKey, err := util.BestPublicKey(data.account)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain public key for account")
|
||||
}
|
||||
copy(pubKeys[0][:], pubKey.Marshal())
|
||||
validators, err := data.eth2Client.(eth2client.ValidatorsProvider).ValidatorsByPubKey(ctx, fmt.Sprintf("%d", uint64(data.epoch)*data.slotsPerEpoch), pubKeys)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to obtain validator information")
|
||||
}
|
||||
if len(validators) == 0 {
|
||||
return nil, errors.New("validator is not known")
|
||||
}
|
||||
data.validator = validators[0]
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// attesterDutiesAccount obtains the account for the attester duties command.
|
||||
func attesterDutiesAccount() (e2wtypes.Account, error) {
|
||||
var account e2wtypes.Account
|
||||
var err error
|
||||
if viper.GetString("account") != "" {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
|
||||
defer cancel()
|
||||
_, account, err = util.WalletAndAccountFromPath(ctx, viper.GetString("account"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account")
|
||||
}
|
||||
} else {
|
||||
pubKey := viper.GetString("pubkey")
|
||||
pubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(pubKey, "0x"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("failed to decode public key %s", pubKey))
|
||||
}
|
||||
account, err = util.NewScratchAccount(nil, pubKeyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("invalid public key %s", pubKey))
|
||||
}
|
||||
}
|
||||
return account, nil
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func TestInput(t *testing.T) {
|
||||
vars: map[string]interface{}{
|
||||
"timeout": "5s",
|
||||
},
|
||||
err: "failed to obtain account: invalid public key : public key must be 48 bytes",
|
||||
err: "account or pubkey is required",
|
||||
},
|
||||
{
|
||||
name: "ConnectionMissing",
|
||||
|
||||
@@ -15,11 +15,16 @@ package attesterduties
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wealdtech/ethdo/util"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
func process(ctx context.Context, data *dataIn) (*dataOut, error) {
|
||||
@@ -27,13 +32,49 @@ func process(ctx context.Context, data *dataIn) (*dataOut, error) {
|
||||
return nil, errors.New("no data")
|
||||
}
|
||||
|
||||
var account e2wtypes.Account
|
||||
var err error
|
||||
if data.account != "" {
|
||||
ctx, cancel := context.WithTimeout(ctx, data.timeout)
|
||||
defer cancel()
|
||||
_, account, err = util.WalletAndAccountFromPath(ctx, data.account)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account")
|
||||
}
|
||||
} else {
|
||||
pubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(data.pubKey, "0x"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("failed to decode public key %s", data.pubKey))
|
||||
}
|
||||
account, err = util.NewScratchAccount(nil, pubKeyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("invalid public key %s", data.pubKey))
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch validator
|
||||
pubKeys := make([]spec.BLSPubKey, 1)
|
||||
pubKey, err := util.BestPublicKey(account)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain public key for account")
|
||||
}
|
||||
copy(pubKeys[0][:], pubKey.Marshal())
|
||||
validators, err := data.eth2Client.(eth2client.ValidatorsProvider).ValidatorsByPubKey(ctx, fmt.Sprintf("%d", uint64(data.epoch)*data.slotsPerEpoch), pubKeys)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to obtain validator information")
|
||||
}
|
||||
if len(validators) == 0 {
|
||||
return nil, errors.New("validator is not known")
|
||||
}
|
||||
validator := validators[0]
|
||||
|
||||
results := &dataOut{
|
||||
debug: data.debug,
|
||||
quiet: data.quiet,
|
||||
verbose: data.verbose,
|
||||
}
|
||||
|
||||
duty, err := duty(ctx, data.eth2Client, data.validator, data.epoch, data.slotsPerEpoch)
|
||||
duty, err := duty(ctx, data.eth2Client, validator, data.epoch, data.slotsPerEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain duty for validator")
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
"github.com/attestantio/go-eth2-client/auto"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -48,10 +47,8 @@ func TestProcess(t *testing.T) {
|
||||
dataIn: &dataIn{
|
||||
eth2Client: eth2Client,
|
||||
slotsPerEpoch: 32,
|
||||
validator: &api.Validator{
|
||||
Index: 0,
|
||||
},
|
||||
epoch: 100,
|
||||
pubKey: "0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95",
|
||||
epoch: 100,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -15,18 +15,13 @@ package attesterinclusion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wealdtech/ethdo/util"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
type dataIn struct {
|
||||
@@ -38,10 +33,10 @@ type dataIn struct {
|
||||
// Chain information.
|
||||
slotsPerEpoch uint64
|
||||
// Operation.
|
||||
validator *api.Validator
|
||||
eth2Client eth2client.Service
|
||||
epoch spec.Epoch
|
||||
account e2wtypes.Account
|
||||
account string
|
||||
pubKey string
|
||||
}
|
||||
|
||||
func input(ctx context.Context) (*dataIn, error) {
|
||||
@@ -55,14 +50,15 @@ func input(ctx context.Context) (*dataIn, error) {
|
||||
data.verbose = viper.GetBool("verbose")
|
||||
data.debug = viper.GetBool("debug")
|
||||
|
||||
// Account.
|
||||
var err error
|
||||
data.account, err = attesterInclusionAccount()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account")
|
||||
// Account or pubkey.
|
||||
if viper.GetString("account") == "" && viper.GetString("pubkey") == "" {
|
||||
return nil, errors.New("account or pubkey is required")
|
||||
}
|
||||
data.account = viper.GetString("account")
|
||||
data.pubKey = viper.GetString("pubkey")
|
||||
|
||||
// Ethereum 2 client.
|
||||
var err error
|
||||
data.eth2Client, err = util.ConnectToBeaconNode(ctx, viper.GetString("connection"), viper.GetDuration("timeout"), viper.GetBool("allow-insecure-connections"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to connect to Ethereum 2 beacon node")
|
||||
@@ -89,49 +85,5 @@ func input(ctx context.Context) (*dataIn, error) {
|
||||
}
|
||||
data.epoch = spec.Epoch(epoch)
|
||||
|
||||
// Validator.
|
||||
stateID := "head"
|
||||
if viper.GetInt64("epoch") != -1 {
|
||||
stateID = fmt.Sprintf("%d", uint64(data.epoch)*data.slotsPerEpoch)
|
||||
}
|
||||
pubKeys := make([]spec.BLSPubKey, 1)
|
||||
pubKey, err := util.BestPublicKey(data.account)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain public key for account")
|
||||
}
|
||||
copy(pubKeys[0][:], pubKey.Marshal())
|
||||
validators, err := data.eth2Client.(eth2client.ValidatorsProvider).ValidatorsByPubKey(ctx, stateID, pubKeys)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to obtain validator information")
|
||||
}
|
||||
for _, validator := range validators {
|
||||
data.validator = validator
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// attesterInclusionAccount obtains the account for the attester inclusion command.
|
||||
func attesterInclusionAccount() (e2wtypes.Account, error) {
|
||||
var account e2wtypes.Account
|
||||
var err error
|
||||
if viper.GetString("account") != "" {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
|
||||
defer cancel()
|
||||
_, account, err = util.WalletAndAccountFromPath(ctx, viper.GetString("account"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account")
|
||||
}
|
||||
} else {
|
||||
pubKey := viper.GetString("pubkey")
|
||||
pubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(pubKey, "0x"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("failed to decode public key %s", pubKey))
|
||||
}
|
||||
account, err = util.NewScratchAccount(nil, pubKeyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("invalid public key %s", pubKey))
|
||||
}
|
||||
}
|
||||
return account, nil
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func TestInput(t *testing.T) {
|
||||
vars: map[string]interface{}{
|
||||
"timeout": "5s",
|
||||
},
|
||||
err: "failed to obtain account: invalid public key : public key must be 48 bytes",
|
||||
err: "account or pubkey is required",
|
||||
},
|
||||
{
|
||||
name: "ConnectionMissing",
|
||||
|
||||
@@ -15,12 +15,16 @@ package attesterinclusion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wealdtech/ethdo/util"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
func process(ctx context.Context, data *dataIn) (*dataOut, error) {
|
||||
@@ -28,13 +32,49 @@ func process(ctx context.Context, data *dataIn) (*dataOut, error) {
|
||||
return nil, errors.New("no data")
|
||||
}
|
||||
|
||||
var account e2wtypes.Account
|
||||
var err error
|
||||
if data.account != "" {
|
||||
ctx, cancel := context.WithTimeout(ctx, data.timeout)
|
||||
defer cancel()
|
||||
_, account, err = util.WalletAndAccountFromPath(ctx, data.account)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account")
|
||||
}
|
||||
} else {
|
||||
pubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(data.pubKey, "0x"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("failed to decode public key %s", data.pubKey))
|
||||
}
|
||||
account, err = util.NewScratchAccount(nil, pubKeyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("invalid public key %s", data.pubKey))
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch validator
|
||||
pubKeys := make([]spec.BLSPubKey, 1)
|
||||
pubKey, err := util.BestPublicKey(account)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain public key for account")
|
||||
}
|
||||
copy(pubKeys[0][:], pubKey.Marshal())
|
||||
validators, err := data.eth2Client.(eth2client.ValidatorsProvider).ValidatorsByPubKey(ctx, fmt.Sprintf("%d", uint64(data.epoch)*data.slotsPerEpoch), pubKeys)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to obtain validator information")
|
||||
}
|
||||
if len(validators) == 0 {
|
||||
return nil, errors.New("validator is not known")
|
||||
}
|
||||
validator := validators[0]
|
||||
|
||||
results := &dataOut{
|
||||
debug: data.debug,
|
||||
quiet: data.quiet,
|
||||
verbose: data.verbose,
|
||||
}
|
||||
|
||||
duty, err := duty(ctx, data.eth2Client, data.validator, data.epoch, data.slotsPerEpoch)
|
||||
duty, err := duty(ctx, data.eth2Client, validator, data.epoch, data.slotsPerEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain duty for validator")
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
"github.com/attestantio/go-eth2-client/auto"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -48,10 +47,8 @@ func TestProcess(t *testing.T) {
|
||||
dataIn: &dataIn{
|
||||
eth2Client: eth2Client,
|
||||
slotsPerEpoch: 32,
|
||||
validator: &api.Validator{
|
||||
Index: 0,
|
||||
},
|
||||
epoch: 100,
|
||||
pubKey: "0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95",
|
||||
epoch: 100,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
// ReleaseVersion is the release version of the codebase.
|
||||
// Usually overrideen by tag names when building binaries.
|
||||
var ReleaseVersion = "local build (latest release 1.7.4)"
|
||||
var ReleaseVersion = "local build (latest release 1.7.5)"
|
||||
|
||||
// versionCmd represents the version command
|
||||
var versionCmd = &cobra.Command{
|
||||
|
||||
Reference in New Issue
Block a user