Skip to content

Commit 3f72b41

Browse files
committed
Add --custom-spec-support flag for non-mainnet SSZ presets
Build the go-eth2-client HTTP client with WithCustomSpecSupport when the new --custom-spec-support persistent flag is set, switching from the static mainnet fastssz decoder to dynamic-ssz. Without it, decoding a non-mainnet preset beacon state (e.g. Gnosis) fails with: invalid ssz encoding. first variable element offset indexes into fixed value data because the static mainnet-preset decoder misreads the variable-length offsets of a Gnosis-preset BeaconState. This blocks "validator exit --prepare-offline" against a Gnosis node, which fetches the full beacon state via SSZ. Threads the flag through ConnectOpts and connectToBeaconNode, and wires it into the validator exit command's ConnectToBeaconNode call, mirroring the existing --allow-insecure-connections plumbing.
1 parent ae1b9af commit 3f72b41

4 files changed

Lines changed: 21 additions & 12 deletions

File tree

cmd/root.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ func addPersistentFlags() {
253253
if err := viper.BindPFlag("allow-insecure-connections", RootCmd.PersistentFlags().Lookup("allow-insecure-connections")); err != nil {
254254
panic(err)
255255
}
256+
RootCmd.PersistentFlags().Bool("custom-spec-support", false, "use dynamic SSZ to support non-mainnet presets (e.g. Gnosis); slower than the static decoder")
257+
if err := viper.BindPFlag("custom-spec-support", RootCmd.PersistentFlags().Lookup("custom-spec-support")); err != nil {
258+
panic(err)
259+
}
256260
}
257261

258262
// initConfig reads in config file and ENV variables if set.

cmd/validator/exit/command.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type command struct {
5050
timeout time.Duration
5151
connection string
5252
allowInsecureConnections bool
53+
customSpecSupport bool
5354

5455
// Information required to generate the operations.
5556
chainInfo *beacon.ChainInfo
@@ -73,6 +74,7 @@ func newCommand(_ context.Context) (*command, error) {
7374
timeout: viper.GetDuration("timeout"),
7475
connection: viper.GetString("connection"),
7576
allowInsecureConnections: viper.GetBool("allow-insecure-connections"),
77+
customSpecSupport: viper.GetBool("custom-spec-support"),
7678
prepareOffline: viper.GetBool("prepare-offline"),
7779
passphrases: util.GetPassphrases(),
7880
mnemonic: viper.GetString("mnemonic"),

cmd/validator/exit/process.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,11 @@ func (c *command) setup(ctx context.Context) error {
595595
// Connect to the consensus node.
596596
var err error
597597
c.consensusClient, err = util.ConnectToBeaconNode(ctx, &util.ConnectOpts{
598-
Address: c.connection,
599-
Timeout: c.timeout,
600-
AllowInsecure: c.allowInsecureConnections,
601-
LogFallback: !c.quiet,
598+
Address: c.connection,
599+
Timeout: c.timeout,
600+
AllowInsecure: c.allowInsecureConnections,
601+
CustomSpecSupport: c.customSpecSupport,
602+
LogFallback: !c.quiet,
602603
})
603604
if err != nil {
604605
return err

util/beaconnode.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ var defaultBeaconNodeAddresses = []string{
3838
var fallbackBeaconNode = "http://mainnet-consensus.attestant.io/"
3939

4040
type ConnectOpts struct {
41-
Address string
42-
Timeout time.Duration
43-
AllowInsecure bool
44-
LogFallback bool
41+
Address string
42+
Timeout time.Duration
43+
AllowInsecure bool
44+
CustomSpecSupport bool
45+
LogFallback bool
4546
}
4647

4748
// ConnectToBeaconNode connects to a beacon node at the given address.
@@ -56,12 +57,12 @@ func ConnectToBeaconNode(ctx context.Context, opts *ConnectOpts) (eth2client.Ser
5657

5758
if opts.Address != "" {
5859
// We have an explicit address; use it.
59-
return connectToBeaconNode(ctx, opts.Address, opts.Timeout, opts.AllowInsecure)
60+
return connectToBeaconNode(ctx, opts.Address, opts.Timeout, opts.AllowInsecure, opts.CustomSpecSupport)
6061
}
6162

6263
// Try the defaults.
6364
for _, address := range defaultBeaconNodeAddresses {
64-
client, err := connectToBeaconNode(ctx, address, opts.Timeout, opts.AllowInsecure)
65+
client, err := connectToBeaconNode(ctx, address, opts.Timeout, opts.AllowInsecure, opts.CustomSpecSupport)
6566
if err == nil {
6667
return client, nil
6768
}
@@ -71,15 +72,15 @@ func ConnectToBeaconNode(ctx context.Context, opts *ConnectOpts) (eth2client.Ser
7172
if opts.LogFallback {
7273
fmt.Fprintf(os.Stderr, "No connection supplied with --connection parameter and no local beacon node found, attempting to use mainnet fallback\n")
7374
}
74-
client, err := connectToBeaconNode(ctx, fallbackBeaconNode, opts.Timeout, true)
75+
client, err := connectToBeaconNode(ctx, fallbackBeaconNode, opts.Timeout, true, opts.CustomSpecSupport)
7576
if err == nil {
7677
return client, nil
7778
}
7879

7980
return nil, errors.New("failed to connect to any beacon node")
8081
}
8182

82-
func connectToBeaconNode(ctx context.Context, address string, timeout time.Duration, allowInsecure bool) (eth2client.Service, error) {
83+
func connectToBeaconNode(ctx context.Context, address string, timeout time.Duration, allowInsecure bool, customSpecSupport bool) (eth2client.Service, error) {
8384
if !strings.HasPrefix(address, "http") {
8485
address = fmt.Sprintf("http://%s", address)
8586
}
@@ -101,6 +102,7 @@ func connectToBeaconNode(ctx context.Context, address string, timeout time.Durat
101102
http.WithLogLevel(zerolog.Disabled),
102103
http.WithAddress(address),
103104
http.WithTimeout(timeout),
105+
http.WithCustomSpecSupport(customSpecSupport),
104106
)
105107
if err != nil {
106108
return nil, errors.Wrap(err, "failed to connect to beacon node")

0 commit comments

Comments
 (0)