Skip to content

Commit fd33eed

Browse files
committed
add get_pubkeys_from_mnemonic task
1 parent 0e9670c commit fd33eed

4 files changed

Lines changed: 160 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## `get_pubkeys_from_mnemonic` Task
2+
3+
### Description
4+
The `get_pubkeys_from_mnemonic` task generates public keys from a given mnemonic phrase. This task is essential for setting up and verifying validator identities in scenarios involving multiple validators derived from a single mnemonic, commonly used in Ethereum staking operations.
5+
6+
### Configuration Parameters
7+
8+
- **`mnemonic`**:
9+
The mnemonic phrase used to generate the public keys. This should be a BIP-39 compliant seed phrase that is used to derive Ethereum validator keys.
10+
11+
- **`start_index`**:
12+
The starting index from which to begin deriving public keys. This allows users to specify a segment of the key sequence for generation, rather than starting from the beginning.
13+
14+
- **`count`**:
15+
The number of public keys to generate from the specified `start_index`.
16+
17+
### Outputs
18+
19+
- **`pubkeys`**:
20+
A list of validator public keys derived from the mnemonic. Each key corresponds to a validator index starting from the `start_index` and continuing for `count` keys. This output is crucial for tasks that involve setting up validators, validating identities, or performing any operation that requires public key data.
21+
22+
### Defaults
23+
24+
Default settings for the `get_pubkeys_from_mnemonic` task:
25+
26+
```yaml
27+
- name: get_pubkeys_from_mnemonic
28+
config:
29+
mnemonic: ""
30+
start_index: 0
31+
count: 1
32+
```
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package getpubkeysfrommnemonic
2+
3+
import "fmt"
4+
5+
type Config struct {
6+
Mnemonic string `yaml:"mnemonic" json:"mnemonic"`
7+
StartIndex int `yaml:"start_index" json:"start_index"`
8+
Count int `yaml:"count" json:"count"`
9+
}
10+
11+
func DefaultConfig() Config {
12+
return Config{
13+
Count: 1,
14+
}
15+
}
16+
17+
func (c *Config) Validate() error {
18+
if c.Mnemonic == "" {
19+
return fmt.Errorf("mnemonic is required")
20+
}
21+
22+
return nil
23+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package getpubkeysfrommnemonic
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"strings"
8+
"time"
9+
10+
"github.com/ethpandaops/assertoor/pkg/coordinator/types"
11+
"github.com/sirupsen/logrus"
12+
"github.com/tyler-smith/go-bip39"
13+
util "github.com/wealdtech/go-eth2-util"
14+
)
15+
16+
var (
17+
TaskName = "get_pubkeys_from_mnemonic"
18+
TaskDescriptor = &types.TaskDescriptor{
19+
Name: TaskName,
20+
Description: "Get public keys from mnemonic",
21+
Config: DefaultConfig(),
22+
NewTask: NewTask,
23+
}
24+
)
25+
26+
type Task struct {
27+
ctx *types.TaskContext
28+
options *types.TaskOptions
29+
config Config
30+
logger logrus.FieldLogger
31+
}
32+
33+
func NewTask(ctx *types.TaskContext, options *types.TaskOptions) (types.Task, error) {
34+
return &Task{
35+
ctx: ctx,
36+
options: options,
37+
logger: ctx.Logger.GetLogger(),
38+
}, nil
39+
}
40+
41+
func (t *Task) Config() interface{} {
42+
return t.config
43+
}
44+
45+
func (t *Task) Timeout() time.Duration {
46+
return t.options.Timeout.Duration
47+
}
48+
49+
func (t *Task) LoadConfig() error {
50+
config := DefaultConfig()
51+
52+
// parse static config
53+
if t.options.Config != nil {
54+
if err := t.options.Config.Unmarshal(&config); err != nil {
55+
return fmt.Errorf("error parsing task config for %v: %w", TaskName, err)
56+
}
57+
}
58+
59+
// load dynamic vars
60+
err := t.ctx.Vars.ConsumeVars(&config, t.options.ConfigVars)
61+
if err != nil {
62+
return err
63+
}
64+
65+
// validate config
66+
if err := config.Validate(); err != nil {
67+
return err
68+
}
69+
70+
t.config = config
71+
72+
return nil
73+
}
74+
75+
func (t *Task) Execute(_ context.Context) error {
76+
mnemonic := strings.TrimSpace(t.config.Mnemonic)
77+
if !bip39.IsMnemonicValid(mnemonic) {
78+
return errors.New("mnemonic is not valid")
79+
}
80+
81+
seed := bip39.NewSeed(mnemonic, "")
82+
pubkeys := make([]string, 0, t.config.Count)
83+
84+
for index := t.config.StartIndex; index < t.config.StartIndex+t.config.Count; index++ {
85+
validatorKeyPath := fmt.Sprintf("m/12381/3600/%d/0/0", index)
86+
87+
validatorPriv, err := util.PrivateKeyFromSeedAndPath(seed, validatorKeyPath)
88+
if err != nil {
89+
return fmt.Errorf("failed generating validator key %v: %w", validatorKeyPath, err)
90+
}
91+
92+
validatorPubkey := validatorPriv.PublicKey().Marshal()
93+
pubkey := fmt.Sprintf("0x%x", validatorPubkey)
94+
95+
t.logger.Infof("Generated pubkey %v: %v", index, pubkey)
96+
97+
pubkeys = append(pubkeys, pubkey)
98+
}
99+
100+
t.ctx.Outputs.SetVar("pubkeys", pubkeys)
101+
102+
return nil
103+
}

pkg/coordinator/tasks/tasks.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
generateslashings "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/generate_slashings"
2424
generatetransaction "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/generate_transaction"
2525
getconsensusspecs "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/get_consensus_specs"
26+
getpubkeysfrommnemonic "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/get_pubkeys_from_mnemonic"
2627
getrandommnemonic "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/get_random_mnemonic"
2728
getwalletdetails "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/get_wallet_details"
2829
runcommand "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/run_command"
@@ -56,6 +57,7 @@ var AvailableTaskDescriptors = []*types.TaskDescriptor{
5657
generateexits.TaskDescriptor,
5758
generateslashings.TaskDescriptor,
5859
generatetransaction.TaskDescriptor,
60+
getpubkeysfrommnemonic.TaskDescriptor,
5961
getconsensusspecs.TaskDescriptor,
6062
getrandommnemonic.TaskDescriptor,
6163
getwalletdetails.TaskDescriptor,

0 commit comments

Comments
 (0)