Skip to content

Commit

Permalink
dkg: add deposit data to lock file (#1815)
Browse files Browse the repository at this point in the history
Populates the deposit data field in the generated lock files.

category: feature 
ticket: #1775
  • Loading branch information
corverroos authored Feb 17, 2023
1 parent b16fd01 commit bf0f469
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 186 deletions.
103 changes: 65 additions & 38 deletions cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ func runCreateCluster(ctx context.Context, w io.Writer, conf clusterConfig) erro
return err
}

// Create validators
vals, err := getValidators(pubkeys, shareSets)
if err != nil {
return err
}

// Create operators
ops, err := getOperators(numNodes, conf.ClusterDir)
if err != nil {
Expand All @@ -195,12 +189,26 @@ func runCreateCluster(ctx context.Context, w io.Writer, conf clusterConfig) erro
}
}

network, err := eth2util.ForkVersionToNetwork(def.ForkVersion)
if err != nil {
return err
}

depositDatas, err := createDepositDatas(def.WithdrawalAddresses(), network, secrets)
if err != nil {
return err
}

// Write deposit-data file
if err = writeDepositData(def.WithdrawalAddresses(), conf.ClusterDir, def.ForkVersion, numNodes, secrets); err != nil {
if err = writeDepositData(depositDatas, network, conf.ClusterDir, numNodes); err != nil {
return err
}

vals, err := getValidators(pubkeys, shareSets, depositDatas)
if err != nil {
return err
}

// Create cluster-lock
lock := cluster.Lock{
Definition: def,
Validators: vals,
Expand Down Expand Up @@ -231,41 +239,47 @@ func runCreateCluster(ctx context.Context, w io.Writer, conf clusterConfig) erro
}

// signDepositDatas returns Distributed Validator pubkeys and deposit data signatures corresponding to each pubkey.
func signDepositDatas(secrets []tblsv2.PrivateKey, withdrawalAddresses []string, network string) ([]eth2p0.BLSPubKey, []eth2p0.BLSSignature, error) {
func signDepositDatas(secrets []tblsv2.PrivateKey, withdrawalAddresses []string, network string) ([]eth2p0.DepositData, error) {
if len(secrets) != len(withdrawalAddresses) {
return nil, nil, errors.New("insufficient withdrawal addresses")
return nil, errors.New("insufficient withdrawal addresses")
}

var (
pubkeys []eth2p0.BLSPubKey
signatures []eth2p0.BLSSignature
)
var datas []eth2p0.DepositData
for i, secret := range secrets {
withdrawalAddr, err := eth2util.ChecksumAddress(withdrawalAddresses[i])
if err != nil {
return nil, nil, err
return nil, err
}

pk, err := tblsv2.SecretToPublicKey(secret)
if err != nil {
return nil, nil, errors.Wrap(err, "secret to pubkey")
return nil, errors.Wrap(err, "secret to pubkey")
}

msgRoot, err := deposit.GetMessageSigningRoot(eth2p0.BLSPubKey(pk), withdrawalAddr, network)
msg, err := deposit.NewMessage(eth2p0.BLSPubKey(pk), withdrawalAddr)
if err != nil {
return nil, nil, err
return nil, err
}

sig, err := tblsv2.Sign(secret, msgRoot[:])
sigRoot, err := deposit.GetMessageSigningRoot(msg, network)
if err != nil {
return nil, nil, err
return nil, err
}

sig, err := tblsv2.Sign(secret, sigRoot[:])
if err != nil {
return nil, err
}

pubkeys = append(pubkeys, eth2p0.BLSPubKey(pk))
signatures = append(signatures, tblsconv2.SigToETH2(sig))
datas = append(datas, eth2p0.DepositData{
PublicKey: msg.PublicKey,
WithdrawalCredentials: msg.WithdrawalCredentials,
Amount: msg.Amount,
Signature: tblsconv2.SigToETH2(sig),
})
}

return pubkeys, signatures, nil
return datas, nil
}

// getTSSShares splits the secrets and returns the threshold key shares.
Expand Down Expand Up @@ -335,25 +349,19 @@ func getKeys(splitKeys bool, splitKeysDir string, numDVs int) ([]tblsv2.PrivateK
return secrets, nil
}

// writeDepositData writes deposit data to disk for the DVs for all peers in a cluster.
func writeDepositData(withdrawalAddresses []string, clusterDir string, forkVersion []byte, numNodes int, secrets []tblsv2.PrivateKey) error {
// createDepositDatas creates a slice of deposit datas using the provided parameters and returns it.
func createDepositDatas(withdrawalAddresses []string, network string, secrets []tblsv2.PrivateKey) ([]eth2p0.DepositData, error) {
if len(secrets) != len(withdrawalAddresses) {
return errors.New("insufficient withdrawal addresses")
}

network, err := eth2util.ForkVersionToNetwork(forkVersion)
if err != nil {
return err
return nil, errors.New("insufficient withdrawal addresses")
}

// Create deposit message signatures
pubkeys, sigs, err := signDepositDatas(secrets, withdrawalAddresses, network)
if err != nil {
return err
}
return signDepositDatas(secrets, withdrawalAddresses, network)
}

// writeDepositData writes deposit data to disk for the DVs for all peers in a cluster.
func writeDepositData(depositDatas []eth2p0.DepositData, network string, clusterDir string, numNodes int) error {
// Serialize the deposit data into bytes
bytes, err := deposit.MarshalDepositData(pubkeys, sigs, withdrawalAddresses, network)
bytes, err := deposit.MarshalDepositData(depositDatas, network)
if err != nil {
return err
}
Expand Down Expand Up @@ -395,7 +403,7 @@ func writeLock(lock cluster.Lock, clusterDir string, numNodes int, shareSets [][

// getValidators returns distributed validators from the provided dv public keys and keyshares.
// It creates new peers from the provided config and saves validator keys to disk for each peer.
func getValidators(dvsPubkeys []tblsv2.PublicKey, dvPrivShares [][]tblsv2.PrivateKey) ([]cluster.DistValidator, error) {
func getValidators(dvsPubkeys []tblsv2.PublicKey, dvPrivShares [][]tblsv2.PrivateKey, depositDatas []eth2p0.DepositData) ([]cluster.DistValidator, error) {
var vals []cluster.DistValidator
for idx, dv := range dvsPubkeys {
dv := dv
Expand All @@ -410,9 +418,28 @@ func getValidators(dvsPubkeys []tblsv2.PublicKey, dvPrivShares [][]tblsv2.Privat
pubshares = append(pubshares, pubk[:])
}

depositIdx := -1
for i, dd := range depositDatas {
if [48]byte(dd.PublicKey) != dv {
continue
}
depositIdx = i

break
}
if depositIdx == -1 {
return nil, errors.New("deposit data not found")
}

vals = append(vals, cluster.DistValidator{
PubKey: dv[:],
PubShares: pubshares,
DepositData: cluster.DepositData{
PubKey: depositDatas[depositIdx].PublicKey[:],
WithdrawalCredentials: depositDatas[depositIdx].WithdrawalCredentials,
Amount: int(depositDatas[depositIdx].Amount),
Signature: depositDatas[depositIdx].Signature[:],
},
})
}

Expand Down
17 changes: 2 additions & 15 deletions dkg/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/obolnetwork/charon/app/log"
"github.com/obolnetwork/charon/app/z"
"github.com/obolnetwork/charon/cluster"
"github.com/obolnetwork/charon/eth2util"
"github.com/obolnetwork/charon/eth2util/deposit"
"github.com/obolnetwork/charon/eth2util/keymanager"
"github.com/obolnetwork/charon/eth2util/keystore"
Expand Down Expand Up @@ -160,21 +159,9 @@ func writeLock(datadir string, lock cluster.Lock) error {
}

// writeDepositData writes deposit data file to disk.
func writeDepositData(pubkeys []eth2p0.BLSPubKey, depositDataSigs []eth2p0.BLSSignature, withdrawalAddresses []string, network string, dataDir string) error {
if len(pubkeys) != len(withdrawalAddresses) {
return errors.New("insufficient withdrawal addresses")
}

for i := 0; i < len(withdrawalAddresses); i++ {
var err error
withdrawalAddresses[i], err = eth2util.ChecksumAddress(withdrawalAddresses[i])
if err != nil {
return err
}
}

func writeDepositData(depositDatas []eth2p0.DepositData, network string, dataDir string) error {
// Serialize the deposit data into bytes
bytes, err := deposit.MarshalDepositData(pubkeys, depositDataSigs, withdrawalAddresses, network)
bytes, err := deposit.MarshalDepositData(depositDatas, network)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit bf0f469

Please sign in to comment.