From f4b4aba9c084592eac80787d944b7dbb9e2e7699 Mon Sep 17 00:00:00 2001 From: corey Date: Wed, 14 Jan 2026 17:30:55 +0800 Subject: [PATCH 1/3] fix NewRetryableClient --- node/core/executor.go | 9 ++++++++- node/derivation/derivation.go | 4 +++- node/types/retryable_client.go | 23 ++++------------------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/node/core/executor.go b/node/core/executor.go index 43aeb21a..2757600f 100644 --- a/node/core/executor.go +++ b/node/core/executor.go @@ -98,7 +98,14 @@ func NewExecutor(newSyncFunc NewSyncerFunc, config *Config, tmPubKey crypto.PubK logger.Info("L2Next geth not configured (no upgrade switch)") } - l2Client := types.NewRetryableClient(aClient, eClient, aNextClient, eNextClient, config.L2.EthAddr, config.Logger) + // Fetch geth config at startup + gethCfg, err := types.FetchGethConfig(config.L2.EthAddr, logger) + if err != nil { + return nil, fmt.Errorf("failed to fetch geth config: %w", err) + } + logger.Info("Geth config fetched", "switchTime", gethCfg.SwitchTime, "useZktrie", gethCfg.UseZktrie) + + l2Client := types.NewRetryableClient(aClient, eClient, aNextClient, eNextClient, gethCfg.SwitchTime, logger) index, err := getNextL1MsgIndex(l2Client) if err != nil { return nil, err diff --git a/node/derivation/derivation.go b/node/derivation/derivation.go index 65d34d09..8f862ee0 100644 --- a/node/derivation/derivation.go +++ b/node/derivation/derivation.go @@ -146,6 +146,8 @@ func NewDerivationClient(ctx context.Context, cfg *Config, syncer *sync.Syncer, } logger.Info("Geth config fetched", "switchTime", gethCfg.SwitchTime, "useZktrie", gethCfg.UseZktrie) + l2Client := types.NewRetryableClient(aClient, eClient, aNextClient, eNextClient, gethCfg.SwitchTime, logger) + return &Derivation{ ctx: ctx, db: db, @@ -159,7 +161,7 @@ func NewDerivationClient(ctx context.Context, cfg *Config, syncer *sync.Syncer, logger: logger, RollupContractAddress: cfg.RollupContractAddress, confirmations: cfg.L1.Confirmations, - l2Client: types.NewRetryableClient(aClient, eClient, aNextClient, eNextClient, cfg.L2.EthAddr, logger), + l2Client: l2Client, cancel: cancel, stop: make(chan struct{}), startHeight: cfg.StartHeight, diff --git a/node/types/retryable_client.go b/node/types/retryable_client.go index 5bdf9a73..629926f2 100644 --- a/node/types/retryable_client.go +++ b/node/types/retryable_client.go @@ -111,15 +111,6 @@ func FetchGethConfig(rpcURL string, logger tmlog.Logger) (*GethConfig, error) { return config, nil } -// fetchMPTForkTime fetches the MPT fork time from geth via eth_config API (internal) -func fetchMPTForkTime(rpcURL string, logger tmlog.Logger) (uint64, error) { - config, err := FetchGethConfig(rpcURL, logger) - if err != nil { - return 0, err - } - return config.SwitchTime, nil -} - type RetryableClient struct { authClient *authclient.Client // current geth ethClient *ethclient.Client // current geth @@ -131,22 +122,16 @@ type RetryableClient struct { logger tmlog.Logger } -// NewRetryableClient creates a new retryable client that fetches switch time from geth. -// The l2EthAddr is used to fetch the switch time via eth_config API. +// NewRetryableClient creates a new retryable client with the given switch time. // Will retry calling the api, if the connection is refused. // // If nextAuthClient or nextEthClient is nil, switch is disabled and only current client is used. // This is useful for nodes that don't need to switch geth (most nodes). -func NewRetryableClient(authClient *authclient.Client, ethClient *ethclient.Client, nextAuthClient *authclient.Client, nextEthClient *ethclient.Client, l2EthAddr string, logger tmlog.Logger) *RetryableClient { +// +// The switchTime should be fetched via FetchGethConfig before calling this function. +func NewRetryableClient(authClient *authclient.Client, ethClient *ethclient.Client, nextAuthClient *authclient.Client, nextEthClient *ethclient.Client, switchTime uint64, logger tmlog.Logger) *RetryableClient { logger = logger.With("module", "retryClient") - // Fetch switch time from geth - switchTime, err := fetchMPTForkTime(l2EthAddr, logger) - if err != nil { - logger.Error("Failed to fetch switch time from geth, using 0", "error", err) - switchTime = 0 - } - // If next client is not configured, disable switch if nextAuthClient == nil || nextEthClient == nil { logger.Info("L2Next client not configured, switch disabled") From 7fde1eeafe08d197227b640baeb428e75dd9c951 Mon Sep 17 00:00:00 2001 From: corey Date: Thu, 15 Jan 2026 11:41:16 +0800 Subject: [PATCH 2/3] clean --- node/derivation/derivation.go | 4 +--- node/types/retryable_client.go | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/node/derivation/derivation.go b/node/derivation/derivation.go index 8f862ee0..2592b2e4 100644 --- a/node/derivation/derivation.go +++ b/node/derivation/derivation.go @@ -146,8 +146,6 @@ func NewDerivationClient(ctx context.Context, cfg *Config, syncer *sync.Syncer, } logger.Info("Geth config fetched", "switchTime", gethCfg.SwitchTime, "useZktrie", gethCfg.UseZktrie) - l2Client := types.NewRetryableClient(aClient, eClient, aNextClient, eNextClient, gethCfg.SwitchTime, logger) - return &Derivation{ ctx: ctx, db: db, @@ -161,7 +159,7 @@ func NewDerivationClient(ctx context.Context, cfg *Config, syncer *sync.Syncer, logger: logger, RollupContractAddress: cfg.RollupContractAddress, confirmations: cfg.L1.Confirmations, - l2Client: l2Client, + l2Client: types.NewRetryableClient(aClient, eClient, aNextClient, eNextClient, gethCfg.SwitchTime, logger), cancel: cancel, stop: make(chan struct{}), startHeight: cfg.StartHeight, diff --git a/node/types/retryable_client.go b/node/types/retryable_client.go index 629926f2..88a4c0e5 100644 --- a/node/types/retryable_client.go +++ b/node/types/retryable_client.go @@ -111,6 +111,15 @@ func FetchGethConfig(rpcURL string, logger tmlog.Logger) (*GethConfig, error) { return config, nil } +// fetchMPTForkTime fetches the MPT fork time from geth via eth_config API (internal) +func fetchMPTForkTime(rpcURL string, logger tmlog.Logger) (uint64, error) { + config, err := FetchGethConfig(rpcURL, logger) + if err != nil { + return 0, err + } + return config.SwitchTime, nil +} + type RetryableClient struct { authClient *authclient.Client // current geth ethClient *ethclient.Client // current geth From 456b5f7ab19fe92312aa745199b93f0d6b2f540e Mon Sep 17 00:00:00 2001 From: corey Date: Thu, 15 Jan 2026 16:23:45 +0800 Subject: [PATCH 3/3] clean --- node/types/retryable_client.go | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/node/types/retryable_client.go b/node/types/retryable_client.go index 88a4c0e5..53d94f35 100644 --- a/node/types/retryable_client.go +++ b/node/types/retryable_client.go @@ -40,12 +40,12 @@ type configResponse struct { // forkConfig represents a single fork configuration type forkConfig struct { - ActivationTime uint64 `json:"activationTime"` - ChainId string `json:"chainId"` - ForkId string `json:"forkId"` - Precompiles map[string]string `json:"precompiles"` - SystemContracts map[string]string `json:"systemContracts"` - Morph *morphExtension `json:"morph,omitempty"` + ActivationTime uint64 `json:"activationTime"` + ChainId string `json:"chainId"` + ForkId string `json:"forkId"` + Precompiles map[string]string `json:"precompiles"` + SystemContracts map[string]string `json:"systemContracts"` + Morph *morphExtension `json:"morph,omitempty"` } // morphExtension contains Morph-specific configuration fields @@ -111,15 +111,6 @@ func FetchGethConfig(rpcURL string, logger tmlog.Logger) (*GethConfig, error) { return config, nil } -// fetchMPTForkTime fetches the MPT fork time from geth via eth_config API (internal) -func fetchMPTForkTime(rpcURL string, logger tmlog.Logger) (uint64, error) { - config, err := FetchGethConfig(rpcURL, logger) - if err != nil { - return 0, err - } - return config.SwitchTime, nil -} - type RetryableClient struct { authClient *authclient.Client // current geth ethClient *ethclient.Client // current geth @@ -185,7 +176,6 @@ func NewRetryableClient(authClient *authclient.Client, ethClient *ethclient.Clie return rc } - func (rc *RetryableClient) aClient() *authclient.Client { if !rc.switched.Load() { return rc.authClient