From 9f2b58a57ca61bf059bb4fe37072be78a2bc732c Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 26 Dec 2025 08:48:10 +0100 Subject: [PATCH] Load specs from beacon node --- beaconclient/prod_beacon_instance.go | 5 +++ cmd/api.go | 52 ++++++++++++++++++++++++---- common/types.go | 3 ++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/beaconclient/prod_beacon_instance.go b/beaconclient/prod_beacon_instance.go index a69a622f6..39fca1c13 100644 --- a/beaconclient/prod_beacon_instance.go +++ b/beaconclient/prod_beacon_instance.go @@ -324,6 +324,11 @@ type GetSpecResponse struct { DomainAggregateAndProof string `json:"DOMAIN_AGGREGATE_AND_PROOF"` //nolint:tagliatelle InactivityPenaltyQuotient string `json:"INACTIVITY_PENALTY_QUOTIENT"` //nolint:tagliatelle InactivityPenaltyQuotientAltair string `json:"INACTIVITY_PENALTY_QUOTIENT_ALTAIR"` //nolint:tagliatelle + BellatrixForkVersion string `json:"BELLATRIX_FORK_VERSION"` //nolint:tagliatelle + CapellaForkVersion string `json:"CAPELLA_FORK_VERSION"` //nolint:tagliatelle + DenebForkVersion string `json:"DENEB_FORK_VERSION"` //nolint:tagliatelle + ElectraForkVersion string `json:"ELECTRA_FORK_VERSION"` //nolint:tagliatelle + FuluForkVersion string `json:"FULU_FORK_VERSION"` //nolint:tagliatelle } // GetSpec - https://ethereum.github.io/beacon-APIs/#/Config/getSpec diff --git a/cmd/api.go b/cmd/api.go index ef23a3d16..116d5f7d0 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -1,6 +1,7 @@ package cmd import ( + "fmt" "net/url" "os" "os/signal" @@ -90,13 +91,6 @@ var apiCmd = &cobra.Command{ } log.Infof("boost-relay %s", Version) - networkInfo, err := common.NewEthNetworkDetails(network) - if err != nil { - log.WithError(err).Fatalf("error getting network details") - } - log.Infof("Using network: %s", networkInfo.Name) - log.Debug(networkInfo.String()) - // Connect to beacon clients and ensure it's synced if len(beaconNodeURIs) == 0 { log.Fatalf("no beacon endpoints specified") @@ -117,6 +111,19 @@ var apiCmd = &cobra.Command{ } beaconClient := beaconclient.NewMultiBeaconClient(log, beaconInstances) + if network == "" { + if err := loadSpecFromBeaconClient(beaconClient); err != nil { + log.WithError(err).Fatalf("error loading spec from beacon client") + } + } + + networkInfo, err := common.NewEthNetworkDetails(network) + if err != nil { + log.WithError(err).Fatalf("error getting network details") + } + log.Infof("Using network: %s", networkInfo.Name) + log.Debug(networkInfo.String()) + // Connect to Redis if redisReadonlyURI == "" { log.Infof("Connecting to Redis at %s ...", redisURI) @@ -217,3 +224,34 @@ var apiCmd = &cobra.Command{ log.Info("bye") }, } + +// loadSpecFromBeaconClient fetches the chain spec and genesis data from the beacon client +// and sets the corresponding environment variables for fork versions and genesis info. +// This allows the relay to automatically configure network parameters without manual specification. +func loadSpecFromBeaconClient(beaconClient *beaconclient.MultiBeaconClient) error { + spec, err := beaconClient.GetSpec() + if err != nil { + return err + } + + genesis, err := beaconClient.GetGenesis() + if err != nil { + return err + } + + envs := map[string]string{ + "GENESIS_FORK_VERSION": genesis.Data.GenesisForkVersion, + "GENESIS_VALIDATORS_ROOT": genesis.Data.GenesisValidatorsRoot, + "BELLATRIX_FORK_VERSION": spec.BellatrixForkVersion, + "CAPELLA_FORK_VERSION": spec.CapellaForkVersion, + "DENEB_FORK_VERSION": spec.DenebForkVersion, + "ELECTRA_FORK_VERSION": spec.ElectraForkVersion, + "FULU_FORK_VERSION": spec.FuluForkVersion, + } + for k, v := range envs { + if err := os.Setenv(k, v); err != nil { + return fmt.Errorf("failed to set env var %s: %w", k, err) + } + } + return nil +} diff --git a/common/types.go b/common/types.go index 59f72a27c..efe2f8b9f 100644 --- a/common/types.go +++ b/common/types.go @@ -31,6 +31,7 @@ var ( EthNetworkHoodi = "hoodi" EthNetworkMainnet = "mainnet" EthNetworkCustom = "custom" + EthNetworkBeacon = "" GenesisForkVersionHolesky = "0x01017000" GenesisForkVersionSepolia = "0x90000069" @@ -155,6 +156,8 @@ func NewEthNetworkDetails(networkName string) (ret *EthNetworkDetails, err error denebForkVersion = DenebForkVersionMainnet electraForkVersion = ElectraForkVersionMainnet fuluForkVersion = FuluForkVersionMainnet + case EthNetworkBeacon: + fallthrough case EthNetworkCustom: genesisForkVersion = os.Getenv("GENESIS_FORK_VERSION") genesisValidatorsRoot = os.Getenv("GENESIS_VALIDATORS_ROOT")