diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 5389ade2f..29e763d32 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" gethRPC "github.com/ethereum/go-ethereum/rpc" "github.com/holiman/uint256" "github.com/pkg/errors" @@ -37,8 +36,6 @@ const ( ExecutionBlockByHashMethod = "eth_getBlockByHash" // ExecutionBlockByNumberMethod request string for JSON-RPC. ExecutionBlockByNumberMethod = "eth_getBlockByNumber" - // Defines the seconds to wait before timing out engine endpoints with block execution semantics (newPayload, forkchoiceUpdated). - payloadAndForkchoiceUpdatedTimeout = 8 * time.Second // Defines the seconds before timing out engine endpoints with non-block execution semantics. defaultEngineTimeout = time.Second ) @@ -85,7 +82,8 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa defer func() { newPayloadLatency.Observe(float64(time.Since(start).Milliseconds())) }() - d := time.Now().Add(payloadAndForkchoiceUpdatedTimeout) + + d := time.Now().Add(time.Duration(params.BeaconConfig().ExecutionEngineTimeoutValue) * time.Second) ctx, cancel := context.WithDeadline(ctx, d) defer cancel() result := &pb.PayloadStatus{} @@ -123,7 +121,7 @@ func (s *Service) ForkchoiceUpdated( forkchoiceUpdatedLatency.Observe(float64(time.Since(start).Milliseconds())) }() - d := time.Now().Add(payloadAndForkchoiceUpdatedTimeout) + d := time.Now().Add(time.Duration(params.BeaconConfig().ExecutionEngineTimeoutValue) * time.Second) ctx, cancel := context.WithDeadline(ctx, d) defer cancel() result := &ForkchoiceUpdatedResponse{} @@ -322,7 +320,7 @@ func (s *Service) ExecutionBlockByHash(ctx context.Context, hash common.Hash, wi // ExecutionBlocksByHashes fetches a batch of execution engine blocks by hash by calling // eth_blockByHash via JSON-RPC. func (s *Service) ExecutionBlocksByHashes(ctx context.Context, hashes []common.Hash, withTxs bool) ([]*pb.ExecutionBlock, error) { - ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.ExecutionBlocksByHashes") + _, span := trace.StartSpan(ctx, "powchain.engine-api-client.ExecutionBlocksByHashes") defer span.End() numOfHashes := len(hashes) elems := make([]gethRPC.BatchElem, 0, numOfHashes) @@ -524,7 +522,7 @@ func handleRPCError(err error) error { if isTimeout(err) { return ErrHTTPTimeout } - e, ok := err.(rpc.Error) + e, ok := err.(gethRPC.Error) if !ok { if strings.Contains(err.Error(), "401 Unauthorized") { log.Error("HTTP authentication to your execution client is not working. Please ensure " + @@ -563,7 +561,7 @@ func handleRPCError(err error) error { case -32000: errServerErrorCount.Inc() // Only -32000 status codes are data errors in the RPC specification. - errWithData, ok := err.(rpc.DataError) + errWithData, ok := err.(gethRPC.DataError) if !ok { return errors.Wrapf(err, "got an unexpected error in JSON-RPC response") } diff --git a/beacon-chain/node/config.go b/beacon-chain/node/config.go index 550f29023..751700336 100644 --- a/beacon-chain/node/config.go +++ b/beacon-chain/node/config.go @@ -96,6 +96,12 @@ func configureEth1Config(cliCtx *cli.Context) error { return err } } + if cliCtx.IsSet(flags.EngineEndpointTimeoutSeconds.Name) { + c.ExecutionEngineTimeoutValue = cliCtx.Uint64(flags.EngineEndpointTimeoutSeconds.Name) + if err := params.SetActive(c); err != nil { + return err + } + } if cliCtx.IsSet(flags.DepositContractFlag.Name) { c.DepositContractAddress = cliCtx.String(flags.DepositContractFlag.Name) if err := params.SetActive(c); err != nil { diff --git a/cmd/beacon-chain/flags/base.go b/cmd/beacon-chain/flags/base.go index 6080deae8..bd6a72ed0 100644 --- a/cmd/beacon-chain/flags/base.go +++ b/cmd/beacon-chain/flags/base.go @@ -192,6 +192,13 @@ var ( Name: "network-id", Usage: "Sets the network id of the beacon chain.", } + // EngineEndpointTimeoutSeconds defines the seconds to wait before timing out engine endpoints with execution payload execution semantics (newPayload, forkchoiceUpdated). + // If this flag is not used then default will be used as defined here: + // https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#core + EngineEndpointTimeoutSeconds = &cli.Uint64Flag{ + Name: "engine-endpoint-timeout-seconds", + Usage: "Sets the execution engine timeout (seconds) for execution payload semantics (forkchoiceUpdated, newPayload)", + } // Eth1HeaderReqLimit defines a flag to set the maximum number of headers that a deposit log query can fetch. If none is set, 1000 will be the limit. Eth1HeaderReqLimit = &cli.Uint64Flag{ Name: "eth1-header-req-limit", diff --git a/cmd/beacon-chain/main.go b/cmd/beacon-chain/main.go index 8126777a3..c05447c26 100644 --- a/cmd/beacon-chain/main.go +++ b/cmd/beacon-chain/main.go @@ -75,6 +75,7 @@ var appFlags = []cli.Flag{ flags.MevRelayEndpoint, flags.MaxBuilderEpochMissedSlots, flags.MaxBuilderConsecutiveMissedSlots, + flags.EngineEndpointTimeoutSeconds, cmd.BackupWebhookOutputDir, cmd.MinimalConfigFlag, cmd.E2EConfigFlag, diff --git a/cmd/beacon-chain/usage.go b/cmd/beacon-chain/usage.go index 17a43d1f5..8e67f4a56 100644 --- a/cmd/beacon-chain/usage.go +++ b/cmd/beacon-chain/usage.go @@ -125,6 +125,7 @@ var appHelpFlagGroups = []flagGroup{ flags.MevRelayEndpoint, flags.MaxBuilderEpochMissedSlots, flags.MaxBuilderConsecutiveMissedSlots, + flags.EngineEndpointTimeoutSeconds, checkpoint.BlockPath, checkpoint.StatePath, checkpoint.RemoteURL, diff --git a/config/params/config.go b/config/params/config.go index 645933f0a..5b11c6fe8 100644 --- a/config/params/config.go +++ b/config/params/config.go @@ -203,6 +203,9 @@ type BeaconChainConfig struct { // Mev-boost circuit breaker MaxBuilderConsecutiveMissedSlots types.Slot // MaxBuilderConsecutiveMissedSlots defines the number of consecutive skip slot to fallback from using relay/builder to local execution engine for block construction. MaxBuilderEpochMissedSlots types.Slot // MaxBuilderEpochMissedSlots is defines the number of total skip slot (per epoch rolling windows) to fallback from using relay/builder to local execution engine for block construction. + + // Execution engine timeout value + ExecutionEngineTimeoutValue uint64 // ExecutionEngineTimeoutValue defines the seconds to wait before timing out engine endpoints with execution payload execution semantics (newPayload, forkchoiceUpdated). } // InitializeForkSchedule initializes the schedules forks baked into the config. diff --git a/config/params/mainnet_config.go b/config/params/mainnet_config.go index 9fdab50c5..0735308ab 100644 --- a/config/params/mainnet_config.go +++ b/config/params/mainnet_config.go @@ -254,6 +254,9 @@ var mainnetBeaconConfig = &BeaconChainConfig{ // Mevboost circuit breaker MaxBuilderConsecutiveMissedSlots: 3, MaxBuilderEpochMissedSlots: 8, + + // Execution engine timeout value + ExecutionEngineTimeoutValue: 8, // 8 seconds default based on: https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#core } // MainnetTestConfig provides a version of the mainnet config that has a different name