From ccedd8f00ff51871f1367afd9b633fb3d873dd02 Mon Sep 17 00:00:00 2001 From: Joe Clapis Date: Mon, 15 Jul 2024 10:59:40 -0400 Subject: [PATCH 1/3] Moved networks to file-system loading instead of hardcoded --- config/besu-config.go | 6 +- config/cfg-section.go | 39 +++++++++++ config/enums.go | 20 ++++-- config/geth-config.go | 6 +- config/lighthouse-bn-config.go | 6 +- config/lighthouse-vc-config.go | 6 +- config/lodestar-bn-config.go | 6 +- config/lodestar-vc-config.go | 6 +- config/nethermind-config.go | 10 ++- config/network-resources.go | 70 ------------------- config/network-settings.go | 114 +++++++++++++++++++++++++++++++ config/nimbus-bn-config.go | 6 +- config/nimbus-vc-config.go | 6 +- config/parameter.go | 119 ++++++++++++++++++++------------- config/prysm-bn-config.go | 6 +- config/prysm-vc-config.go | 6 +- config/reth-config.go | 6 +- config/teku-bn-config.go | 6 +- config/teku-vc-config.go | 6 +- 19 files changed, 271 insertions(+), 179 deletions(-) delete mode 100644 config/network-resources.go create mode 100644 config/network-settings.go diff --git a/config/besu-config.go b/config/besu-config.go index 112697d..79f8019 100644 --- a/config/besu-config.go +++ b/config/besu-config.go @@ -7,8 +7,7 @@ import ( // Constants const ( // Tags - besuTagTest string = "hyperledger/besu:24.6.0" - besuTagProd string = "hyperledger/besu:24.6.0" + besuTag string = "hyperledger/besu:24.6.0" ) // Configuration for Besu @@ -101,8 +100,7 @@ func NewBesuConfig() *BesuConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: besuTagProd, - Network_Holesky: besuTagTest, + Network_All: besuTag, }, }, diff --git a/config/cfg-section.go b/config/cfg-section.go index 79c439b..6ff407a 100644 --- a/config/cfg-section.go +++ b/config/cfg-section.go @@ -135,3 +135,42 @@ func ApplyDefaults(cfg IConfigSection, network Network) { ApplyDefaults(subconfig, network) } } + +// Assign the default values of a config section for the provided network +func SetDefaultsForNetworks(cfg IConfigSection, defaults map[string]any, network Network) error { + // Handle the parameters + params := cfg.GetParameters() + for _, param := range params { + id := param.GetCommon().ID + val, exists := defaults[id] + if !exists { + continue + } + valString, isString := val.(string) + if !isString { + return fmt.Errorf("parameter [%s] is not a string but has a parameter ID name", id) + } + err := param.SetDefaultValueForNetwork(valString, network) + if err != nil { + return err + } + } + + // Handle the subconfigs + subconfigs := cfg.GetSubconfigs() + for name, subconfig := range subconfigs { + subParams, exists := defaults[name] + if exists { + submap, isMap := subParams.(map[string]any) + if !isMap { + return fmt.Errorf("subsection [%s] is not a map, it is %s", name, reflect.TypeOf(subParams)) + } + err := SetDefaultsForNetworks(subconfig, submap, network) + if err != nil { + return fmt.Errorf("error deserializing subsection [%s]: %w", name, err) + } + } + } + + return nil +} diff --git a/config/enums.go b/config/enums.go index 9099c65..01f3732 100644 --- a/config/enums.go +++ b/config/enums.go @@ -2,10 +2,18 @@ package config import "fmt" -// The network that this installation is configured to run on +const ( + // The standard name of the Ethereum mainnet network, used for EL / CL flags + EthNetwork_Mainnet string = "mainnet" + + // The standard name of the Ethereum holesky network, used for EL / CL flags + EthNetwork_Holesky string = "holesky" +) + +// Deprecated: Switch to using dynamically-loaded network settings instead type Network string -// Enum to describe the various network values +// Enum to describe well-known network keys for convenience, which may or may not be used by the application. const ( // Unknown Network_Unknown Network = "" @@ -13,11 +21,11 @@ const ( // All networks (used for parameter defaults) Network_All Network = "all" - // The Holesky test network - Network_Holesky Network = "holesky" - // The Ethereum mainnet - Network_Mainnet Network = "mainnet" + Network_Mainnet Network = Network(EthNetwork_Mainnet) + + // The Holesky test network + Network_Holesky Network = Network(EthNetwork_Holesky) ) // A Docker container name diff --git a/config/geth-config.go b/config/geth-config.go index 4a0fa6c..769e02d 100644 --- a/config/geth-config.go +++ b/config/geth-config.go @@ -10,8 +10,7 @@ import ( // Constants const ( // Tags - gethTagProd string = "ethereum/client-go:v1.14.7" - gethTagTest string = "ethereum/client-go:v1.14.7" + gethTag string = "ethereum/client-go:v1.14.7" ) // Configuration for Geth @@ -87,8 +86,7 @@ func NewGethConfig() *GethConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: gethTagProd, - Network_Holesky: gethTagTest, + Network_All: gethTag, }, }, diff --git a/config/lighthouse-bn-config.go b/config/lighthouse-bn-config.go index 1e39bbb..0508491 100644 --- a/config/lighthouse-bn-config.go +++ b/config/lighthouse-bn-config.go @@ -6,8 +6,7 @@ import ( const ( // Tags - lighthouseBnTagProd string = "sigp/lighthouse:v5.2.1" - lighthouseBnTagTest string = "sigp/lighthouse:v5.2.1" + lighthouseBnTag string = "sigp/lighthouse:v5.2.1" ) // Configuration for the Lighthouse BN @@ -66,8 +65,7 @@ func NewLighthouseBnConfig() *LighthouseBnConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: lighthouseBnTagProd, - Network_Holesky: lighthouseBnTagTest, + Network_All: lighthouseBnTag, }, }, diff --git a/config/lighthouse-vc-config.go b/config/lighthouse-vc-config.go index cc9d3ee..42ad00e 100644 --- a/config/lighthouse-vc-config.go +++ b/config/lighthouse-vc-config.go @@ -6,8 +6,7 @@ import ( const ( // Tags - lighthouseVcTagProd string = lighthouseBnTagProd - lighthouseVcTagTest string = lighthouseBnTagTest + lighthouseVcTag string = lighthouseBnTag ) // Configuration for the Lighthouse VC @@ -32,8 +31,7 @@ func NewLighthouseVcConfig() *LighthouseVcConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: lighthouseVcTagProd, - Network_Holesky: lighthouseVcTagTest, + Network_All: lighthouseVcTag, }, }, diff --git a/config/lodestar-bn-config.go b/config/lodestar-bn-config.go index a4c2403..5ece047 100644 --- a/config/lodestar-bn-config.go +++ b/config/lodestar-bn-config.go @@ -5,8 +5,7 @@ import ( ) const ( - lodestarBnTagTest string = "chainsafe/lodestar:v1.19.0" - lodestarBnTagProd string = "chainsafe/lodestar:v1.19.0" + lodestarBnTag string = "chainsafe/lodestar:v1.19.0" ) // Configuration for the Lodestar BN @@ -48,8 +47,7 @@ func NewLodestarBnConfig() *LodestarBnConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: lodestarBnTagProd, - Network_Holesky: lodestarBnTagTest, + Network_All: lodestarBnTag, }, }, diff --git a/config/lodestar-vc-config.go b/config/lodestar-vc-config.go index 491b54a..9932fe3 100644 --- a/config/lodestar-vc-config.go +++ b/config/lodestar-vc-config.go @@ -5,8 +5,7 @@ import ( ) const ( - lodestarVcTagTest string = lodestarBnTagTest - lodestarVcTagProd string = lodestarBnTagProd + lodestarVcTag string = lodestarBnTag ) // Configuration for the Lodestar VC @@ -31,8 +30,7 @@ func NewLodestarVcConfig() *LodestarVcConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: lodestarVcTagProd, - Network_Holesky: lodestarVcTagTest, + Network_All: lodestarVcTag, }, }, diff --git a/config/nethermind-config.go b/config/nethermind-config.go index 1907916..8ebf01a 100644 --- a/config/nethermind-config.go +++ b/config/nethermind-config.go @@ -11,8 +11,7 @@ import ( // Constants const ( // Tags - nethermindTagProd string = "nethermind/nethermind:1.27.0" - nethermindTagTest string = "nethermind/nethermind:1.27.0" + nethermindTag string = "nethermind/nethermind:1.27.0" ) // Configuration for Nethermind @@ -114,8 +113,8 @@ func NewNethermindConfig() *NethermindConfig { OverwriteOnUpgrade: false, }, Default: map[Network]uint64{ - Network_Mainnet: uint64(307200), - Network_Holesky: uint64(51200), + Network_All: uint64(307200), + //Network_Holesky: uint64(51200), TODO: Port }, }, @@ -157,8 +156,7 @@ func NewNethermindConfig() *NethermindConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: nethermindTagProd, - Network_Holesky: nethermindTagTest, + Network_All: nethermindTag, }, }, diff --git a/config/network-resources.go b/config/network-resources.go deleted file mode 100644 index 2f08a33..0000000 --- a/config/network-resources.go +++ /dev/null @@ -1,70 +0,0 @@ -package config - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" -) - -// A collection of network-specific resources and getters for them -type NetworkResources struct { - // The Network being used - Network Network - - // The actual name of the underlying Ethereum network, passed into the clients - EthNetworkName string - - // The chain ID for the current network - ChainID uint - - // The genesis fork version for the network according to the Beacon config for the network - GenesisForkVersion []byte - - // The address of the multicall contract - MulticallAddress common.Address - - // The BalanceChecker contract address - BalanceBatcherAddress common.Address - - // The URL for transaction monitoring on the network's chain explorer - TxWatchUrl string - - // The FlashBots Protect RPC endpoint - FlashbotsProtectUrl string -} - -// Creates a new resource collection for the given network -func NewResources(network Network) *NetworkResources { - // Mainnet - mainnetResources := &NetworkResources{ - Network: Network_Mainnet, - EthNetworkName: string(Network_Mainnet), - ChainID: 1, - GenesisForkVersion: common.FromHex("0x00000000"), // https://github.com/eth-clients/eth2-networks/tree/master/shared/mainnet#genesis-information - MulticallAddress: common.HexToAddress("0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696"), - BalanceBatcherAddress: common.HexToAddress("0xb1f8e55c7f64d203c1400b9d8555d050f94adf39"), - TxWatchUrl: "https://etherscan.io/tx", - FlashbotsProtectUrl: "https://rpc.flashbots.net/", - } - - // Holesky - holeskyResources := &NetworkResources{ - Network: Network_Holesky, - EthNetworkName: string(Network_Holesky), - ChainID: 17000, - GenesisForkVersion: common.FromHex("0x01017000"), // https://github.com/eth-clients/holesky - MulticallAddress: common.HexToAddress("0x0540b786f03c9491f3a2ab4b0e3ae4ecd4f63ce7"), - BalanceBatcherAddress: common.HexToAddress("0xfAa2e7C84eD801dd9D27Ac1ed957274530796140"), - TxWatchUrl: "https://holesky.etherscan.io/tx", - FlashbotsProtectUrl: "https://rpc-holesky.flashbots.net", - } - - switch network { - case Network_Mainnet: - return mainnetResources - case Network_Holesky: - return holeskyResources - } - - panic(fmt.Sprintf("network %s is not supported", network)) -} diff --git a/config/network-settings.go b/config/network-settings.go new file mode 100644 index 0000000..0c8eba6 --- /dev/null +++ b/config/network-settings.go @@ -0,0 +1,114 @@ +package config + +import ( + "errors" + "fmt" + "io/fs" + "os" + + "github.com/ethereum/go-ethereum/common" + "gopkg.in/yaml.v3" +) + +const () + +var ( + DefaultMainnetSettings = &NetworkSettings{ + Key: "mainnet", + Name: "Ethereum Mainnet", + Description: "The Ethereum Mainnet network", + NetworkResources: &NetworkResources{ + EthNetworkName: "mainnet", + ChainID: 1, + GenesisForkVersion: common.FromHex("0x00000000"), // https://github.com/eth-clients/eth2-networks/tree/master/shared/mainnet#genesis-information + MulticallAddress: common.HexToAddress("0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696"), + BalanceBatcherAddress: common.HexToAddress("0xb1f8e55c7f64d203c1400b9d8555d050f94adf39"), + TxWatchUrl: "https://etherscan.io/tx", + FlashbotsProtectUrl: "https://rpc.flashbots.net/", + }, + DefaultConfigSettings: map[string]any{}, + } + + DefaultHoleskySettings = &NetworkSettings{ + Key: "holesky", + Name: "Holesky Testnet", + Description: "The Ethereum holesky public test network", + NetworkResources: &NetworkResources{ + EthNetworkName: "holesky", + ChainID: 17000, + GenesisForkVersion: common.FromHex("0x01017000"), // https://github.com/eth-clients/holesky + MulticallAddress: common.HexToAddress("0x0540b786f03c9491f3a2ab4b0e3ae4ecd4f63ce7"), + BalanceBatcherAddress: common.HexToAddress("0xfAa2e7C84eD801dd9D27Ac1ed957274530796140"), + TxWatchUrl: "https://holesky.etherscan.io/tx", + FlashbotsProtectUrl: "https://rpc-holesky.flashbots.net", + }, + DefaultConfigSettings: map[string]any{}, + } +) + +// A collection of network-specific resources and getters for them +type NetworkResources struct { + // The actual name of the underlying Ethereum network, passed into the clients + EthNetworkName string `yaml:"ethNetworkName" json:"ethNetworkName"` + + // The chain ID for the current network + ChainID uint `yaml:"chainID" json:"chainID"` + + // The genesis fork version for the network according to the Beacon config for the network + GenesisForkVersion []byte `yaml:"genesisForkVersion" json:"genesisForkVersion"` + + // The address of the multicall contract + MulticallAddress common.Address `yaml:"multicallAddress" json:"multicallAddress"` + + // The BalanceChecker contract address + BalanceBatcherAddress common.Address `yaml:"balanceBatcherAddress" json:"balanceBatcherAddress"` + + // The URL for transaction monitoring on the network's chain explorer + TxWatchUrl string `yaml:"txWatchUrl" json:"txWatchUrl"` + + // The FlashBots Protect RPC endpoint + FlashbotsProtectUrl string `yaml:"flashbotsProtectUrl" json:"flashbotsProtectUrl"` +} + +// NetworkSettings contains all of the settings for a given Ethereum network +type NetworkSettings struct { + // The unique key used to identify the network in the configuration + Key Network `yaml:"key" json:"key"` + + // Human-readable name of the network + Name string `yaml:"name" json:"name"` + + // A brief description of the network + Description string `yaml:"description" json:"description"` + + // The list of resources for the network + NetworkResources *NetworkResources `yaml:"networkResources" json:"networkResources"` + + // A collection of default configuration settings to use for the network, which will override + // the standard "general-purpose" default value for the setting + DefaultConfigSettings map[string]any `yaml:"defaultConfigSettings" json:"defaultConfigSettings"` +} + +// Load network settings from a file +func LoadSettingsFile(path string) (*NetworkSettings, error) { + // Make sure the file exists + _, err := os.Stat(path) + if errors.Is(err, fs.ErrNotExist) { + return nil, fmt.Errorf("network settings file [%s] does not exist", path) + } + + // Load the file + bytes, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("error reading network settings file [%s]: %w", path, err) + } + + // Unmarshal the settings + settings := new(NetworkSettings) + err = yaml.Unmarshal(bytes, settings) + if err != nil { + return nil, fmt.Errorf("error unmarshalling network settings file [%s]: %w", path, err) + } + + return settings, nil +} diff --git a/config/nimbus-bn-config.go b/config/nimbus-bn-config.go index 6a3109b..d6eee44 100644 --- a/config/nimbus-bn-config.go +++ b/config/nimbus-bn-config.go @@ -9,8 +9,7 @@ import ( const ( // Tags - nimbusBnTagTest string = "statusim/nimbus-eth2:multiarch-v24.6.0" - nimbusBnTagProd string = "statusim/nimbus-eth2:multiarch-v24.6.0" + nimbusBnTag string = "statusim/nimbus-eth2:multiarch-v24.6.0" ) // Nimbus's pruning mode @@ -92,8 +91,7 @@ func NewNimbusBnConfig() *NimbusBnConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: nimbusBnTagProd, - Network_Holesky: nimbusBnTagTest, + Network_All: nimbusBnTag, }, }, diff --git a/config/nimbus-vc-config.go b/config/nimbus-vc-config.go index e9dd206..bf0ba0c 100644 --- a/config/nimbus-vc-config.go +++ b/config/nimbus-vc-config.go @@ -6,8 +6,7 @@ import ( const ( // Tags - nimbusVcTagTest string = "statusim/nimbus-validator-client:multiarch-v24.6.0" - nimbusVcTagProd string = "statusim/nimbus-validator-client:multiarch-v24.6.0" + nimbusVcTag string = "statusim/nimbus-validator-client:multiarch-v24.6.0" ) // Configuration for Nimbus @@ -32,8 +31,7 @@ func NewNimbusVcConfig() *NimbusVcConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: nimbusVcTagProd, - Network_Holesky: nimbusVcTagTest, + Network_All: nimbusVcTag, }, }, diff --git a/config/parameter.go b/config/parameter.go index 2abe15c..645afa4 100644 --- a/config/parameter.go +++ b/config/parameter.go @@ -87,6 +87,9 @@ type IParameter interface { // Set the parameter's value explicitly; panics if it's the wrong type SetValue(value any) + // Sets the default value for the provided network + SetDefaultValueForNetwork(serializedDefault string, network Network) error + // Change the current network ChangeNetwork(oldNetwork Network, newNetwork Network) } @@ -143,59 +146,24 @@ func (p *Parameter[_]) GetDefaultAsAny(network Network) any { // Deserializes a string into this parameter's value func (p *Parameter[_]) Deserialize(serializedParam string, network Network) error { - if len(p.Options) > 0 { - for _, option := range p.Options { - optionVal := option.String() - if optionVal == serializedParam { - p.Value = option.Value - return nil - } + value, err := p.deserializeToType(serializedParam, network) + if err != nil { + // Set to the default option if none of the options match + if len(p.Options) > 0 { + p.SetToDefault(network) + return nil } - p.SetToDefault(network) - return nil - } - - // Set blanks to the default if blank isn't allowed - if !p.CanBeBlank && serializedParam == "" { - p.SetToDefault(network) - return nil - } - var err error - switch value := any(&p.Value).(type) { - case *int64: - *value, err = strconv.ParseInt(serializedParam, 0, 0) - case *uint64: - *value, err = strconv.ParseUint(serializedParam, 0, 0) - case *uint16: - var result uint64 - result, err = strconv.ParseUint(serializedParam, 0, 16) - *value = uint16(result) - case *bool: - *value, err = strconv.ParseBool(serializedParam) - case *float64: - *value, err = strconv.ParseFloat(serializedParam, 64) - case *string: - if p.CanBeBlank && serializedParam == "" { - *value = "" + // Set blanks to the default if blank isn't allowed + if !p.CanBeBlank && serializedParam == "" { + p.SetToDefault(network) return nil } - if p.MaxLength > 0 && len(serializedParam) > p.MaxLength { - return fmt.Errorf("cannot deserialize parameter [%s]: value [%s] is longer than the max length of [%d]", p.ID, serializedParam, p.MaxLength) - } - if p.Regex != "" { - regex := regexp.MustCompile(p.Regex) - if !regex.MatchString(serializedParam) { - return fmt.Errorf("cannot deserialize parameter [%s]: value [%s] did not match the expected format", p.ID, serializedParam) - } - } - *value = serializedParam - } - if err != nil { return fmt.Errorf("cannot deserialize parameter [%s]: %w", p.ID, err) } + p.Value = value return nil } @@ -230,3 +198,64 @@ func (p *Parameter[_]) ChangeNetwork(oldNetwork Network, newNetwork Network) { // Update the description, if applicable p.UpdateDescription(newNetwork) } + +// Sets the default value for the provided network +func (p *Parameter[Type]) SetDefaultValueForNetwork(serializedDefault string, network Network) error { + value, err := p.deserializeToType(serializedDefault, network) + if err != nil { + return fmt.Errorf("cannot set default of parameter [%s] for network [%v]: %w", p.ID, network, err) + } + + p.Default[network] = value + return nil +} + +// Deserializes a string into this parameter's value type +func (p *Parameter[Type]) deserializeToType(serializedDefault string, network Network) (Type, error) { + var defaultValue Type + if len(p.Options) > 0 { + for _, option := range p.Options { + optionVal := option.String() + if optionVal == serializedDefault { + defaultValue = option.Value + return defaultValue, nil + } + } + return defaultValue, fmt.Errorf("value [%s] is not a valid option", serializedDefault) + } + + // Set blanks to the default if blank isn't allowed + if !p.CanBeBlank && serializedDefault == "" { + return defaultValue, fmt.Errorf("value cannot be blank") + } + + var err error + switch value := any(&defaultValue).(type) { + case *int64: + *value, err = strconv.ParseInt(serializedDefault, 0, 0) + case *uint64: + *value, err = strconv.ParseUint(serializedDefault, 0, 0) + case *uint16: + var result uint64 + result, err = strconv.ParseUint(serializedDefault, 0, 16) + *value = uint16(result) + case *bool: + *value, err = strconv.ParseBool(serializedDefault) + case *float64: + *value, err = strconv.ParseFloat(serializedDefault, 64) + case *string: + if p.CanBeBlank && serializedDefault == "" { + *value = "" + } else if p.MaxLength > 0 && len(serializedDefault) > p.MaxLength { + err = fmt.Errorf("value [%s] is longer than the max length of [%d]", serializedDefault, p.MaxLength) + } else if p.Regex != "" { + regex := regexp.MustCompile(p.Regex) + if !regex.MatchString(serializedDefault) { + err = fmt.Errorf("value [%s] did not match the expected format", serializedDefault) + } + } else { + *value = serializedDefault + } + } + return defaultValue, err +} diff --git a/config/prysm-bn-config.go b/config/prysm-bn-config.go index 6b2086c..dcb6fb3 100644 --- a/config/prysm-bn-config.go +++ b/config/prysm-bn-config.go @@ -6,8 +6,7 @@ import ( const ( // Tags - prysmBnTagTest string = "rocketpool/prysm:v5.0.4" - prysmBnTagProd string = "rocketpool/prysm:v5.0.4" + prysmBnTag string = "rocketpool/prysm:v5.0.4" ) // Configuration for the Prysm BN @@ -84,8 +83,7 @@ func NewPrysmBnConfig() *PrysmBnConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: prysmBnTagProd, - Network_Holesky: prysmBnTagTest, + Network_All: prysmBnTag, }, }, diff --git a/config/prysm-vc-config.go b/config/prysm-vc-config.go index 0e4bd3f..0a4acbc 100644 --- a/config/prysm-vc-config.go +++ b/config/prysm-vc-config.go @@ -6,8 +6,7 @@ import ( const ( // Tags - prysmVcTagTest string = prysmBnTagTest - prysmVcTagProd string = prysmBnTagProd + prysmVcTag string = prysmBnTag ) // Configuration for the Prysm VC @@ -32,8 +31,7 @@ func NewPrysmVcConfig() *PrysmVcConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: prysmVcTagProd, - Network_Holesky: prysmVcTagTest, + Network_All: prysmVcTag, }, }, diff --git a/config/reth-config.go b/config/reth-config.go index 38e968a..90b97ec 100644 --- a/config/reth-config.go +++ b/config/reth-config.go @@ -9,8 +9,7 @@ import ( // Constants const ( - rethTagProd string = "ghcr.io/paradigmxyz/reth:v1.0.1" - rethTagTest string = "ghcr.io/paradigmxyz/reth:v1.0.1" + rethTag string = "ghcr.io/paradigmxyz/reth:v1.0.1" ) // Configuration for Reth @@ -82,8 +81,7 @@ func NewRethConfig() *RethConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: rethTagProd, - Network_Holesky: rethTagTest, + Network_All: rethTag, }, }, diff --git a/config/teku-bn-config.go b/config/teku-bn-config.go index 3e48589..3b64e25 100644 --- a/config/teku-bn-config.go +++ b/config/teku-bn-config.go @@ -7,8 +7,7 @@ import ( const ( // Tags - tekuBnTagTest string = "consensys/teku:24.6.1" - tekuBnTagProd string = "consensys/teku:24.6.1" + tekuBnTag string = "consensys/teku:24.6.1" ) // Configuration for Teku @@ -84,8 +83,7 @@ func NewTekuBnConfig() *TekuBnConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: tekuBnTagProd, - Network_Holesky: tekuBnTagTest, + Network_All: tekuBnTag, }, }, diff --git a/config/teku-vc-config.go b/config/teku-vc-config.go index 808d2a0..a8367f4 100644 --- a/config/teku-vc-config.go +++ b/config/teku-vc-config.go @@ -6,8 +6,7 @@ import ( const ( // Tags - tekuVcTagTest string = tekuBnTagTest - tekuVcTagProd string = tekuBnTagProd + tekuVcTag string = tekuBnTag ) // Configuration for Teku @@ -49,8 +48,7 @@ func NewTekuVcConfig() *TekuVcConfig { OverwriteOnUpgrade: true, }, Default: map[Network]string{ - Network_Mainnet: tekuVcTagProd, - Network_Holesky: tekuVcTagTest, + Network_All: tekuVcTag, }, }, From 814ef9159f5a6027a7519c8c06fdf3592f6ed3e7 Mon Sep 17 00:00:00 2001 From: Joe Clapis Date: Tue, 16 Jul 2024 12:57:41 -0400 Subject: [PATCH 2/3] Moved some types out of the Beacon client package for general usage --- beacon/client/committees.go | 7 +- beacon/client/std-client.go | 2 +- beacon/client/types.go | 153 ++++++++++++------------------------ config/network-settings.go | 53 +++++-------- utils/types.go | 83 +++++++++++++++++++ 5 files changed, 158 insertions(+), 140 deletions(-) create mode 100644 utils/types.go diff --git a/beacon/client/committees.go b/beacon/client/committees.go index 1662b50..469afa5 100644 --- a/beacon/client/committees.go +++ b/beacon/client/committees.go @@ -5,12 +5,13 @@ import ( "sync" "github.com/goccy/go-json" + "github.com/rocket-pool/node-manager-core/utils" ) type Committee struct { - Index Uinteger `json:"index"` - Slot Uinteger `json:"slot"` - Validators []string `json:"validators"` + Index utils.Uinteger `json:"index"` + Slot utils.Uinteger `json:"slot"` + Validators []string `json:"validators"` } // Custom deserialization logic for Committee allows us to pool the validator diff --git a/beacon/client/std-client.go b/beacon/client/std-client.go index b70ee36..9070744 100644 --- a/beacon/client/std-client.go +++ b/beacon/client/std-client.go @@ -373,7 +373,7 @@ func (c *StandardClient) GetDomainData(ctx context.Context, domainType []byte, e func (c *StandardClient) ExitValidator(ctx context.Context, validatorIndex string, epoch uint64, signature beacon.ValidatorSignature) error { return c.provider.Beacon_VoluntaryExits_Post(ctx, VoluntaryExitRequest{ Message: VoluntaryExitMessage{ - Epoch: Uinteger(epoch), + Epoch: utils.Uinteger(epoch), ValidatorIndex: validatorIndex, }, Signature: signature[:], diff --git a/beacon/client/types.go b/beacon/client/types.go index d7e478b..88ce6b4 100644 --- a/beacon/client/types.go +++ b/beacon/client/types.go @@ -1,79 +1,76 @@ package client import ( - "strconv" - "github.com/ethereum/go-ethereum/common" - "github.com/goccy/go-json" "github.com/rocket-pool/node-manager-core/utils" ) // Request types type VoluntaryExitMessage struct { - Epoch Uinteger `json:"epoch"` - ValidatorIndex string `json:"validator_index"` + Epoch utils.Uinteger `json:"epoch"` + ValidatorIndex string `json:"validator_index"` } type VoluntaryExitRequest struct { Message VoluntaryExitMessage `json:"message"` - Signature ByteArray `json:"signature"` + Signature utils.ByteArray `json:"signature"` } type BLSToExecutionChangeMessage struct { - ValidatorIndex string `json:"validator_index"` - FromBLSPubkey ByteArray `json:"from_bls_pubkey"` - ToExecutionAddress ByteArray `json:"to_execution_address"` + ValidatorIndex string `json:"validator_index"` + FromBLSPubkey utils.ByteArray `json:"from_bls_pubkey"` + ToExecutionAddress utils.ByteArray `json:"to_execution_address"` } type BLSToExecutionChangeRequest struct { Message BLSToExecutionChangeMessage `json:"message"` - Signature ByteArray `json:"signature"` + Signature utils.ByteArray `json:"signature"` } // Response types type SyncStatusResponse struct { Data struct { - IsSyncing bool `json:"is_syncing"` - HeadSlot Uinteger `json:"head_slot"` - SyncDistance Uinteger `json:"sync_distance"` + IsSyncing bool `json:"is_syncing"` + HeadSlot utils.Uinteger `json:"head_slot"` + SyncDistance utils.Uinteger `json:"sync_distance"` } `json:"data"` } type Eth2ConfigResponse struct { Data struct { - SecondsPerSlot Uinteger `json:"SECONDS_PER_SLOT"` - SlotsPerEpoch Uinteger `json:"SLOTS_PER_EPOCH"` - EpochsPerSyncCommitteePeriod Uinteger `json:"EPOCHS_PER_SYNC_COMMITTEE_PERIOD"` - CapellaForkVersion ByteArray `json:"CAPELLA_FORK_VERSION"` + SecondsPerSlot utils.Uinteger `json:"SECONDS_PER_SLOT"` + SlotsPerEpoch utils.Uinteger `json:"SLOTS_PER_EPOCH"` + EpochsPerSyncCommitteePeriod utils.Uinteger `json:"EPOCHS_PER_SYNC_COMMITTEE_PERIOD"` + CapellaForkVersion utils.ByteArray `json:"CAPELLA_FORK_VERSION"` } `json:"data"` } type Eth2DepositContractResponse struct { Data struct { - ChainID Uinteger `json:"chain_id"` + ChainID utils.Uinteger `json:"chain_id"` Address common.Address `json:"address"` } `json:"data"` } type GenesisResponse struct { Data struct { - GenesisTime Uinteger `json:"genesis_time"` - GenesisForkVersion ByteArray `json:"genesis_fork_version"` - GenesisValidatorsRoot ByteArray `json:"genesis_validators_root"` + GenesisTime utils.Uinteger `json:"genesis_time"` + GenesisForkVersion utils.ByteArray `json:"genesis_fork_version"` + GenesisValidatorsRoot utils.ByteArray `json:"genesis_validators_root"` } `json:"data"` } type FinalityCheckpointsResponse struct { Data struct { PreviousJustified struct { - Epoch Uinteger `json:"epoch"` + Epoch utils.Uinteger `json:"epoch"` } `json:"previous_justified"` CurrentJustified struct { - Epoch Uinteger `json:"epoch"` + Epoch utils.Uinteger `json:"epoch"` } `json:"current_justified"` Finalized struct { - Epoch Uinteger `json:"epoch"` + Epoch utils.Uinteger `json:"epoch"` } `json:"finalized"` } `json:"data"` } type ForkResponse struct { Data struct { - PreviousVersion ByteArray `json:"previous_version"` - CurrentVersion ByteArray `json:"current_version"` - Epoch Uinteger `json:"epoch"` + PreviousVersion utils.ByteArray `json:"previous_version"` + CurrentVersion utils.ByteArray `json:"current_version"` + Epoch utils.Uinteger `json:"epoch"` } `json:"data"` } type AttestationsResponse struct { @@ -82,18 +79,18 @@ type AttestationsResponse struct { type BeaconBlockResponse struct { Data struct { Message struct { - Slot Uinteger `json:"slot"` - ProposerIndex string `json:"proposer_index"` + Slot utils.Uinteger `json:"slot"` + ProposerIndex string `json:"proposer_index"` Body struct { Eth1Data struct { - DepositRoot ByteArray `json:"deposit_root"` - DepositCount Uinteger `json:"deposit_count"` - BlockHash ByteArray `json:"block_hash"` + DepositRoot utils.ByteArray `json:"deposit_root"` + DepositCount utils.Uinteger `json:"deposit_count"` + BlockHash utils.ByteArray `json:"block_hash"` } `json:"eth1_data"` Attestations []Attestation `json:"attestations"` ExecutionPayload *struct { - FeeRecipient ByteArray `json:"fee_recipient"` - BlockNumber Uinteger `json:"block_number"` + FeeRecipient utils.ByteArray `json:"fee_recipient"` + BlockNumber utils.Uinteger `json:"block_number"` } `json:"execution_payload"` } `json:"body"` } `json:"message"` @@ -106,8 +103,8 @@ type BeaconBlockHeaderResponse struct { Canonical bool `json:"canonical"` Header struct { Message struct { - Slot Uinteger `json:"slot"` - ProposerIndex string `json:"proposer_index"` + Slot utils.Uinteger `json:"slot"` + ProposerIndex string `json:"proposer_index"` } `json:"message"` } `json:"header"` } `json:"data"` @@ -116,27 +113,27 @@ type ValidatorsResponse struct { Data []Validator `json:"data"` } type Validator struct { - Index string `json:"index"` - Balance Uinteger `json:"balance"` - Status string `json:"status"` + Index string `json:"index"` + Balance utils.Uinteger `json:"balance"` + Status string `json:"status"` Validator struct { - Pubkey ByteArray `json:"pubkey"` - WithdrawalCredentials ByteArray `json:"withdrawal_credentials"` - EffectiveBalance Uinteger `json:"effective_balance"` - Slashed bool `json:"slashed"` - ActivationEligibilityEpoch Uinteger `json:"activation_eligibility_epoch"` - ActivationEpoch Uinteger `json:"activation_epoch"` - ExitEpoch Uinteger `json:"exit_epoch"` - WithdrawableEpoch Uinteger `json:"withdrawable_epoch"` + Pubkey utils.ByteArray `json:"pubkey"` + WithdrawalCredentials utils.ByteArray `json:"withdrawal_credentials"` + EffectiveBalance utils.Uinteger `json:"effective_balance"` + Slashed bool `json:"slashed"` + ActivationEligibilityEpoch utils.Uinteger `json:"activation_eligibility_epoch"` + ActivationEpoch utils.Uinteger `json:"activation_epoch"` + ExitEpoch utils.Uinteger `json:"exit_epoch"` + WithdrawableEpoch utils.Uinteger `json:"withdrawable_epoch"` } `json:"validator"` } type SyncDutiesResponse struct { Data []SyncDuty `json:"data"` } type SyncDuty struct { - Pubkey ByteArray `json:"pubkey"` - ValidatorIndex string `json:"validator_index"` - SyncCommitteeIndices []Uinteger `json:"validator_sync_committee_indices"` + Pubkey utils.ByteArray `json:"pubkey"` + ValidatorIndex string `json:"validator_index"` + SyncCommitteeIndices []utils.Uinteger `json:"validator_sync_committee_indices"` } type ProposerDutiesResponse struct { Data []ProposerDuty `json:"data"` @@ -152,59 +149,7 @@ type CommitteesResponse struct { type Attestation struct { AggregationBits string `json:"aggregation_bits"` Data struct { - Slot Uinteger `json:"slot"` - Index Uinteger `json:"index"` + Slot utils.Uinteger `json:"slot"` + Index utils.Uinteger `json:"index"` } `json:"data"` } - -// Unsigned integer type -type Uinteger uint64 - -func (i Uinteger) MarshalJSON() ([]byte, error) { - return json.Marshal(strconv.FormatUint(uint64(i), 10)) -} -func (i *Uinteger) UnmarshalJSON(data []byte) error { - - // Unmarshal string - var dataStr string - if err := json.Unmarshal(data, &dataStr); err != nil { - return err - } - - // Parse integer value - value, err := strconv.ParseUint(dataStr, 10, 64) - if err != nil { - return err - } - - // Set value and return - *i = Uinteger(value) - return nil - -} - -// Byte array type -type ByteArray []byte - -func (b ByteArray) MarshalJSON() ([]byte, error) { - return json.Marshal(utils.EncodeHexWithPrefix(b)) -} -func (b *ByteArray) UnmarshalJSON(data []byte) error { - - // Unmarshal string - var dataStr string - if err := json.Unmarshal(data, &dataStr); err != nil { - return err - } - - // Decode hex - value, err := utils.DecodeHex(dataStr) - if err != nil { - return err - } - - // Set value and return - *b = value - return nil - -} diff --git a/config/network-settings.go b/config/network-settings.go index 0c8eba6..49f700f 100644 --- a/config/network-settings.go +++ b/config/network-settings.go @@ -7,42 +7,31 @@ import ( "os" "github.com/ethereum/go-ethereum/common" + "github.com/rocket-pool/node-manager-core/utils" "gopkg.in/yaml.v3" ) -const () - var ( - DefaultMainnetSettings = &NetworkSettings{ - Key: "mainnet", - Name: "Ethereum Mainnet", - Description: "The Ethereum Mainnet network", - NetworkResources: &NetworkResources{ - EthNetworkName: "mainnet", - ChainID: 1, - GenesisForkVersion: common.FromHex("0x00000000"), // https://github.com/eth-clients/eth2-networks/tree/master/shared/mainnet#genesis-information - MulticallAddress: common.HexToAddress("0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696"), - BalanceBatcherAddress: common.HexToAddress("0xb1f8e55c7f64d203c1400b9d8555d050f94adf39"), - TxWatchUrl: "https://etherscan.io/tx", - FlashbotsProtectUrl: "https://rpc.flashbots.net/", - }, - DefaultConfigSettings: map[string]any{}, + // Reference for Mainnet network resources, not used directly but helpful for testing + MainnetResourcesReference *NetworkResources = &NetworkResources{ + EthNetworkName: "mainnet", + ChainID: 1, + GenesisForkVersion: common.FromHex("0x00000000"), // https://github.com/eth-clients/eth2-networks/tree/master/shared/mainnet#genesis-information + MulticallAddress: common.HexToAddress("0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696"), + BalanceBatcherAddress: common.HexToAddress("0xb1f8e55c7f64d203c1400b9d8555d050f94adf39"), + TxWatchUrl: "https://etherscan.io/tx", + FlashbotsProtectUrl: "https://rpc.flashbots.net/", } - DefaultHoleskySettings = &NetworkSettings{ - Key: "holesky", - Name: "Holesky Testnet", - Description: "The Ethereum holesky public test network", - NetworkResources: &NetworkResources{ - EthNetworkName: "holesky", - ChainID: 17000, - GenesisForkVersion: common.FromHex("0x01017000"), // https://github.com/eth-clients/holesky - MulticallAddress: common.HexToAddress("0x0540b786f03c9491f3a2ab4b0e3ae4ecd4f63ce7"), - BalanceBatcherAddress: common.HexToAddress("0xfAa2e7C84eD801dd9D27Ac1ed957274530796140"), - TxWatchUrl: "https://holesky.etherscan.io/tx", - FlashbotsProtectUrl: "https://rpc-holesky.flashbots.net", - }, - DefaultConfigSettings: map[string]any{}, + // Reference for Holesky network resources, not used directly but helpful for testing + HoleskyResourcesReference *NetworkResources = &NetworkResources{ + EthNetworkName: "holesky", + ChainID: 17000, + GenesisForkVersion: common.FromHex("0x01017000"), // https://github.com/eth-clients/holesky + MulticallAddress: common.HexToAddress("0x0540b786f03c9491f3a2ab4b0e3ae4ecd4f63ce7"), + BalanceBatcherAddress: common.HexToAddress("0xfAa2e7C84eD801dd9D27Ac1ed957274530796140"), + TxWatchUrl: "https://holesky.etherscan.io/tx", + FlashbotsProtectUrl: "https://rpc-holesky.flashbots.net", } ) @@ -55,7 +44,7 @@ type NetworkResources struct { ChainID uint `yaml:"chainID" json:"chainID"` // The genesis fork version for the network according to the Beacon config for the network - GenesisForkVersion []byte `yaml:"genesisForkVersion" json:"genesisForkVersion"` + GenesisForkVersion utils.ByteArray `yaml:"genesisForkVersion" json:"genesisForkVersion"` // The address of the multicall contract MulticallAddress common.Address `yaml:"multicallAddress" json:"multicallAddress"` @@ -86,7 +75,7 @@ type NetworkSettings struct { // A collection of default configuration settings to use for the network, which will override // the standard "general-purpose" default value for the setting - DefaultConfigSettings map[string]any `yaml:"defaultConfigSettings" json:"defaultConfigSettings"` + DefaultConfigSettings map[string]any `yaml:"defaultConfigSettings,omitempty" json:"defaultConfigSettings,omitempty"` } // Load network settings from a file diff --git a/utils/types.go b/utils/types.go new file mode 100644 index 0000000..c3ef6e6 --- /dev/null +++ b/utils/types.go @@ -0,0 +1,83 @@ +package utils + +import ( + "encoding/json" + "strconv" + + "gopkg.in/yaml.v3" +) + +// Unsigned integer type +type Uinteger uint64 + +func (i Uinteger) MarshalYAML() (interface{}, error) { + return strconv.FormatUint(uint64(i), 10), nil +} + +func (i *Uinteger) UnmarshalYAML(value *yaml.Node) error { + intVal, err := strconv.ParseUint(value.Value, 10, 64) + if err != nil { + return err + } + *i = Uinteger(intVal) + return nil +} + +func (i Uinteger) MarshalJSON() ([]byte, error) { + return json.Marshal(strconv.FormatUint(uint64(i), 10)) +} +func (i *Uinteger) UnmarshalJSON(data []byte) error { + // Unmarshal string + var dataStr string + if err := json.Unmarshal(data, &dataStr); err != nil { + return err + } + + // Parse integer value + value, err := strconv.ParseUint(dataStr, 10, 64) + if err != nil { + return err + } + + // Set value and return + *i = Uinteger(value) + return nil +} + +// Byte array type +type ByteArray []byte + +func (b ByteArray) MarshalYAML() (interface{}, error) { + return EncodeHexWithPrefix(b), nil +} + +func (b *ByteArray) UnmarshalYAML(value *yaml.Node) error { + bytes, err := DecodeHex(value.Value) + if err != nil { + return err + } + *b = bytes + return nil +} + +func (b ByteArray) MarshalJSON() ([]byte, error) { + return json.Marshal(EncodeHexWithPrefix(b)) +} + +func (b *ByteArray) UnmarshalJSON(data []byte) error { + // Unmarshal string + var dataStr string + if err := json.Unmarshal(data, &dataStr); err != nil { + return err + } + + // Decode hex + value, err := DecodeHex(dataStr) + if err != nil { + return err + } + + // Set value and return + *b = value + return nil +} From 55e038b8f0e591410a2f8a6525403281f94a3497 Mon Sep 17 00:00:00 2001 From: Joe Clapis Date: Tue, 16 Jul 2024 13:24:02 -0400 Subject: [PATCH 3/3] Removed deprecation from the Network type --- config/enums.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/enums.go b/config/enums.go index 01f3732..214a120 100644 --- a/config/enums.go +++ b/config/enums.go @@ -10,7 +10,7 @@ const ( EthNetwork_Holesky string = "holesky" ) -// Deprecated: Switch to using dynamically-loaded network settings instead +// Type for network keys, used in NetworkSettings to uniquely define the network type Network string // Enum to describe well-known network keys for convenience, which may or may not be used by the application. @@ -21,10 +21,10 @@ const ( // All networks (used for parameter defaults) Network_All Network = "all" - // The Ethereum mainnet + // The standard key for an Ethereum mainnet config Network_Mainnet Network = Network(EthNetwork_Mainnet) - // The Holesky test network + // The standard key for the Holesky test network Network_Holesky Network = Network(EthNetwork_Holesky) )