mirror of
https://github.com/wealdtech/ethdo.git
synced 2026-01-08 21:48:05 -05:00
Merge branch 'master' into electra_merge
# Conflicts: # CHANGELOG.md
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
electra:
|
electra:
|
||||||
- update to handle versioned attestations from go-eth2-client electra branch
|
- update to handle versioned attestations from go-eth2-client electra branch
|
||||||
|
|
||||||
|
1.36.6:
|
||||||
|
- allow specification of blockid for validator info
|
||||||
|
- validator depositdata orders deposits from an HD wallet by path
|
||||||
|
|
||||||
|
1.36.5:
|
||||||
|
- avoid corner case mnemonic derivation with 25th word
|
||||||
|
|
||||||
1.36.2:
|
1.36.2:
|
||||||
- avoid crash when signing and verifing signatures using keys rather than accounts
|
- avoid crash when signing and verifing signatures using keys rather than accounts
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
type dataOut struct {
|
type dataOut struct {
|
||||||
format string
|
format string
|
||||||
account string
|
account string
|
||||||
|
path string
|
||||||
validatorPubKey *spec.BLSPubKey
|
validatorPubKey *spec.BLSPubKey
|
||||||
withdrawalCredentials []byte
|
withdrawalCredentials []byte
|
||||||
amount spec.Gwei
|
amount spec.Gwei
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||||
@@ -80,7 +82,7 @@ func process(data *dataIn) ([]*dataOut, error) {
|
|||||||
copy(depositDataRoot[:], root[:])
|
copy(depositDataRoot[:], root[:])
|
||||||
|
|
||||||
validatorWallet := validatorAccount.(e2wtypes.AccountWalletProvider).Wallet()
|
validatorWallet := validatorAccount.(e2wtypes.AccountWalletProvider).Wallet()
|
||||||
results = append(results, &dataOut{
|
result := &dataOut{
|
||||||
format: data.format,
|
format: data.format,
|
||||||
account: fmt.Sprintf("%s/%s", validatorWallet.Name(), validatorAccount.Name()),
|
account: fmt.Sprintf("%s/%s", validatorWallet.Name(), validatorAccount.Name()),
|
||||||
validatorPubKey: &pubKey,
|
validatorPubKey: &pubKey,
|
||||||
@@ -90,8 +92,53 @@ func process(data *dataIn) ([]*dataOut, error) {
|
|||||||
forkVersion: data.forkVersion,
|
forkVersion: data.forkVersion,
|
||||||
depositMessageRoot: &depositMessageRoot,
|
depositMessageRoot: &depositMessageRoot,
|
||||||
depositDataRoot: &depositDataRoot,
|
depositDataRoot: &depositDataRoot,
|
||||||
|
}
|
||||||
|
if pathProvider, isPathProvider := validatorAccount.(e2wtypes.AccountPathProvider); isPathProvider {
|
||||||
|
result.path = pathProvider.Path()
|
||||||
|
}
|
||||||
|
results = append(results, result)
|
||||||
|
}
|
||||||
|
if len(results) == 0 {
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order the results
|
||||||
|
if results[0].path != "" {
|
||||||
|
// Order accounts by their path components.
|
||||||
|
sort.Slice(results, func(i int, j int) bool {
|
||||||
|
iBits := strings.Split(results[i].path, "/")
|
||||||
|
jBits := strings.Split(results[j].path, "/")
|
||||||
|
for index := range iBits {
|
||||||
|
if iBits[index] == "m" && jBits[index] == "m" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(jBits) <= index {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
iBit, err := strconv.ParseUint(iBits[index], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
jBit, err := strconv.ParseUint(jBits[index], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if iBit < jBit {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if iBit > jBit {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(jBits) > len(iBits)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Order accounts by their name.
|
||||||
|
sort.Slice(results, func(i int, j int) bool {
|
||||||
|
return strings.Compare(results[i].account, results[j].account) < 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright © 2020 - 2022 Weald Technology Trading
|
// Copyright © 2020 - 2025 Weald Technology Trading
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
@@ -67,7 +67,7 @@ In quiet mode this will return 0 if the validator information can be obtained, o
|
|||||||
os.Exit(_exitFailure)
|
os.Exit(_exitFailure)
|
||||||
}
|
}
|
||||||
|
|
||||||
validator, err := util.ParseValidator(ctx, eth2Client.(eth2client.ValidatorsProvider), viper.GetString("validator"), "head")
|
validator, err := util.ParseValidator(ctx, eth2Client.(eth2client.ValidatorsProvider), viper.GetString("validator"), viper.GetString("blockid"))
|
||||||
errCheck(err, "Failed to obtain validator")
|
errCheck(err, "Failed to obtain validator")
|
||||||
|
|
||||||
if viper.GetBool("verbose") {
|
if viper.GetBool("verbose") {
|
||||||
@@ -185,7 +185,8 @@ func graphData(network string, validatorPubKey []byte) (uint64, spec.Gwei, error
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
validatorCmd.AddCommand(validatorInfoCmd)
|
validatorCmd.AddCommand(validatorInfoCmd)
|
||||||
validatorInfoCmd.Flags().String("validator", "", "Public key for which to obtain status")
|
validatorInfoCmd.Flags().String("validator", "", "ID of the validator")
|
||||||
|
validatorInfoCmd.Flags().String("blockid", "head", "the block at which to fetch the information")
|
||||||
validatorFlags(validatorInfoCmd)
|
validatorFlags(validatorInfoCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,4 +194,7 @@ func validatorInfoBindings(cmd *cobra.Command) {
|
|||||||
if err := viper.BindPFlag("validator", cmd.Flags().Lookup("validator")); err != nil {
|
if err := viper.BindPFlag("validator", cmd.Flags().Lookup("validator")); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
if err := viper.BindPFlag("blockid", cmd.Flags().Lookup("blockid")); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright © 2019 - 2024 Weald Technology Trading.
|
// Copyright © 2019 - 2025 Weald Technology Trading.
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
|
|
||||||
// ReleaseVersion is the release version of the codebase.
|
// ReleaseVersion is the release version of the codebase.
|
||||||
// Usually overridden by tag names when building binaries.
|
// Usually overridden by tag names when building binaries.
|
||||||
var ReleaseVersion = "local build (latest release 1.36.4)"
|
var ReleaseVersion = "local build (latest release 1.36.6)"
|
||||||
|
|
||||||
// versionCmd represents the version command.
|
// versionCmd represents the version command.
|
||||||
var versionCmd = &cobra.Command{
|
var versionCmd = &cobra.Command{
|
||||||
|
|||||||
@@ -682,6 +682,7 @@ $ ethdo validator exit --private-key=0x01e748d098d3bcb477d636f19d510399ae18205fa
|
|||||||
`ethdo validator info` provides information for a given validator. Options include:
|
`ethdo validator info` provides information for a given validator. Options include:
|
||||||
|
|
||||||
- `validator`: the validator for which to obtain information, as a [validator specifier](https://github.com/wealdtech/ethdo#validator-specifier)
|
- `validator`: the validator for which to obtain information, as a [validator specifier](https://github.com/wealdtech/ethdo#validator-specifier)
|
||||||
|
- `blockid`: the ID (slot, root, 'head') of the block at which to obtain information
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ ethdo validator info --validator=Validators/1
|
$ ethdo validator info --validator=Validators/1
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// Copyright © 2020 - 2025 Weald Technology Trading
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
@@ -56,6 +57,12 @@ func ParseAccount(ctx context.Context,
|
|||||||
account, err = parseAccountFromKeystorePath(ctx, accountStr, supplementary, unlock)
|
account, err = parseAccountFromKeystorePath(ctx, accountStr, supplementary, unlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
if strings.Count(accountStr, " ") > 7 {
|
||||||
|
// It is also possible that this is a mnemonic with "/" in the additional word, so try that as well.
|
||||||
|
account, err = parseAccountFromMnemonic(ctx, accountStr, supplementary, unlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright © 2020 Weald Technology Trading
|
// Copyright © 2020 - 2025 Weald Technology Trading
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
@@ -75,6 +75,18 @@ func TestParseAccount(t *testing.T) {
|
|||||||
supplementary: []string{"m/12381/3600/0/0"},
|
supplementary: []string{"m/12381/3600/0/0"},
|
||||||
expectedPubkey: "0x99b1f1d84d76185466d86c34bde1101316afddae76217aa86cd066979b19858c2c9d9e56eebc1e067ac54277a61790db",
|
expectedPubkey: "0x99b1f1d84d76185466d86c34bde1101316afddae76217aa86cd066979b19858c2c9d9e56eebc1e067ac54277a61790db",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ShortMnemonic",
|
||||||
|
accountStr: "aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban art",
|
||||||
|
supplementary: []string{"m/12381/3600/0/0"},
|
||||||
|
expectedPubkey: "0x99b1f1d84d76185466d86c34bde1101316afddae76217aa86cd066979b19858c2c9d9e56eebc1e067ac54277a61790db",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ShortMnemonicWith25th",
|
||||||
|
accountStr: `aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban aban art !"£$%^&*()<>,./?;:'@#~]}[{-_=+`,
|
||||||
|
supplementary: []string{"m/12381/3600/0/0"},
|
||||||
|
expectedPubkey: "0xa9264986cbde1f05d4c37ed57b03c476f360f0c64cf4a41752c3d352f60caebb6555c5522f0f962962a619336e1539f2",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "MnemonicUnlocked",
|
name: "MnemonicUnlocked",
|
||||||
accountStr: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
accountStr: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||||
|
|||||||
Reference in New Issue
Block a user