Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pkg/tasks/generate_deposits/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Config struct {
AwaitReceipt bool `yaml:"awaitReceipt" json:"awaitReceipt" desc:"Wait for transaction receipts on the execution layer before completing."`
FailOnReject bool `yaml:"failOnReject" json:"failOnReject" desc:"Fail the task if any deposit transaction is rejected."`
AwaitInclusion bool `yaml:"awaitInclusion" json:"awaitInclusion" desc:"Wait for deposits to be included in beacon blocks before completing."`
InvalidSigPercent int `yaml:"invalidSigPercent" json:"invalidSigPercent" desc:"Random percentage (0-100) of deposits to generate with corrupted signatures."`

DepositTransactionsResultVar string `yaml:"depositTransactionsResultVar" json:"depositTransactionsResultVar" deprecated:"true" desc:"Deprecated: Use task outputs instead."`
DepositReceiptsResultVar string `yaml:"depositReceiptsResultVar" json:"depositReceiptsResultVar" deprecated:"true" desc:"Deprecated: Use task outputs instead."`
Expand Down Expand Up @@ -64,5 +65,9 @@ func (c *Config) Validate() error {
return errors.New("depositAmount must be > 0")
}

if c.InvalidSigPercent < 0 || c.InvalidSigPercent > 100 {
return errors.New("invalidSigPercent must be in range 0-100")
}

return nil
}
68 changes: 53 additions & 15 deletions pkg/tasks/generate_deposits/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"crypto/ecdsa"
cryptorand "crypto/rand"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -515,21 +516,8 @@ func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onComplet
Signature: common.BLSSignature{},
}

if !t.config.TopUpDeposit {
msgRoot := depositData.ToMessage().HashTreeRoot(tree.GetHashFn())

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(depositData.Signature[:], sig.Serialize())
if err := t.signDepositData(&depositData, validatorPrivkey); err != nil {
return nil, nil, err
}

dataRoot := depositData.HashTreeRoot(tree.GetHashFn())
Expand Down Expand Up @@ -620,6 +608,56 @@ func (t *Task) generateDeposit(ctx context.Context, accountIdx uint64, onComplet
return &pub, tx, nil
}

func (t *Task) signDepositData(depositData *common.DepositData, validatorPrivkey *e2types.BLSPrivateKey) error {
if t.config.TopUpDeposit {
return nil
}

useInvalid, err := t.shouldUseInvalidSignature()
if err != nil {
return err
}

if useInvalid {
if _, err := cryptorand.Read(depositData.Signature[:]); err != nil {
return fmt.Errorf("failed to generate random invalid signature: %w", err)
}

t.logger.Debugf("generated deposit with invalid (random) signature for pubkey 0x%x", depositData.Pubkey)

return nil
}

msgRoot := depositData.ToMessage().HashTreeRoot(tree.GetHashFn())

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

clientPool := t.ctx.Scheduler.GetServices().ClientPool()
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(depositData.Signature[:], sig.Serialize())

return nil
}

func (t *Task) shouldUseInvalidSignature() (bool, error) {
if t.config.InvalidSigPercent <= 0 {
return false, nil
}

var b [1]byte
if _, err := cryptorand.Read(b[:]); err != nil {
return false, fmt.Errorf("failed to read random byte: %w", err)
}

return int(b[0])%100 < t.config.InvalidSigPercent, nil
}

func (t *Task) mnemonicToSeed(mnemonic string) (seed []byte, err error) {
mnemonic = strings.TrimSpace(mnemonic)
if !bip39.IsMnemonicValid(mnemonic) {
Expand Down