Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add holesky network #320

Merged
merged 20 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from 17 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- New `--latest` flag to `sedge generate` subcommands to use the latest version of the image in the clients.
- Integrate Holesky network.make

### Fixed

Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Sedge is a one-click node setup tool for PoS network/chain validators and nodes
- [Mainnet](#mainnet)
- [Sepolia](#sepolia)
- [Goerli](#goerli)
- [Holesky](#holesky)
- [Gnosis](#gnosis)
- [Chiado (Gnosis testnet)](#chiado-gnosis-testnet)
- [CL clients with Mev-Boost](#cl-clients-with-mev-boost)
Expand Down Expand Up @@ -156,6 +157,15 @@ Users acknowledge that no warranty is being made of a successful installation. S
| Erigon | Prysm | Prysm |
| Besu | Teku | Teku |

### Holesky

| Execution | Consensus | Validator |
| ---------- |------------|------------|
| Geth | Lighthouse | Lighthouse |
| Nethermind | Lodestar | Lodestar |
| Erigon | Teku | Teku |
| Besu | | |

### Gnosis

| Execution | Consensus | Validator |
Expand Down
2 changes: 1 addition & 1 deletion cli/actions/importKeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func setupLodestarValidatorImport(dockerClient client.APIClient, serviceManager
// CMD
var preset string
switch options.Network {
case "mainnet", "goerli", "sepolia":
case "mainnet", "goerli", "sepolia", "holesky":
preset = "mainnet"
case "gnosis", "chiado":
preset = "gnosis"
Expand Down
3 changes: 2 additions & 1 deletion cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
NetworkSepolia = "sepolia"
NetworkGnosis = "gnosis"
NetworkChiado = "chiado"
NetworkHolesky = "holesky"
NetworkCustom = "custom"

NodeTypeFullNode = "full-node"
Expand Down Expand Up @@ -615,7 +616,7 @@ func runPromptActions(p ui.Prompter, o *CliCmdOptions, actions ...promptAction)
}

func selectNetwork(p ui.Prompter, o *CliCmdOptions) error {
options := []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado}
options := []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}
index, err := p.Select("Select network", "", options)
if err != nil {
return err
Expand Down
146 changes: 141 additions & 5 deletions cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ func TestCli(t *testing.T) {
GnosisClients["consensus"] = append(GnosisClients["consensus"], "randomize")
GnosisClients["validator"] = append(GnosisClients["validator"], "randomize")

HoleskyClients := map[string][]string{
"execution": clients.AllClients["execution"],
"consensus": utils.Filter(clients.AllClients["consensus"], func(c string) bool { return c != "prysm" }),
"validator": utils.Filter(clients.AllClients["validator"], func(c string) bool { return c != "prysm" }),
}
HoleskyClients["execution"] = append(HoleskyClients["execution"], "randomize")
HoleskyClients["consensus"] = append(HoleskyClients["consensus"], "randomize")
HoleskyClients["validator"] = append(HoleskyClients["validator"], "randomize")

tests := []struct {
name string
setup func(*testing.T, *sedge_mocks.MockSedgeActions, *sedge_mocks.MockPrompter, *sedge_mocks.MockDependenciesManager)
Expand Down Expand Up @@ -94,7 +103,7 @@ func TestCli(t *testing.T) {
}
sedgeActions.EXPECT().GetCommandRunner().Return(&test.SimpleCMDRunner{})
gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado}).Return(0, nil),
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(0, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(0, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
Expand Down Expand Up @@ -164,7 +173,7 @@ func TestCli(t *testing.T) {
JWTSecretPath: filepath.Join(generationPath, "jwtsecret"),
}
gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado}).Return(0, nil),
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(0, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(0, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
Expand All @@ -183,6 +192,49 @@ func TestCli(t *testing.T) {
)
},
},
{
name: "full node without validator holesky",
setup: func(t *testing.T, sedgeActions *sedge_mocks.MockSedgeActions, prompter *sedge_mocks.MockPrompter, depsMgr *sedge_mocks.MockDependenciesManager) {
generationPath := t.TempDir()
genData := generate.GenData{
Services: []string{"execution", "consensus"},
ExecutionClient: &clients.Client{
Name: "nethermind",
Type: "execution",
Image: configs.ClientImages.Execution.Nethermind.String(),
},
ConsensusClient: &clients.Client{
Name: "lodestar",
Type: "consensus",
Image: configs.ClientImages.Consensus.Lodestar.String(),
},
Network: "holesky",
CheckpointSyncUrl: "https://checkpoint-sync.holesky.ethpandaops.io/",
FeeRecipient: "0x2d07a21ebadde0c13e6b91022a7e5722eb6bf5d5",
MapAllPorts: true,
ContainerTag: "tag",
JWTSecretPath: filepath.Join(generationPath, "jwtsecret"),
}
gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(5, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(0, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
prompter.EXPECT().Confirm("Do you want to set up a validator?", true).Return(false, nil),
prompter.EXPECT().Select("Select execution client", "", HoleskyClients["execution"]).Return(0, nil),
prompter.EXPECT().Select("Select consensus client", "", HoleskyClients["consensus"]).Return(2, nil),
prompter.EXPECT().InputURL("Checkpoint sync URL", configs.NetworksConfigs()[genData.Network].CheckpointSyncURL, false).Return("https://checkpoint-sync.holesky.ethpandaops.io/", nil),
prompter.EXPECT().EthAddress("Please enter the Fee Recipient address (press enter to skip it)", "", false).Return("0x2d07a21ebadde0c13e6b91022a7e5722eb6bf5d5", nil),
prompter.EXPECT().Confirm("Do you want to expose all ports?", false).Return(true, nil),
prompter.EXPECT().Select("Select JWT source", "", []string{SourceTypeCreate, SourceTypeExisting}).Return(0, nil),
sedgeActions.EXPECT().Generate(gomock.Eq(actions.GenerateOptions{
GenerationPath: generationPath,
GenerationData: genData,
})).Return(genData, nil),
prompter.EXPECT().Confirm("Run services now?", false).Return(false, nil),
)
},
},
{
name: "execution node",
setup: func(t *testing.T, sedgeActions *sedge_mocks.MockSedgeActions, prompter *sedge_mocks.MockPrompter, depsMgr *sedge_mocks.MockDependenciesManager) {
Expand All @@ -200,7 +252,50 @@ func TestCli(t *testing.T) {
}

gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado}).Return(0, nil),
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(0, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(1, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
prompter.EXPECT().Select("Select execution client", "", ETHClients["execution"]).Return(0, nil),
prompter.EXPECT().Confirm("Do you want to expose all ports?", false).Return(true, nil),
prompter.EXPECT().Select("Select JWT source", "", []string{SourceTypeCreate, SourceTypeExisting, SourceTypeSkip}).Return(2, nil),
sedgeActions.EXPECT().Generate(gomock.Eq(actions.GenerateOptions{
GenerationPath: generationPath,
GenerationData: genData,
})).Return(genData, nil),
prompter.EXPECT().Confirm("Run services now?", false).Return(true, nil),
depsMgr.EXPECT().Check([]string{dependencies.Docker}).Return([]string{dependencies.Docker}, nil),
depsMgr.EXPECT().DockerEngineIsOn().Return(nil),
depsMgr.EXPECT().DockerComposeIsInstalled().Return(nil),
sedgeActions.EXPECT().SetupContainers(actions.SetupContainersOptions{
GenerationPath: generationPath,
Services: []string{"execution"},
}),
sedgeActions.EXPECT().RunContainers(actions.RunContainersOptions{
GenerationPath: generationPath,
Services: []string{"execution"},
}),
)
},
},
{
name: "execution node holesky",
setup: func(t *testing.T, sedgeActions *sedge_mocks.MockSedgeActions, prompter *sedge_mocks.MockPrompter, depsMgr *sedge_mocks.MockDependenciesManager) {
generationPath := t.TempDir()
genData := generate.GenData{
Services: []string{"execution"},
ExecutionClient: &clients.Client{
Name: "nethermind",
Type: "execution",
Image: configs.ClientImages.Execution.Nethermind.String(),
},
Network: "holesky",
MapAllPorts: true,
ContainerTag: "tag",
}

gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(5, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(1, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
Expand Down Expand Up @@ -249,7 +344,7 @@ func TestCli(t *testing.T) {
}

gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado}).Return(1, nil),
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(1, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(2, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
Expand All @@ -269,6 +364,47 @@ func TestCli(t *testing.T) {
)
},
},
{
name: "consensus node holesky",
setup: func(t *testing.T, sedgeActions *sedge_mocks.MockSedgeActions, prompter *sedge_mocks.MockPrompter, depsMgr *sedge_mocks.MockDependenciesManager) {
generationPath := t.TempDir()
genData := generate.GenData{
Services: []string{"consensus"},
ConsensusClient: &clients.Client{
Name: "lodestar",
Type: "consensus",
Image: configs.ClientImages.Consensus.Lodestar.String(),
},
Network: NetworkHolesky,
CheckpointSyncUrl: "https://checkpoint-sync.holesky.ethpandaops.io/",
FeeRecipient: "0x2d07a21ebadde0c13e8b91022a7e5732eb6bf5d5",
MapAllPorts: false,
ExecutionApiUrl: "http://execution:5051",
ExecutionAuthUrl: "http://execution:5051",
ContainerTag: "tag",
JWTSecretPath: filepath.Join(generationPath, "jwtsecret"),
}

gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(5, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(2, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
prompter.EXPECT().Select("Select consensus client", "", HoleskyClients["consensus"]).Return(2, nil),
prompter.EXPECT().InputURL("Checkpoint sync URL", configs.NetworksConfigs()[genData.Network].CheckpointSyncURL, false).Return("https://checkpoint-sync.holesky.ethpandaops.io/", nil),
prompter.EXPECT().InputURL("Execution API URL", "", true).Return("http://execution:5051", nil),
prompter.EXPECT().InputURL("Execution Auth API URL", "", true).Return("http://execution:5051", nil),
prompter.EXPECT().EthAddress("Please enter the Fee Recipient address (press enter to skip it)", "", false).Return("0x2d07a21ebadde0c13e8b91022a7e5732eb6bf5d5", nil),
prompter.EXPECT().Confirm("Do you want to expose all ports?", false).Return(false, nil),
prompter.EXPECT().Select("Select JWT source", "", []string{SourceTypeCreate, SourceTypeExisting, SourceTypeSkip}).Return(0, nil),
sedgeActions.EXPECT().Generate(gomock.Eq(actions.GenerateOptions{
GenerationPath: generationPath,
GenerationData: genData,
})).Return(genData, nil),
prompter.EXPECT().Confirm("Run services now?", false).Return(false, nil),
)
},
},
{
name: "validator mainnet",
setup: func(t *testing.T, sedgeActions *sedge_mocks.MockSedgeActions, prompter *sedge_mocks.MockPrompter, depsMgr *sedge_mocks.MockDependenciesManager) {
Expand All @@ -292,7 +428,7 @@ func TestCli(t *testing.T) {
}

gomock.InOrder(
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado}).Return(0, nil),
prompter.EXPECT().Select("Select network", "", []string{NetworkMainnet, NetworkGoerli, NetworkSepolia, NetworkGnosis, NetworkChiado, NetworkHolesky}).Return(0, nil),
prompter.EXPECT().Select("Select node type", "", []string{NodeTypeFullNode, NodeTypeExecution, NodeTypeConsensus, NodeTypeValidator}).Return(3, nil),
prompter.EXPECT().Input("Generation path", configs.DefaultAbsSedgeDataPath, false, nil).Return(generationPath, nil),
prompter.EXPECT().Input("Container tag, sedge will add to each container and the network, a suffix with the tag", "", false, nil).Return("tag", nil),
Expand Down
2 changes: 1 addition & 1 deletion cli/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ You can generate:
cmd.AddCommand(MevBoostSubCmd(sedgeAction))

cmd.PersistentFlags().StringVarP(&generationPath, "path", "p", configs.DefaultAbsSedgeDataPath, "generation path for sedge data. Default is sedge-data")
cmd.PersistentFlags().StringVarP(&network, "network", "n", "mainnet", "Target network. e.g. mainnet, goerli, sepolia, etc.")
cmd.PersistentFlags().StringVarP(&network, "network", "n", "mainnet", "Target network. e.g. mainnet, goerli, sepolia, holesky, gnosis, chiado, etc.")
cmd.PersistentFlags().StringVar(&logging, "logging", "json", fmt.Sprintf("Docker logging driver used by all the services. Set 'none' to use the default docker logging driver. Possible values: %v", configs.ValidLoggingFlags()))
cmd.PersistentFlags().StringVar(&containerTag, "container-tag", "", "Container tag to use. If defined, sedge will add to each container and the network, a suffix with the tag. e.g. sedge-validator-client -> sedge-validator-client-<tag>.")
return cmd
Expand Down
2 changes: 1 addition & 1 deletion cli/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func KeysCmd(cmdRunner commands.CommandRunner, p ui.Prompter) *cobra.Command {
},
}
// Flag binds
cmd.Flags().StringVarP(&flags.network, "network", "n", "mainnet", "Target network. e.g. mainnet, goerli, sepolia etc.")
cmd.Flags().StringVarP(&flags.network, "network", "n", "mainnet", "Target network. e.g. mainnet, goerli, sepolia, holesky, gnosis, chiado etc.")
cmd.Flags().StringVarP(&flags.path, "path", "p", configs.DefaultAbsSedgeDataPath, "Absolute path to keystore folder. e.g. /home/user/keystore")
cmd.Flags().StringVar(&flags.eth1WithdrawalAddress, "eth1-withdrawal-address", "", "If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in EIP-2334 format.")
cmd.Flags().StringVar(&flags.mnemonicPath, "mnemonic-path", "", "Path to file with a existing mnemonic to use.")
Expand Down
1 change: 1 addition & 0 deletions cli/sub_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ func MevBoostSubCmd(sedgeAction actions.SedgeActions) *cobra.Command {
// Bind flags
cmd.Flags().StringSliceVar(&flags.relayURLs, "relay-urls", []string{}, "List of comma separated relay URLs used to connect to mev relay. Example: 'sedge generate mev-boost --relay-urls=https://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@boost-relay.flashbots.net,https://0xa1559ace749633b997cb3fdacffb890aeebdb0f5a3b6aaa7eeeaf1a38af0a8fe88b9e4b1f61f236d2e64d95733327a62@relay.ultrasound.money'")
cmd.Flags().StringVarP(&flags.mevImage, "mev-boost-image", "m", "", "Custom docker image to use for Mev Boost. Example: 'sedge generate mev-boost --mev-boost-image flashbots/mev-boost:latest-portable'")
cmd.Flags().StringVarP(&network, "network", "n", "mainnet", "Target network. e.g. mainnet, goerli, sepolia etc.")
cmd.Flags().SortFlags = false
return cmd
}
10 changes: 5 additions & 5 deletions configs/client_images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ execution:
version: v1.13.3
besu:
name: hyperledger/besu
version: 23.4.4
version: 23.7.2
nethermind:
name: nethermind/nethermind
version: 1.21.0
Expand All @@ -17,10 +17,10 @@ consensus:
version: v4.5.0
lodestar:
name: chainsafe/lodestar
version: v1.9.2
version: v1.11.1
teku:
name: consensys/teku
version: 23.8.0
version: 23.9.0
prysm:
name: gcr.io/prysmaticlabs/prysm/beacon-chain
version: v4.0.8
Expand All @@ -30,10 +30,10 @@ validator:
version: v4.5.0
lodestar:
name: chainsafe/lodestar
version: v1.9.2
version: v1.11.1
teku:
name: consensys/teku
version: 23.8.0
version: 23.9.0
prysm:
name: gcr.io/prysmaticlabs/prysm/validator
version: v4.0.8
Loading