Skip to content

Commit

Permalink
commit
Browse files Browse the repository at this point in the history
  • Loading branch information
pk910 committed Sep 20, 2024
1 parent 5ef03ae commit 9ddca95
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 31 deletions.
8 changes: 8 additions & 0 deletions pkg/coordinator/tasks/generate_deposits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ The `generate_deposits` task focuses on creating deposit transactions and sendin
- **`indexCount`**:\
The total number of validator keys to generate from the mnemonic. This number determines how many unique deposit transactions will be created.

- **`publicKey`**\
The publickey of the validator to generate a deposit for. This is for topup deposits only.

- **`walletPrivkey`**:\
The private key of the wallet from which the deposit will be made. This key is crucial for initiating the deposit transaction.

Expand All @@ -41,6 +44,9 @@ The `generate_deposits` task focuses on creating deposit transactions and sendin
- **`withdrawalCredentials`**:\
Specifies the withdrawal credentials for the deposited ETH. If left empty, it defaults to a standard `0x00...` credentials based on the validator mnemonic.

- **`topUpDeposit`**:\
Specifies if the deposit should be a topup deposit (without withdrawal credentials or signature)

- **`clientPattern`**:\
A regex pattern to select specific client endpoints for sending deposit transactions. If left blank, any available endpoint will be used.

Expand Down Expand Up @@ -76,12 +82,14 @@ Default settings for the `generate_deposits` task:
mnemonic: ""
startIndex: 0
indexCount: 0
publicKey: ""
walletPrivkey: ""
depositContract: ""
depositAmount: 32
depositTxFeeCap: 100000000000
depositTxTipCap: 1000000000
withdrawalCredentials: ""
topUpDeposit: false
clientPattern: ""
excludeClientPattern: ""
awaitReceipt: false
Expand Down
11 changes: 9 additions & 2 deletions pkg/coordinator/tasks/generate_deposits/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ type Config struct {
Mnemonic string `yaml:"mnemonic" json:"mnemonic"`
StartIndex int `yaml:"startIndex" json:"startIndex"`
IndexCount int `yaml:"indexCount" json:"indexCount"`
PublicKey string `yaml:"publicKey" json:"publicKey"`
WalletPrivkey string `yaml:"walletPrivkey" json:"walletPrivkey"`
DepositContract string `yaml:"depositContract" json:"depositContract"`
DepositAmount uint64 `yaml:"depositAmount" json:"depositAmount"`
DepositTxFeeCap int64 `yaml:"depositTxFeeCap" json:"depositTxFeeCap"`
DepositTxTipCap int64 `yaml:"depositTxTipCap" json:"depositTxTipCap"`
WithdrawalCredentials string `yaml:"withdrawalCredentials" json:"withdrawalCredentials"`
TopUpDeposit bool `yaml:"topUpDeposit" json:"topUpDeposit"`
ClientPattern string `yaml:"clientPattern" json:"clientPattern"`
ExcludeClientPattern string `yaml:"excludeClientPattern" json:"excludeClientPattern"`
AwaitReceipt bool `yaml:"awaitReceipt" json:"awaitReceipt"`
Expand All @@ -40,8 +42,13 @@ func (c *Config) Validate() error {
return errors.New("either limitPerSlot or limitTotal or indexCount must be set")
}

if c.Mnemonic == "" {
return errors.New("mnemonic must be set")
switch {
case c.Mnemonic == "" && c.PublicKey == "":
return errors.New("mnemonic or publickey must be set")
case c.Mnemonic != "" && c.PublicKey != "":
return errors.New("only one of mnemonic or publickey must be set")
case c.PublicKey != "" && !c.TopUpDeposit:
return errors.New("publicKey can only be used with topUpDeposit")
}

if c.WalletPrivkey == "" {
Expand Down
80 changes: 51 additions & 29 deletions pkg/coordinator/tasks/generate_deposits/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/protolambda/ztyp/tree"
"github.com/sirupsen/logrus"
"github.com/tyler-smith/go-bip39"
e2types "github.com/wealdtech/go-eth2-types/v2"
util "github.com/wealdtech/go-eth2-util"

depositcontract "github.com/ethpandaops/assertoor/pkg/coordinator/tasks/generate_deposits/deposit_contract"
Expand Down Expand Up @@ -90,12 +91,14 @@ func (t *Task) LoadConfig() error {
return valerr
}

t.valkeySeed, err = t.mnemonicToSeed(config.Mnemonic)
if err != nil {
return err
}
if config.Mnemonic != "" {
t.valkeySeed, err = t.mnemonicToSeed(config.Mnemonic)
if err != nil {
return err
}

t.logger.Infof("validator key seed: 0x%x", t.valkeySeed)
t.logger.Infof("validator key seed: 0x%x", t.valkeySeed)
}

t.walletPrivKey, err = crypto.HexToECDSA(config.WalletPrivkey)
if err != nil {
Expand Down Expand Up @@ -274,20 +277,29 @@ func (t *Task) Execute(ctx context.Context) error {

func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onConfirm func(tx *ethtypes.Transaction, receipt *ethtypes.Receipt)) (*common.BLSPubkey, *ethtypes.Transaction, error) {
clientPool := t.ctx.Scheduler.GetServices().ClientPool()
validatorKeyPath := fmt.Sprintf("m/12381/3600/%d/0/0", accountIdx)
withdrAccPath := fmt.Sprintf("m/12381/3600/%d/0", accountIdx)
validatorSet := t.ctx.Scheduler.GetServices().ClientPool().GetConsensusPool().GetValidatorSet()

validatorPrivkey, err := util.PrivateKeyFromSeedAndPath(t.valkeySeed, validatorKeyPath)
if err != nil {
return nil, nil, fmt.Errorf("failed generating validator key %v: %w", validatorKeyPath, err)
}
var validatorPubkey []byte

validatorSet := t.ctx.Scheduler.GetServices().ClientPool().GetConsensusPool().GetValidatorSet()
var validatorPrivkey *e2types.BLSPrivateKey

var validator *v1.Validator
if t.valkeySeed != nil {
validatorKeyPath := fmt.Sprintf("m/12381/3600/%d/0/0", accountIdx)

validatorPriv, err := util.PrivateKeyFromSeedAndPath(t.valkeySeed, validatorKeyPath)
if err != nil {
return nil, nil, fmt.Errorf("failed generating validator key %v: %w", validatorKeyPath, err)
}

validatorPubkey := validatorPrivkey.PublicKey().Marshal()
t.logger.Debugf("generated validator pubkey %v: 0x%x", validatorKeyPath, validatorPubkey)
validatorPrivkey = validatorPriv

validatorPubkey = validatorPrivkey.PublicKey().Marshal()
t.logger.Debugf("generated validator pubkey %v: 0x%x", validatorKeyPath, validatorPubkey)
} else {
validatorPubkey = ethcommon.FromHex(t.config.PublicKey)
}

var validator *v1.Validator

for _, val := range validatorSet {
if bytes.Equal(val.Validator.PublicKey[:], validatorPubkey) {
Expand All @@ -296,8 +308,10 @@ func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onConfirm
}
}

if validator != nil {
if t.valkeySeed != nil && validator != nil {
t.logger.Warnf("validator already exists on chain (index: %v)", validator.Index)
} else if t.valkeySeed == nil && validator == nil {
t.logger.Warnf("validator not found on chain for topup deposit")
}

var pub common.BLSPubkey
Expand All @@ -306,7 +320,12 @@ func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onConfirm

copy(pub[:], validatorPubkey)

if t.config.WithdrawalCredentials == "" {
switch {
case t.config.TopUpDeposit:
withdrCreds = ethcommon.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
case t.config.WithdrawalCredentials == "":
withdrAccPath := fmt.Sprintf("m/12381/3600/%d/0", accountIdx)

withdrPrivkey, err2 := util.PrivateKeyFromSeedAndPath(t.valkeySeed, withdrAccPath)
if err2 != nil {
return nil, nil, fmt.Errorf("failed generating key %v: %w", withdrAccPath, err2)
Expand All @@ -318,7 +337,7 @@ func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onConfirm
withdrKeyHash := hashing.Hash(withdrPubKey)
withdrCreds = withdrKeyHash[:]
withdrCreds[0] = common.BLS_WITHDRAWAL_PREFIX
} else {
default:
withdrCreds = ethcommon.FromHex(t.config.WithdrawalCredentials)
}

Expand All @@ -328,20 +347,23 @@ func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onConfirm
Amount: common.Gwei(t.config.DepositAmount * 1000000000),
Signature: common.BLSSignature{},
}
msgRoot := data.ToMessage().HashTreeRoot(tree.GetHashFn())

var secKey hbls.SecretKey
if !t.config.TopUpDeposit {
msgRoot := data.ToMessage().HashTreeRoot(tree.GetHashFn())

err = secKey.Deserialize(validatorPrivkey.Marshal())
if err != nil {
return nil, nil, fmt.Errorf("cannot convert validator priv key")
}
var secKey hbls.SecretKey

err := secKey.Deserialize(validatorPrivkey.Marshal())
if err != nil {
return nil, nil, fmt.Errorf("cannot convert validator priv key")
}

genesis := clientPool.GetConsensusPool().GetBlockCache().GetGenesis()
dom := common.ComputeDomain(common.DOMAIN_DEPOSIT, common.Version(genesis.GenesisForkVersion), common.Root{})
msg := common.ComputeSigningRoot(msgRoot, dom)
sig := secKey.SignHash(msg[:])
copy(data.Signature[:], sig.Serialize())
genesis := clientPool.GetConsensusPool().GetBlockCache().GetGenesis()
dom := common.ComputeDomain(common.DOMAIN_DEPOSIT, common.Version(genesis.GenesisForkVersion), common.Root{})
msg := common.ComputeSigningRoot(msgRoot, dom)
sig := secKey.SignHash(msg[:])
copy(data.Signature[:], sig.Serialize())
}

dataRoot := data.HashTreeRoot(tree.GetHashFn())

Expand Down

0 comments on commit 9ddca95

Please sign in to comment.