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
28 changes: 16 additions & 12 deletions cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func newCreateClusterCmd(runFunc func(context.Context, io.Writer, clusterConfig)

bindClusterFlags(cmd.Flags(), &conf)
bindInsecureFlags(cmd.Flags(), &conf.InsecureKeys)
bindNetworkFlags(cmd.Flags(), &conf.Network, &conf.testnetConfig)

wrapPreRunE(cmd, func(cmd *cobra.Command, _ []string) error {
thresholdPresent := cmd.Flags().Lookup("threshold").Changed
Expand Down Expand Up @@ -142,16 +143,11 @@ func bindClusterFlags(flags *pflag.FlagSet, config *clusterConfig) {
flags.IntVar(&config.Threshold, "threshold", 0, "Optional override of threshold required for signature reconstruction. Defaults to ceil(n*2/3) if zero. Warning, non-default values decrease security.")
flags.StringSliceVar(&config.FeeRecipientAddrs, "fee-recipient-addresses", nil, "Comma separated list of Ethereum addresses of the fee recipient for each validator. Either provide a single fee recipient address or fee recipient addresses for each validator.")
flags.StringSliceVar(&config.WithdrawalAddrs, "withdrawal-addresses", nil, "Comma separated list of Ethereum addresses to receive the returned stake and accrued rewards for each validator. Either provide a single withdrawal address or withdrawal addresses for each validator.")
flags.StringVar(&config.Network, "network", "", "Ethereum network to create validators for. Options: mainnet, goerli, sepolia, hoodi, holesky, gnosis, chiado.")
flags.IntVar(&config.NumDVs, "num-validators", 0, "The number of distributed validators needed in the cluster.")
flags.BoolVar(&config.SplitKeys, "split-existing-keys", false, "Split an existing validator's private key into a set of distributed validator private key shares. Does not re-create deposit data for this key.")
flags.StringVar(&config.SplitKeysDir, "split-keys-dir", "", "Directory containing keys to split. Expects keys in keystore-*.json and passwords in keystore-*.txt. Requires --split-existing-keys.")
flags.StringVar(&config.PublishAddr, "publish-address", "https://api.obol.tech/v1", "The URL to publish the lock file to.")
flags.BoolVar(&config.Publish, "publish", false, "Publish lock file to obol-api.")
flags.StringVar(&config.testnetConfig.Name, "testnet-name", "", "Name of the custom test network.")
flags.StringVar(&config.testnetConfig.GenesisForkVersionHex, "testnet-fork-version", "", "Genesis fork version of the custom test network (in hex).")
flags.Uint64Var(&config.testnetConfig.ChainID, "testnet-chain-id", 0, "Chain ID of the custom test network.")
flags.Int64Var(&config.testnetConfig.GenesisTimestamp, "testnet-genesis-timestamp", 0, "Genesis timestamp of the custom test network.")
flags.IntSliceVar(&config.DepositAmounts, "deposit-amounts", nil, "List of partial deposit amounts (integers) in ETH. Values must sum up to at least 32ETH.")
flags.StringVar(&config.ConsensusProtocol, "consensus-protocol", "", "Preferred consensus protocol name for the cluster. Selected automatically when not specified.")
flags.UintVar(&config.TargetGasLimit, "target-gas-limit", 60000000, "Preferred target gas limit for transactions.")
Expand All @@ -160,6 +156,14 @@ func bindClusterFlags(flags *pflag.FlagSet, config *clusterConfig) {
flags.BoolVar(&config.Zipped, "zipped", false, "Create a tar archive compressed with gzip of the cluster directory after creation.")
}

func bindNetworkFlags(flags *pflag.FlagSet, network *string, testnetConfig *eth2util.Network) {
flags.StringVar(network, "network", "mainnet", "Ethereum network to create validators for. Options: mainnet, goerli, sepolia, hoodi, holesky, gnosis, chiado.")
flags.StringVar(&testnetConfig.Name, "testnet-name", "", "Name of the custom test network.")
flags.StringVar(&testnetConfig.GenesisForkVersionHex, "testnet-fork-version", "", "Genesis fork version of the custom test network (in hex).")
flags.Uint64Var(&testnetConfig.ChainID, "testnet-chain-id", 0, "Chain ID of the custom test network.")
flags.Int64Var(&testnetConfig.GenesisTimestamp, "testnet-genesis-timestamp", 0, "Genesis timestamp of the custom test network.")
}

func bindInsecureFlags(flags *pflag.FlagSet, insecureKeys *bool) {
flags.BoolVar(insecureKeys, "insecure-keys", false, "Generates insecure keystore files. This should never be used. It is not supported on mainnet.")
}
Expand Down Expand Up @@ -377,7 +381,7 @@ func validateCreateConfig(ctx context.Context, conf clusterConfig) error {
}

// Check for valid network configuration.
if err := validateNetworkConfig(conf); err != nil {
if err := validateNetworkConfig(conf.Network, conf.testnetConfig); err != nil {
return errors.Wrap(err, "get network config")
}

Expand Down Expand Up @@ -1219,19 +1223,19 @@ func builderRegistrationFromETH2(reg core.VersionedSignedValidatorRegistration)
}

// validateNetworkConfig returns an error if the network configuration is invalid in the given cluster configuration.
func validateNetworkConfig(conf clusterConfig) error {
if conf.Network != "" {
if eth2util.ValidNetwork(conf.Network) {
func validateNetworkConfig(network string, testnet eth2util.Network) error {
if network != "" {
if eth2util.ValidNetwork(network) {
return nil
}

return errors.New("invalid network specified", z.Str("network", conf.Network))
return errors.New("invalid network specified", z.Str("network", network))
}

// Check if custom testnet configuration is provided.
if conf.testnetConfig.IsNonZero() {
if testnet.IsNonZero() {
// Add testnet config to supported networks.
eth2util.AddTestNetwork(conf.testnetConfig)
eth2util.AddTestNetwork(testnet)

return nil
}
Expand Down
25 changes: 17 additions & 8 deletions cmd/createdkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type createDKGConfig struct {
Publish bool
PublishAddress string
OperatorsAddresses []string

testnetConfig eth2util.Network
}

func newCreateDKGCmd(runFunc func(context.Context, createDKGConfig) error) *cobra.Command {
Expand All @@ -61,6 +63,7 @@ func newCreateDKGCmd(runFunc func(context.Context, createDKGConfig) error) *cobr
}

bindCreateDKGFlags(cmd, &config)
bindNetworkFlags(cmd.Flags(), &config.Network, &config.testnetConfig)

wrapPreRunE(cmd, func(cmd *cobra.Command, _ []string) error {
thresholdPresent := cmd.Flags().Lookup("threshold").Changed
Expand Down Expand Up @@ -99,7 +102,6 @@ func bindCreateDKGFlags(cmd *cobra.Command, config *createDKGConfig) {
cmd.Flags().IntVarP(&config.Threshold, "threshold", "t", 0, "Optional override of threshold required for signature reconstruction. Defaults to ceil(n*2/3) if zero. Warning, non-default values decrease security.")
cmd.Flags().StringSliceVar(&config.FeeRecipientAddrs, "fee-recipient-addresses", nil, "Comma separated list of Ethereum addresses of the fee recipient for each validator. Either provide a single fee recipient address or fee recipient addresses for each validator.")
cmd.Flags().StringSliceVar(&config.WithdrawalAddrs, "withdrawal-addresses", nil, "Comma separated list of Ethereum addresses to receive the returned stake and accrued rewards for each validator. Either provide a single withdrawal address or withdrawal addresses for each validator.")
cmd.Flags().StringVar(&config.Network, "network", defaultNetwork, "Ethereum network to create validators for. Options: mainnet, goerli, sepolia, hoodi, holesky, gnosis, chiado.")
cmd.Flags().StringVar(&config.DKGAlgo, "dkg-algorithm", "default", "DKG algorithm to use; default, frost or pedersen.")
cmd.Flags().IntSliceVar(&config.DepositAmounts, "deposit-amounts", nil, "List of partial deposit amounts (integers) in ETH. Values must sum up to at least 32ETH.")
cmd.Flags().StringSliceVar(&config.OperatorENRs, "operator-enrs", nil, "Comma-separated list of each operator's Charon ENR address.")
Expand Down Expand Up @@ -131,7 +133,7 @@ func runCreateDKG(ctx context.Context, conf createDKGConfig) (err error) {
operatorsLen = len(conf.OperatorsAddresses)
}

if err = validateDKGConfig(operatorsLen, conf.Network, conf.DepositAmounts, conf.ConsensusProtocol, conf.Compounding); err != nil {
if err = validateDKGConfig(operatorsLen, conf.Network, conf.testnetConfig, conf.DepositAmounts, conf.ConsensusProtocol, conf.Compounding); err != nil {
return err
}

Expand Down Expand Up @@ -187,9 +189,16 @@ func runCreateDKG(ctx context.Context, conf createDKGConfig) (err error) {
log.Warn(ctx, "Non standard `--threshold` flag provided, this will affect cluster safety", nil, z.Int("threshold", conf.Threshold), z.Int("safe_threshold", safeThreshold))
}

forkVersion, err := eth2util.NetworkToForkVersion(conf.Network)
if err != nil {
return err
var forkVersion string
if conf.Network != "" {
forkVersion, err = eth2util.NetworkToForkVersion(conf.Network)
if err != nil {
return err
}
} else if conf.testnetConfig.GenesisForkVersionHex != "" {
forkVersion = conf.testnetConfig.GenesisForkVersionHex
} else {
return errors.New("network not specified, missing --network or --testnet-fork-version")
}

var privKey *k1.PrivateKey
Expand Down Expand Up @@ -284,14 +293,14 @@ func validateWithdrawalAddrs(addrs []string, network string) error {
}

// validateDKGConfig returns an error if any of the provided config parameter is invalid.
func validateDKGConfig(numOperators int, network string, depositAmounts []int, consensusProtocol string, compounding bool) error {
func validateDKGConfig(numOperators int, network string, testnet eth2util.Network, depositAmounts []int, consensusProtocol string, compounding bool) error {
// Don't allow cluster size to be less than 3.
if numOperators < minNodes {
return errors.New("number of operators is below minimum", z.Int("operators", numOperators), z.Int("min", minNodes))
}

if !eth2util.ValidNetwork(network) {
return errors.New("unsupported network", z.Str("network", network))
if err := validateNetworkConfig(network, testnet); err != nil {
return errors.Wrap(err, "unsupported network", z.Str("network", network))
}

if len(depositAmounts) > 0 {
Expand Down
8 changes: 4 additions & 4 deletions cmd/createdkg_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,23 +198,23 @@ func TestValidateWithdrawalAddr(t *testing.T) {
func TestValidateDKGConfig(t *testing.T) {
t.Run("insufficient ENRs", func(t *testing.T) {
numOperators := 2
err := validateDKGConfig(numOperators, "", nil, "", false)
err := validateDKGConfig(numOperators, "", eth2util.Network{}, nil, "", false)
require.ErrorContains(t, err, "number of operators is below minimum")
})

t.Run("invalid network", func(t *testing.T) {
numOperators := 4
err := validateDKGConfig(numOperators, "cosmos", nil, "", false)
err := validateDKGConfig(numOperators, "cosmos", eth2util.Network{}, nil, "", false)
require.ErrorContains(t, err, "unsupported network")
})

t.Run("wrong deposit amounts sum", func(t *testing.T) {
err := validateDKGConfig(4, "goerli", []int{8, 16}, "", false)
err := validateDKGConfig(4, "goerli", eth2util.Network{}, []int{8, 16}, "", false)
require.ErrorContains(t, err, "sum of partial deposit amounts must be at least 32ETH, repetition is allowed")
})

t.Run("unsupported consensus protocol", func(t *testing.T) {
err := validateDKGConfig(4, "goerli", nil, "unreal", false)
err := validateDKGConfig(4, "goerli", eth2util.Network{}, nil, "unreal", false)
require.ErrorContains(t, err, "unsupported consensus protocol")
})
}
Expand Down
Loading