Skip to content

Commit

Permalink
cmd/combine: support testnet config (#2856)
Browse files Browse the repository at this point in the history
Add `--testnet-*` flags to `combine` command.

Users must specify custom network name, chain ID genesis timestamp and fork version as hex string to allow for a custom testnet configuration to work.

category: bug
ticket: #2838 

Closes #2838.
  • Loading branch information
gsora authored Feb 6, 2024
1 parent 5b05286 commit 4a2634c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 19 deletions.
16 changes: 15 additions & 1 deletion cluster/test_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,21 @@ func NewForT(t *testing.T, dv, k, n, seed int, random *rand.Rand, opts ...func(*
}

feeRecipientAddr := testutil.RandomETHAddressSeed(random)
reg := getSignedRegistration(t, rootSecret, feeRecipientAddr, eth2util.Goerli.Name)

// get the forkHash to retrieve the network name
var def Definition
for _, opt := range opts {
opt(&def)
}

networkName := eth2util.Goerli.Name

if len(def.ForkVersion) != 0 {
networkName, err = eth2util.ForkVersionToNetwork(def.ForkVersion)
require.NoError(t, err)
}

reg := getSignedRegistration(t, rootSecret, feeRecipientAddr, networkName)

vals = append(vals, DistValidator{
PubKey: rootPublic[:],
Expand Down
17 changes: 13 additions & 4 deletions cmd/combine.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ import (
"github.com/spf13/pflag"

"github.com/obolnetwork/charon/cmd/combine"
"github.com/obolnetwork/charon/eth2util"
)

func newCombineCmd(runFunc func(ctx context.Context, clusterDir, outputDir string, force, noverify bool) error) *cobra.Command {
func newCombineCmd(runFunc func(ctx context.Context, clusterDir, outputDir string, force, noverify bool, testnetConfig eth2util.Network) error) *cobra.Command {
var (
clusterDir string
outputDir string
force bool
noverify bool

testnetConfig eth2util.Network
)

cmd := &cobra.Command{
Expand All @@ -31,6 +34,7 @@ func newCombineCmd(runFunc func(ctx context.Context, clusterDir, outputDir strin
outputDir,
force,
noverify,
testnetConfig,
)
},
}
Expand All @@ -40,19 +44,24 @@ func newCombineCmd(runFunc func(ctx context.Context, clusterDir, outputDir strin
&clusterDir,
&outputDir,
&force,
&testnetConfig,
)

bindNoVerifyFlag(cmd.Flags(), &noverify)

return cmd
}

func newCombineFunc(ctx context.Context, clusterDir, outputDir string, force, noverify bool) error {
return combine.Combine(ctx, clusterDir, outputDir, force, noverify)
func newCombineFunc(ctx context.Context, clusterDir, outputDir string, force, noverify bool, testnetConfig eth2util.Network) error {
return combine.Combine(ctx, clusterDir, outputDir, force, noverify, testnetConfig)
}

func bindCombineFlags(flags *pflag.FlagSet, clusterDir, outputDir *string, force *bool) {
func bindCombineFlags(flags *pflag.FlagSet, clusterDir, outputDir *string, force *bool, config *eth2util.Network) {
flags.StringVar(clusterDir, "cluster-dir", ".charon/cluster", `Parent directory containing a number of .charon subdirectories from the required threshold of nodes in the cluster.`)
flags.StringVar(outputDir, "output-dir", "./validator_keys", "Directory to output the combined private keys to.")
flags.BoolVar(force, "force", false, "Overwrites private keys with the same name if present.")
flags.StringVar(&config.Name, "testnet-name", "", "Name of the custom test network.")
flags.StringVar(&config.GenesisForkVersionHex, "testnet-fork-version", "", "Genesis fork version of the custom test network (in hex).")
flags.Uint64Var(&config.ChainID, "testnet-chain-id", 0, "Chain ID of the custom test network.")
flags.Int64Var(&config.GenesisTimestamp, "testnet-genesis-timestamp", 0, "Genesis timestamp of the custom test network.")
}
9 changes: 8 additions & 1 deletion cmd/combine/combine.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/obolnetwork/charon/cluster"
"github.com/obolnetwork/charon/cluster/manifest"
manifestpb "github.com/obolnetwork/charon/cluster/manifestpb/v1"
"github.com/obolnetwork/charon/eth2util"
"github.com/obolnetwork/charon/eth2util/keystore"
"github.com/obolnetwork/charon/tbls"
"github.com/obolnetwork/charon/tbls/tblsconv"
Expand All @@ -26,7 +27,7 @@ import (
// Note all nodes directories must be preset and all validator private key shares must be present.
//
// Combine will create a new directory named after "outputDir", which will contain Keystore files.
func Combine(ctx context.Context, inputDir, outputDir string, force, noverify bool, opts ...func(*options)) error {
func Combine(ctx context.Context, inputDir, outputDir string, force, noverify bool, testnetConfig eth2util.Network, opts ...func(*options)) error {
o := options{
keyStoreFunc: keystore.StoreKeys,
}
Expand All @@ -35,6 +36,12 @@ func Combine(ctx context.Context, inputDir, outputDir string, force, noverify bo
opt(&o)
}

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

if !filepath.IsAbs(outputDir) {
fp, err := filepath.Abs(outputDir)
if err != nil {
Expand Down
47 changes: 34 additions & 13 deletions cmd/combine/combine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/obolnetwork/charon/cluster/manifest"
manifestpb "github.com/obolnetwork/charon/cluster/manifestpb/v1"
"github.com/obolnetwork/charon/cmd/combine"
"github.com/obolnetwork/charon/eth2util"
"github.com/obolnetwork/charon/eth2util/keystore"
"github.com/obolnetwork/charon/tbls"
)
Expand All @@ -31,7 +32,7 @@ func noLockModif(_ int, l cluster.Lock) cluster.Lock {
func TestCombineNoLockfile(t *testing.T) {
td := t.TempDir()
od := t.TempDir()
err := combine.Combine(context.Background(), td, od, false, false)
err := combine.Combine(context.Background(), td, od, false, false, eth2util.Network{})
require.ErrorContains(t, err, "no manifest file found")
}

Expand Down Expand Up @@ -90,7 +91,7 @@ func TestCombineCannotLoadKeystore(t *testing.T) {
require.NoError(t, os.RemoveAll(filepath.Join(dir, "node0")))
require.NoError(t, os.RemoveAll(filepath.Join(dir, "node1")))

err := combine.Combine(context.Background(), dir, od, false, false, combine.WithInsecureKeysForT(t))
err := combine.Combine(context.Background(), dir, od, false, false, eth2util.Network{}, combine.WithInsecureKeysForT(t))
require.ErrorContains(t, err, "insufficient private key shares found for validator")
}

Expand All @@ -103,7 +104,26 @@ func TestCombineAllManifest(t *testing.T) {
ManifestOnly,
ManifestOnly,
ManifestOnly,
}, eth2util.Network{})
}

func TestCombineCustomNetworkFork(t *testing.T) {
seed := 0
random := rand.New(rand.NewSource(int64(seed)))

customNetwork := eth2util.Network{
GenesisForkVersionHex: "0xcafebabe",
Name: "cafebabe",
ChainID: 0xcafebabe,
GenesisTimestamp: 0xcafebabe,
}

eth2util.AddTestNetwork(customNetwork)

lock, _, shares := cluster.NewForT(t, 100, 3, 4, seed, random, func(definition *cluster.Definition) {
definition.ForkVersion = []byte{0xca, 0xfe, 0xba, 0xbe}
})
combineTest(t, lock, shares, false, false, noLockModif, nil, customNetwork)
}

func TestCombineBothManifestAndLockForAll(t *testing.T) {
Expand All @@ -115,7 +135,7 @@ func TestCombineBothManifestAndLockForAll(t *testing.T) {
Both,
Both,
Both,
})
}, eth2util.Network{})
}

func TestCombineBothManifestAndLockForSome(t *testing.T) {
Expand All @@ -127,29 +147,29 @@ func TestCombineBothManifestAndLockForSome(t *testing.T) {
Both,
Both,
LockOnly,
})
}, eth2util.Network{})
}

// This test exists because of https://github.com/ObolNetwork/charon/issues/2151.
func TestCombineLotsOfVals(t *testing.T) {
seed := 0
random := rand.New(rand.NewSource(int64(seed)))
lock, _, shares := cluster.NewForT(t, 100, 3, 4, seed, random)
combineTest(t, lock, shares, false, false, noLockModif, nil)
combineTest(t, lock, shares, false, false, noLockModif, nil, eth2util.Network{})
}

func TestCombine(t *testing.T) {
seed := 0
random := rand.New(rand.NewSource(int64(seed)))
lock, _, shares := cluster.NewForT(t, 2, 3, 4, seed, random)
combineTest(t, lock, shares, false, false, noLockModif, nil)
combineTest(t, lock, shares, false, false, noLockModif, nil, eth2util.Network{})
}

func TestCombineNoVerifyGoodLock(t *testing.T) {
seed := 0
random := rand.New(rand.NewSource(int64(seed)))
lock, _, shares := cluster.NewForT(t, 2, 3, 4, seed, random)
combineTest(t, lock, shares, true, false, noLockModif, nil)
combineTest(t, lock, shares, true, false, noLockModif, nil, eth2util.Network{})
}

func TestCombineNoVerifyBadLock(t *testing.T) {
Expand All @@ -162,7 +182,7 @@ func TestCombineNoVerifyBadLock(t *testing.T) {
}

return src
}, nil)
}, nil, eth2util.Network{})
}

func TestCombineBadLock(t *testing.T) {
Expand All @@ -175,7 +195,7 @@ func TestCombineBadLock(t *testing.T) {
}

return src
}, nil)
}, nil, eth2util.Network{})
}

func TestCombineNoVerifyDifferentValidatorData(t *testing.T) {
Expand All @@ -188,7 +208,7 @@ func TestCombineNoVerifyDifferentValidatorData(t *testing.T) {
}

return src
}, nil)
}, nil, eth2util.Network{})
}

type manifestChoice int
Expand Down Expand Up @@ -239,6 +259,7 @@ func combineTest(
wantErr bool,
modifyLockFile func(valIndex int, src cluster.Lock) cluster.Lock,
manifestOrLock []manifestChoice,
testnetConfig eth2util.Network,
) {
t.Helper()

Expand Down Expand Up @@ -320,7 +341,7 @@ func combineTest(
}
}

err := combine.Combine(context.Background(), dir, od, true, noVerify, combine.WithInsecureKeysForT(t))
err := combine.Combine(context.Background(), dir, od, true, noVerify, testnetConfig, combine.WithInsecureKeysForT(t))
if wantErr {
require.Error(t, err)
return
Expand Down Expand Up @@ -418,10 +439,10 @@ func TestCombineTwiceWithoutForceFails(t *testing.T) {
require.NoError(t, json.NewEncoder(lf).Encode(lock))
}

err := combine.Combine(context.Background(), dir, od, false, false, combine.WithInsecureKeysForT(t))
err := combine.Combine(context.Background(), dir, od, false, false, eth2util.Network{}, combine.WithInsecureKeysForT(t))
require.NoError(t, err)

err = combine.Combine(context.Background(), dir, od, false, false, combine.WithInsecureKeysForT(t))
err = combine.Combine(context.Background(), dir, od, false, false, eth2util.Network{}, combine.WithInsecureKeysForT(t))
require.Error(t, err)

keyFiles, err := keystore.LoadFilesUnordered(od)
Expand Down

0 comments on commit 4a2634c

Please sign in to comment.