From 005eed1360f71d352ff0f87c6487d327144efbf2 Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Tue, 28 Jan 2025 19:32:01 +0000 Subject: [PATCH 1/5] Avoid corner case when deriving from mnemonic. --- CHANGELOG.md | 3 +++ cmd/version.go | 2 +- util/account.go | 7 +++++++ util/account_test.go | 14 +++++++++++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9278187..44f554b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +1.36.5: + - avoid corner case mnemonic derivation with 25th word + 1.36.2: - avoid crash when signing and verifing signatures using keys rather than accounts diff --git a/cmd/version.go b/cmd/version.go index de785fd..8262579 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -24,7 +24,7 @@ import ( // ReleaseVersion is the release version of the codebase. // 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.5)" // versionCmd represents the version command. var versionCmd = &cobra.Command{ diff --git a/util/account.go b/util/account.go index 68032b2..d0f10ea 100644 --- a/util/account.go +++ b/util/account.go @@ -1,3 +1,4 @@ +// Copyright © 2020 - 2025 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 @@ -56,6 +57,12 @@ func ParseAccount(ctx context.Context, 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 { return nil, err } diff --git a/util/account_test.go b/util/account_test.go index d74e2b5..6b5cfd6 100644 --- a/util/account_test.go +++ b/util/account_test.go @@ -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"); // you may not use this file except in compliance with the License. // 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"}, 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", 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", From 5d95e93b761f08f2bead36e1073d5aa60c954a36 Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Fri, 31 Jan 2025 17:03:48 +0000 Subject: [PATCH 2/5] Allow blockid for validator info. --- CHANGELOG.md | 3 +++ cmd/validatorinfo.go | 10 +++++++--- cmd/version.go | 4 ++-- docs/usage.md | 1 + 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44f554b..4f7eb2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +1.36.6: + - allow specification of blockid for validator info + 1.36.5: - avoid corner case mnemonic derivation with 25th word diff --git a/cmd/validatorinfo.go b/cmd/validatorinfo.go index 401373a..83b9b65 100644 --- a/cmd/validatorinfo.go +++ b/cmd/validatorinfo.go @@ -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"); // you may not use this file except in compliance with the License. // 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) } - 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") if viper.GetBool("verbose") { @@ -185,7 +185,8 @@ func graphData(network string, validatorPubKey []byte) (uint64, spec.Gwei, error func init() { 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) } @@ -193,4 +194,7 @@ func validatorInfoBindings(cmd *cobra.Command) { if err := viper.BindPFlag("validator", cmd.Flags().Lookup("validator")); err != nil { panic(err) } + if err := viper.BindPFlag("blockid", cmd.Flags().Lookup("blockid")); err != nil { + panic(err) + } } diff --git a/cmd/version.go b/cmd/version.go index 8262579..f412cce 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -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"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -24,7 +24,7 @@ import ( // ReleaseVersion is the release version of the codebase. // Usually overridden by tag names when building binaries. -var ReleaseVersion = "local build (latest release 1.36.5)" +var ReleaseVersion = "local build (latest release 1.36.6)" // versionCmd represents the version command. var versionCmd = &cobra.Command{ diff --git a/docs/usage.md b/docs/usage.md index 65c818e..5d1d74a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -682,6 +682,7 @@ $ ethdo validator exit --private-key=0x01e748d098d3bcb477d636f19d510399ae18205fa `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) +- `blockid`: the ID (slot, root, 'head') of the block at which to obtain information ```sh $ ethdo validator info --validator=Validators/1 From 3e173f141e6ec82c103ce3328c656422f2d7b850 Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Fri, 31 Jan 2025 17:04:50 +0000 Subject: [PATCH 3/5] Order deposit data from HD wallet accounts by path. --- CHANGELOG.md | 1 + cmd/validator/depositdata/output.go | 1 + cmd/validator/depositdata/process.go | 49 +++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f7eb2b..b620dcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 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 diff --git a/cmd/validator/depositdata/output.go b/cmd/validator/depositdata/output.go index ba8f26f..a5ccdc2 100644 --- a/cmd/validator/depositdata/output.go +++ b/cmd/validator/depositdata/output.go @@ -24,6 +24,7 @@ import ( type dataOut struct { format string account string + path string validatorPubKey *spec.BLSPubKey withdrawalCredentials []byte amount spec.Gwei diff --git a/cmd/validator/depositdata/process.go b/cmd/validator/depositdata/process.go index dd29776..a9f5ef4 100644 --- a/cmd/validator/depositdata/process.go +++ b/cmd/validator/depositdata/process.go @@ -17,6 +17,8 @@ import ( "context" "encoding/hex" "fmt" + "sort" + "strconv" "strings" spec "github.com/attestantio/go-eth2-client/spec/phase0" @@ -80,7 +82,7 @@ func process(data *dataIn) ([]*dataOut, error) { copy(depositDataRoot[:], root[:]) validatorWallet := validatorAccount.(e2wtypes.AccountWalletProvider).Wallet() - results = append(results, &dataOut{ + result := &dataOut{ format: data.format, account: fmt.Sprintf("%s/%s", validatorWallet.Name(), validatorAccount.Name()), validatorPubKey: &pubKey, @@ -90,8 +92,53 @@ func process(data *dataIn) ([]*dataOut, error) { forkVersion: data.forkVersion, depositMessageRoot: &depositMessageRoot, 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 } From d7d9c66052bfb72512344c0498020d4e9d996d98 Mon Sep 17 00:00:00 2001 From: Jim McDonald Date: Fri, 31 Jan 2025 17:14:12 +0000 Subject: [PATCH 4/5] Update Dockerfile. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c5fd3cd..175bac9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.22-bookworm as builder +FROM golang:1.23-bookworm AS builder WORKDIR /app From f6e23d803b89ad32a4bd1772eebc704bc6c20263 Mon Sep 17 00:00:00 2001 From: Chris Berry Date: Thu, 6 Feb 2025 16:43:26 +0000 Subject: [PATCH 5/5] Update go-eth2-client --- go.mod | 8 ++++---- go.sum | 17 ++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index c38bb07..18b7c33 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.7 toolchain go1.23.2 require ( - github.com/attestantio/go-eth2-client v0.23.1-0.20250127091537-251e60f042d4 + github.com/attestantio/go-eth2-client v0.24.0 github.com/ferranbt/fastssz v0.1.4 github.com/gofrs/uuid v4.4.0+incompatible github.com/google/uuid v1.6.0 @@ -62,7 +62,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/magiconair/properties v1.8.9 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/minio/highwayhash v1.0.3 // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -92,11 +92,11 @@ require ( go.opentelemetry.io/otel/metric v1.33.0 // indirect go.opentelemetry.io/otel/trace v1.33.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb // indirect google.golang.org/grpc v1.69.2 // indirect diff --git a/go.sum b/go.sum index 7836a12..c749017 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ -github.com/attestantio/go-eth2-client v0.22.0 h1:KmF9kPNNWWGfE7l1BP7pXps4EOXgKnYeFGR0/WbyFhY= -github.com/attestantio/go-eth2-client v0.22.0/go.mod h1:d7ZPNrMX8jLfIgML5u7QZxFo2AukLM+5m08iMaLdqb8= -github.com/attestantio/go-eth2-client v0.23.1-0.20250127091537-251e60f042d4 h1:ePstQwO3RoDX2am93bvtUNLsMtxlikx9kPJDdzr9sk8= -github.com/attestantio/go-eth2-client v0.23.1-0.20250127091537-251e60f042d4/go.mod h1:vy5jU/uDZ2+RcVzq5BfnG+bQ3/6uu9DGwCrGsPtjJ1A= +github.com/attestantio/go-eth2-client v0.24.0 h1:lGVbcnhlBwRglt1Zs56JOCgXVyLWKFZOmZN8jKhE7Ws= +github.com/attestantio/go-eth2-client v0.24.0/go.mod h1:/KTLN3WuH1xrJL7ZZrpBoWM1xCCihnFbzequD5L+83o= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -78,8 +76,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -215,8 +214,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -231,8 +230,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=