From 0aab77bf99df64084404d4a7a1bb4054420fd6ae Mon Sep 17 00:00:00 2001 From: Elad Gildnur Date: Thu, 21 Mar 2024 17:32:12 +0200 Subject: [PATCH 1/5] Create MethodNotFound errors to reflect real errors from nodes --- protocol/chainlib/base_chain_parser.go | 6 ++- protocol/chainlib/jsonRPC.go | 6 ++- protocol/chainlib/rest.go | 16 +++++++- protocol/chainlib/tendermintRPC.go | 6 ++- protocol/common/errors.go | 1 + protocol/common/return_errors.go | 57 ++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 protocol/common/return_errors.go diff --git a/protocol/chainlib/base_chain_parser.go b/protocol/chainlib/base_chain_parser.go index 802b70f68b..88ed961d4e 100644 --- a/protocol/chainlib/base_chain_parser.go +++ b/protocol/chainlib/base_chain_parser.go @@ -9,6 +9,7 @@ import ( "time" "github.com/lavanet/lava/protocol/chainlib/extensionslib" + "github.com/lavanet/lava/protocol/common" "github.com/lavanet/lava/utils" epochstorage "github.com/lavanet/lava/x/epochstorage/types" pairingtypes "github.com/lavanet/lava/x/pairing/types" @@ -299,7 +300,10 @@ func (apip *BaseChainParser) getSupportedApi(name, connectionType string) (*ApiC // Return an error if spec does not exist if !ok { - return nil, utils.LavaFormatInfo("api not supported", utils.Attribute{Key: "name", Value: name}, utils.Attribute{Key: "connectionType", Value: connectionType}) + return nil, utils.LavaFormatWarning("api not supported", common.APINotSupportedError, + utils.LogAttr("name", name), + utils.LogAttr("connectionType", connectionType), + ) } // Return an error if api is disabled diff --git a/protocol/chainlib/jsonRPC.go b/protocol/chainlib/jsonRPC.go index 13863ba950..01d94d7d2a 100644 --- a/protocol/chainlib/jsonRPC.go +++ b/protocol/chainlib/jsonRPC.go @@ -106,7 +106,7 @@ func (apip *JsonRPCChainParser) ParseMsg(url string, data []byte, connectionType // Check api is supported and save it in nodeMsg apiCont, err := apip.getSupportedApi(msg.Method, connectionType) if err != nil { - return nil, utils.LavaFormatInfo("getSupportedApi jsonrpc failed", utils.LogAttr("reason", err), utils.Attribute{Key: "method", Value: msg.Method}) + return nil, utils.LavaFormatWarning("getSupportedApi jsonrpc failed", err, utils.LogAttr("method", msg.Method)) } apiCollectionForMessage, err := apip.getApiCollection(connectionType, apiCont.collectionKey.InternalPath, apiCont.collectionKey.Addon) @@ -458,6 +458,10 @@ func (apil *JsonRPCChainListener) Serve(ctx context.Context, cmdFlags common.Con reply := relayResult.GetReply() go apil.logger.AddMetricForHttp(metricsData, err, fiberCtx.GetReqHeaders()) if err != nil { + if common.APINotSupportedError.Is(err) { + return fiberCtx.Status(fiber.StatusOK).JSON(common.JsonRpcMethodNotFoundError) + } + // Get unique GUID response errMasking := apil.logger.GetUniqueGuidResponseForError(err, msgSeed) diff --git a/protocol/chainlib/rest.go b/protocol/chainlib/rest.go index 6602e24cab..04c43f670b 100644 --- a/protocol/chainlib/rest.go +++ b/protocol/chainlib/rest.go @@ -173,7 +173,10 @@ func (apip *RestChainParser) getSupportedApi(name, connectionType string) (*ApiC // Return an error if spec does not exist if !ok { - return nil, errors.New("rest api not supported " + name) + return nil, utils.LavaFormatWarning("rest api not supported", common.APINotSupportedError, + utils.LogAttr("name", name), + utils.LogAttr("connectionType", connectionType), + ) } api := apiCont.api @@ -379,6 +382,17 @@ func (apil *RestChainListener) Serve(ctx context.Context, cmdFlags common.Consum reply := relayResult.GetReply() go apil.logger.AddMetricForHttp(analytics, err, fiberCtx.GetReqHeaders()) if err != nil { + if common.APINotSupportedError.Is(err) { + switch chainID { + case "APT1": + // Aptos node returns a different error body than the rest of the chains + // This solution is temporary until we change the spec to state how the error looks like + return fiberCtx.Status(fiber.StatusNotImplemented).JSON(common.RestAptosMethodNotFoundError) + default: + return fiberCtx.Status(fiber.StatusNotImplemented).JSON(common.RestMethodNotFoundError) + } + } + // Get unique GUID response errMasking := apil.logger.GetUniqueGuidResponseForError(err, msgSeed) diff --git a/protocol/chainlib/tendermintRPC.go b/protocol/chainlib/tendermintRPC.go index 3e54c8af25..59ce0d84ea 100644 --- a/protocol/chainlib/tendermintRPC.go +++ b/protocol/chainlib/tendermintRPC.go @@ -137,7 +137,7 @@ func (apip *TendermintChainParser) ParseMsg(urlPath string, data []byte, connect // Check api is supported and save it in nodeMsg apiCont, err := apip.getSupportedApi(msg.Method, connectionType) if err != nil { - return nil, utils.LavaFormatInfo("getSupportedApi jsonrpc failed", utils.LogAttr("reason", err), utils.Attribute{Key: "method", Value: msg.Method}) + return nil, utils.LavaFormatWarning("getSupportedApi jsonrpc failed", err, utils.LogAttr("method", msg.Method)) } apiCollectionForMessage, err := apip.getApiCollection(connectionType, apiCont.collectionKey.InternalPath, apiCont.collectionKey.Addon) @@ -482,6 +482,10 @@ func (apil *TendermintRpcChainListener) Serve(ctx context.Context, cmdFlags comm go apil.logger.AddMetricForHttp(metricsData, err, fiberCtx.GetReqHeaders()) if err != nil { + if common.APINotSupportedError.Is(err) { + return fiberCtx.Status(fiber.StatusOK).JSON(common.JsonRpcMethodNotFoundError) + } + // Get unique GUID response errMasking := apil.logger.GetUniqueGuidResponseForError(err, msgSeed) diff --git a/protocol/common/errors.go b/protocol/common/errors.go index acc863d301..8c7b16d9cb 100644 --- a/protocol/common/errors.go +++ b/protocol/common/errors.go @@ -7,4 +7,5 @@ var ( StatusCodeError504 = sdkerrors.New("Disallowed StatusCode Error", 504, "Disallowed status code error") StatusCodeError429 = sdkerrors.New("Disallowed StatusCode Error", 429, "Disallowed status code error") StatusCodeErrorStrict = sdkerrors.New("Disallowed StatusCode Error", 800, "Disallowed status code error") + APINotSupportedError = sdkerrors.New("APINotSupported Error", 900, "api is not supported") ) diff --git a/protocol/common/return_errors.go b/protocol/common/return_errors.go new file mode 100644 index 0000000000..4cee075461 --- /dev/null +++ b/protocol/common/return_errors.go @@ -0,0 +1,57 @@ +package common + +// ####### +// JsonRPC +// ####### + +type JsonRPCError struct { + Code int `json:"code"` + Message string `json:"message"` +} + +type JsonRPCErrorMessage struct { + JsonRPC string `json:"jsonrpc"` + Id int `json:"id"` + Error JsonRPCError `json:"error"` +} + +var JsonRpcMethodNotFoundError = JsonRPCErrorMessage{ + JsonRPC: "2.0", + Id: 1, + Error: JsonRPCError{ + Code: -32601, + Message: "Method not found", + }, +} + +// ####### +// Rest +// ####### + +type RestError struct { + Code int `json:"code"` + Message string `json:"message"` + Details []interface{} `json:"details"` +} + +var RestMethodNotFoundError = RestError{ + Code: 12, + Message: "Not Implemented", + Details: []interface{}{}, +} + +// ####### +// Rest - Aptos +// ####### + +type RestAptosError struct { + Message string `json:"message"` + ErrorCode string `json:"error_code"` + VmErrorCode interface{} `json:"vm_error_code"` +} + +var RestAptosMethodNotFoundError = RestAptosError{ + Message: "not found", + ErrorCode: "web_framework_error", + VmErrorCode: nil, +} From 7fa7be2ae1875c58920f9f4445fe8e207b3c720e Mon Sep 17 00:00:00 2001 From: Elad Gildnur Date: Thu, 21 Mar 2024 18:15:19 +0200 Subject: [PATCH 2/5] CR Fix: Remove one log --- protocol/chainlib/base_chain_parser.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/protocol/chainlib/base_chain_parser.go b/protocol/chainlib/base_chain_parser.go index 88ed961d4e..301f210ffc 100644 --- a/protocol/chainlib/base_chain_parser.go +++ b/protocol/chainlib/base_chain_parser.go @@ -300,10 +300,7 @@ func (apip *BaseChainParser) getSupportedApi(name, connectionType string) (*ApiC // Return an error if spec does not exist if !ok { - return nil, utils.LavaFormatWarning("api not supported", common.APINotSupportedError, - utils.LogAttr("name", name), - utils.LogAttr("connectionType", connectionType), - ) + return nil, common.APINotSupportedError } // Return an error if api is disabled From d5ef86874e851f8909cd0f7adb478db565b50b54 Mon Sep 17 00:00:00 2001 From: Elad Gildnur Date: Thu, 21 Mar 2024 18:15:33 +0200 Subject: [PATCH 3/5] Export logic to common --- protocol/chainlib/rest.go | 9 +-------- protocol/common/return_errors.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/protocol/chainlib/rest.go b/protocol/chainlib/rest.go index 04c43f670b..0d218b7eb8 100644 --- a/protocol/chainlib/rest.go +++ b/protocol/chainlib/rest.go @@ -383,14 +383,7 @@ func (apil *RestChainListener) Serve(ctx context.Context, cmdFlags common.Consum go apil.logger.AddMetricForHttp(analytics, err, fiberCtx.GetReqHeaders()) if err != nil { if common.APINotSupportedError.Is(err) { - switch chainID { - case "APT1": - // Aptos node returns a different error body than the rest of the chains - // This solution is temporary until we change the spec to state how the error looks like - return fiberCtx.Status(fiber.StatusNotImplemented).JSON(common.RestAptosMethodNotFoundError) - default: - return fiberCtx.Status(fiber.StatusNotImplemented).JSON(common.RestMethodNotFoundError) - } + return common.CreateRestMethodNotFoundError(fiberCtx, chainID) } // Get unique GUID response diff --git a/protocol/common/return_errors.go b/protocol/common/return_errors.go index 4cee075461..f0c124ad73 100644 --- a/protocol/common/return_errors.go +++ b/protocol/common/return_errors.go @@ -1,5 +1,7 @@ package common +import "github.com/gofiber/fiber/v2" + // ####### // JsonRPC // ####### @@ -55,3 +57,14 @@ var RestAptosMethodNotFoundError = RestAptosError{ ErrorCode: "web_framework_error", VmErrorCode: nil, } + +func CreateRestMethodNotFoundError(fiberCtx *fiber.Ctx, chainId string) error { + switch chainId { + case "APT1": + // Aptos node returns a different error body than the rest of the chains + // This solution is temporary until we change the spec to state how the error looks like + return fiberCtx.Status(fiber.StatusNotImplemented).JSON(RestAptosMethodNotFoundError) + default: + return fiberCtx.Status(fiber.StatusNotImplemented).JSON(RestMethodNotFoundError) + } +} From 02f9d7e58bd1cb4db7e3ff3aa2719eb836000cbd Mon Sep 17 00:00:00 2001 From: Elad Gildnur Date: Mon, 25 Mar 2024 10:58:31 +0200 Subject: [PATCH 4/5] FIx test --- protocol/chainlib/rest_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/protocol/chainlib/rest_test.go b/protocol/chainlib/rest_test.go index 5baf9b4a31..1388e6a39e 100644 --- a/protocol/chainlib/rest_test.go +++ b/protocol/chainlib/rest_test.go @@ -11,6 +11,7 @@ import ( "github.com/lavanet/lava/protocol/chainlib/chainproxy" "github.com/lavanet/lava/protocol/chainlib/chainproxy/rpcInterfaceMessages" "github.com/lavanet/lava/protocol/chainlib/extensionslib" + "github.com/lavanet/lava/protocol/common" "github.com/lavanet/lava/protocol/parser" pairingtypes "github.com/lavanet/lava/x/pairing/types" spectypes "github.com/lavanet/lava/x/spec/types" @@ -89,7 +90,8 @@ func TestRestGetSupportedApi(t *testing.T) { } _, err = apip.getSupportedApi("API2", connectionType_test) assert.Error(t, err) - assert.Equal(t, "rest api not supported API2", err.Error()) + assert.ErrorIs(t, err, common.APINotSupportedError) + assert.Equal(t, "rest api not supported ErrMsg: api is not supported {name:API2,connectionType:test}: api is not supported", err.Error()) // Test case 3: Returns error if the API is disabled apip = &RestChainParser{ From f720e3014a3b23b3f0c48c72829189d78c196741 Mon Sep 17 00:00:00 2001 From: Elad Gildnur Date: Mon, 25 Mar 2024 11:13:53 +0200 Subject: [PATCH 5/5] Fix more test --- protocol/chainlib/rest_test.go | 2 +- protocol/common/errors.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/chainlib/rest_test.go b/protocol/chainlib/rest_test.go index 1ea894e614..73bac82797 100644 --- a/protocol/chainlib/rest_test.go +++ b/protocol/chainlib/rest_test.go @@ -91,7 +91,7 @@ func TestRestGetSupportedApi(t *testing.T) { _, err = apip.getSupportedApi("API2", connectionType_test) assert.Error(t, err) assert.ErrorIs(t, err, common.APINotSupportedError) - assert.Equal(t, "rest api not supported ErrMsg: api is not supported {name:API2,connectionType:test}: api is not supported", err.Error()) + assert.Equal(t, "rest api not supported ErrMsg: api not supported {name:API2,connectionType:test}: api not supported", err.Error()) // Test case 3: Returns error if the API is disabled apip = &RestChainParser{ diff --git a/protocol/common/errors.go b/protocol/common/errors.go index 8c7b16d9cb..77a88cb6bd 100644 --- a/protocol/common/errors.go +++ b/protocol/common/errors.go @@ -7,5 +7,5 @@ var ( StatusCodeError504 = sdkerrors.New("Disallowed StatusCode Error", 504, "Disallowed status code error") StatusCodeError429 = sdkerrors.New("Disallowed StatusCode Error", 429, "Disallowed status code error") StatusCodeErrorStrict = sdkerrors.New("Disallowed StatusCode Error", 800, "Disallowed status code error") - APINotSupportedError = sdkerrors.New("APINotSupported Error", 900, "api is not supported") + APINotSupportedError = sdkerrors.New("APINotSupported Error", 900, "api not supported") )