diff --git a/beacon/engine/errors.go b/beacon/engine/errors.go index 5e4d7536a..c4c858d9d 100644 --- a/beacon/engine/errors.go +++ b/beacon/engine/errors.go @@ -49,6 +49,11 @@ func (e *EngineAPIError) With(err error) *EngineAPIError { } } +// SetStage sets error stage in seal payload +func (e *EngineAPIError) SetStage(stage string) { + e.msg = stage + e.msg +} + var ( _ rpc.Error = new(EngineAPIError) _ rpc.DataError = new(EngineAPIError) diff --git a/beacon/engine/types.go b/beacon/engine/types.go index 960c68d5e..48173eb79 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -31,9 +31,9 @@ import ( type PayloadVersion byte const ( - GetPayloadStage = "getPayload" - NewPayloadStage = "newPayload" - ForkchoiceUpdatedStage = "forkchoiceUpdated" + GetPayloadStage = "sealApiGetPayloadErrStage" + NewPayloadStage = "sealApiNewPayloadErrStage" + ForkchoiceUpdatedStage = "sealApiForkchoiceUpdatedErrStage" ) var ( diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 7a6f9fdf5..a5f5b0156 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -723,11 +723,18 @@ func (api *ConsensusAPI) opSealPayload(payloadID engine.PayloadID, update engine } else if version == "V3" { payloadEnvelope, err = api.GetPayloadV3(payloadID) } else { - return engine.OpSealPayloadResponse{ErrStage: engine.GetPayloadStage}, engine.UnsupportedFork.With(errors.New("invalid engine api version")) + forkErr := engine.UnsupportedFork.With(errors.New(engine.GetPayloadStage + "invalid engine api version")) + forkErr.SetStage(engine.GetPayloadStage) + return engine.OpSealPayloadResponse{ErrStage: engine.GetPayloadStage}, forkErr } if err != nil { + if engineApiErr, ok := err.(*engine.EngineAPIError); ok { + engineApiErr.SetStage(engine.GetPayloadStage) + log.Error("Seal payload engineApiError when get payload", "error", engineApiErr.Error(), "code", engineApiErr.ErrorCode(), "payloadID", payloadID) + return engine.OpSealPayloadResponse{ErrStage: engine.GetPayloadStage}, engineApiErr + } log.Error("Seal payload error when get payload", "error", err, "payloadID", payloadID) - return engine.OpSealPayloadResponse{ErrStage: engine.GetPayloadStage}, err + return engine.OpSealPayloadResponse{ErrStage: engine.GetPayloadStage}, fmt.Errorf("sealApiGetPayloadErrStage: %w", err) } var payloadStatus engine.PayloadStatusV1 @@ -736,18 +743,38 @@ func (api *ConsensusAPI) opSealPayload(payloadID engine.PayloadID, update engine } else if version == "V3" { payloadStatus, err = api.NewPayloadV3(*payloadEnvelope.ExecutionPayload, []common.Hash{}, payloadEnvelope.ParentBeaconBlockRoot) } else { - return engine.OpSealPayloadResponse{ErrStage: engine.NewPayloadStage}, engine.UnsupportedFork.With(errors.New("invalid engine api version")) + forkErr := engine.UnsupportedFork.With(errors.New(engine.NewPayloadStage + "invalid engine api version")) + forkErr.SetStage(engine.NewPayloadStage) + return engine.OpSealPayloadResponse{ErrStage: engine.NewPayloadStage}, forkErr } - if err != nil || payloadStatus.Status != engine.VALID { + if err != nil { + if engineApiErr, ok := err.(*engine.EngineAPIError); ok { + engineApiErr.SetStage(engine.NewPayloadStage) + log.Error("Seal payload engineApiError when new payload", "error", engineApiErr.Error(), "code", engineApiErr.ErrorCode(), "payloadStatus", payloadStatus) + return engine.OpSealPayloadResponse{ErrStage: engine.NewPayloadStage, PayloadStatus: payloadStatus}, engineApiErr + } log.Error("Seal payload error when new payload", "error", err, "payloadStatus", payloadStatus) - return engine.OpSealPayloadResponse{ErrStage: engine.NewPayloadStage, PayloadStatus: payloadStatus}, err + return engine.OpSealPayloadResponse{ErrStage: engine.NewPayloadStage, PayloadStatus: payloadStatus}, fmt.Errorf("sealApiNewPayloadErrStage: %w", err) + } + if payloadStatus.Status != engine.VALID { + log.Error("Seal payload status error when new payload", "payloadStatus", payloadStatus) + return engine.OpSealPayloadResponse{ErrStage: engine.NewPayloadStage, PayloadStatus: payloadStatus}, nil } update.HeadBlockHash = payloadEnvelope.ExecutionPayload.BlockHash updateResponse, err := api.ForkchoiceUpdatedV3(update, nil) - if err != nil || updateResponse.PayloadStatus.Status != engine.VALID { + if err != nil { + if engineApiErr, ok := err.(*engine.EngineAPIError); ok { + engineApiErr.SetStage(engine.ForkchoiceUpdatedStage) + log.Error("Seal payload engineApiError when forkchoiceUpdated", "error", engineApiErr.Error(), "code", engineApiErr.ErrorCode(), "payloadStatus", updateResponse.PayloadStatus) + return engine.OpSealPayloadResponse{ErrStage: engine.ForkchoiceUpdatedStage, PayloadStatus: updateResponse.PayloadStatus}, engineApiErr + } log.Error("Seal payload error when forkchoiceUpdated", "error", err, "payloadStatus", updateResponse.PayloadStatus) - return engine.OpSealPayloadResponse{ErrStage: engine.ForkchoiceUpdatedStage, PayloadStatus: updateResponse.PayloadStatus}, err + return engine.OpSealPayloadResponse{ErrStage: engine.ForkchoiceUpdatedStage, PayloadStatus: updateResponse.PayloadStatus}, fmt.Errorf("sealApiForkchoiceUpdatedErrStage: %w", err) + } + if updateResponse.PayloadStatus.Status != engine.VALID { + log.Error("Seal payload status error when forkchoiceUpdated", "payloadStatus", updateResponse.PayloadStatus) + return engine.OpSealPayloadResponse{ErrStage: engine.ForkchoiceUpdatedStage, PayloadStatus: updateResponse.PayloadStatus}, nil } log.Info("opSealPayload succeed", "hash", payloadEnvelope.ExecutionPayload.BlockHash, "number", payloadEnvelope.ExecutionPayload.Number, "id", payloadID, "payloadStatus", updateResponse.PayloadStatus)