From a746d4edb0f1fc2ac565ee8035959d7954a77be3 Mon Sep 17 00:00:00 2001 From: Chase Ripplinger Date: Fri, 17 Sep 2021 11:21:08 -0500 Subject: [PATCH] Refactor to allow methods to return error codes --- pkg/conversion/util.go | 4 +- pkg/eth/errors.go | 90 +++++++++++++++++++ pkg/eth/eth.go | 13 +-- pkg/internal/tests_common.go | 10 +-- pkg/notifier/agent.go | 8 +- pkg/qtum/client.go | 11 +++ pkg/qtum/jsonrpc.go | 7 +- pkg/server/handler.go | 33 +++---- pkg/server/myctx.go | 6 +- pkg/server/server.go | 4 +- pkg/transformer/eth_accounts.go | 4 +- pkg/transformer/eth_blockNumber.go | 6 +- pkg/transformer/eth_call.go | 28 +++--- pkg/transformer/eth_chainId.go | 4 +- pkg/transformer/eth_estimateGas.go | 20 ++--- pkg/transformer/eth_gasPrice.go | 4 +- pkg/transformer/eth_getBalance.go | 9 +- pkg/transformer/eth_getBlockByHash.go | 18 ++-- pkg/transformer/eth_getBlockByNumber.go | 29 +++--- pkg/transformer/eth_getCode.go | 9 +- pkg/transformer/eth_getCompilers.go | 2 +- pkg/transformer/eth_getFilterChanges.go | 39 ++++---- pkg/transformer/eth_getFilterLogs.go | 11 ++- pkg/transformer/eth_getLogs.go | 23 ++--- pkg/transformer/eth_getStorageAt.go | 9 +- .../eth_getTransactionByBlockHashAndIndex.go | 20 +++-- ...eth_getTransactionByBlockNumberAndIndex.go | 19 ++-- pkg/transformer/eth_getTransactionByHash.go | 26 +++--- pkg/transformer/eth_getTransactionCount.go | 4 +- pkg/transformer/eth_getTransactionReceipt.go | 18 ++-- .../eth_getUncleByBlockHashAndIndex.go | 2 +- .../eth_getUncleCountByBlockHash.go | 2 +- .../eth_getUncleCountByBlockNumber.go | 2 +- pkg/transformer/eth_hashrate.go | 6 +- pkg/transformer/eth_mining.go | 6 +- pkg/transformer/eth_net_listening.go | 4 +- pkg/transformer/eth_net_peerCount.go | 6 +- pkg/transformer/eth_net_version.go | 6 +- pkg/transformer/eth_newBlockFilter.go | 6 +- pkg/transformer/eth_newFilter.go | 9 +- pkg/transformer/eth_personal_unlockAccount.go | 2 +- pkg/transformer/eth_protocolVersion.go | 2 +- pkg/transformer/eth_sendRawTransaction.go | 15 ++-- pkg/transformer/eth_sendTransaction.go | 45 +++++----- pkg/transformer/eth_sign.go | 11 +-- pkg/transformer/eth_signTransaction.go | 66 +++++++------- pkg/transformer/eth_subscribe.go | 12 +-- pkg/transformer/eth_uninstallFilter.go | 9 +- pkg/transformer/eth_unsubscribe.go | 14 +-- pkg/transformer/qtum_getUTXOs.go | 17 ++-- pkg/transformer/tests_common.go | 6 +- pkg/transformer/transformer.go | 10 +-- pkg/transformer/type.go | 2 +- pkg/transformer/util.go | 25 +++--- pkg/transformer/web3_clientVersion.go | 2 +- pkg/transformer/web3_sha3.go | 8 +- 56 files changed, 444 insertions(+), 339 deletions(-) create mode 100644 pkg/eth/errors.go diff --git a/pkg/conversion/util.go b/pkg/conversion/util.go index 85b53597..cef32d06 100644 --- a/pkg/conversion/util.go +++ b/pkg/conversion/util.go @@ -43,10 +43,10 @@ func ConvertLogTopicsToStringArray(topics []interface{}) []string { return requestedTopics } -func SearchLogsAndFilterExtraTopics(q *qtum.Qtum, req *qtum.SearchLogsRequest) (qtum.SearchLogsResponse, error) { +func SearchLogsAndFilterExtraTopics(q *qtum.Qtum, req *qtum.SearchLogsRequest) (qtum.SearchLogsResponse, eth.JSONRPCError) { receipts, err := q.SearchLogs(req) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } hasTopics := len(req.Topics) != 0 diff --git a/pkg/eth/errors.go b/pkg/eth/errors.go new file mode 100644 index 00000000..aab82b84 --- /dev/null +++ b/pkg/eth/errors.go @@ -0,0 +1,90 @@ +package eth + +import ( + "encoding/json" + "fmt" +) + +// unknown service +// return fmt.Sprintf("The method %s%s%s does not exist/is not available", e.service, serviceMethodSeparator, e.method) +var MethodNotFoundErrorCode = -32601 + +// invalid request +var InvalidRequestErrorCode = -32600 +var InvalidMessageErrorCode = -32700 +var InvalidParamsErrorCode = -32602 + +// logic error +var CallbackErrorCode = -32000 + +// shutdown error +// "server is shutting down" +var ShutdownErrorCode = -32000 +var ShutdownError = NewJSONRPCError(ShutdownErrorCode, "server is shutting down", nil) + +func NewMethodNotFoundError(method string) JSONRPCError { + return NewJSONRPCError( + MethodNotFoundErrorCode, + fmt.Sprintf("The method %s does not exist/is not available", method), + nil, + ) +} + +func NewInvalidRequestError(message string) JSONRPCError { + return NewJSONRPCError(InvalidRequestErrorCode, message, nil) +} + +func NewInvalidMessageError(message string) JSONRPCError { + return NewJSONRPCError(InvalidMessageErrorCode, message, nil) +} + +func NewInvalidParamsError(message string) JSONRPCError { + return NewJSONRPCError(InvalidParamsErrorCode, message, nil) +} + +func NewCallbackError(message string) JSONRPCError { + return NewJSONRPCError(CallbackErrorCode, message, nil) +} + +type JSONRPCError interface { + Code() int + Message() string + Error() error +} + +func NewJSONRPCError(code int, message string, err error) JSONRPCError { + return &GenericJSONRPCError{ + code: code, + message: message, + err: err, + } +} + +// JSONRPCError contains the message and code for an ETH RPC error +type GenericJSONRPCError struct { + code int + message string + err error +} + +func (err *GenericJSONRPCError) Code() int { + return err.code +} + +func (err *GenericJSONRPCError) Message() string { + return err.message +} + +func (err *GenericJSONRPCError) Error() error { + return err.err +} + +func (err *GenericJSONRPCError) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Code int `json:"code"` + Message string `json:"message"` + }{ + Code: err.code, + Message: err.message, + }) +} diff --git a/pkg/eth/eth.go b/pkg/eth/eth.go index 28f659f9..93163cf6 100644 --- a/pkg/eth/eth.go +++ b/pkg/eth/eth.go @@ -2,7 +2,6 @@ package eth import ( "encoding/json" - "fmt" ) var EmptyLogsBloom = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" @@ -22,20 +21,10 @@ type JSONRPCRequest struct { type JSONRPCResult struct { JSONRPC string `json:"jsonrpc"` RawResult json.RawMessage `json:"result,omitempty"` - Error *JSONRPCError `json:"error,omitempty"` + Error JSONRPCError `json:"error,omitempty"` ID json.RawMessage `json:"id"` } -// JSONRPCError contains the message and code for an ETH RPC error -type JSONRPCError struct { - Code int `json:"code"` - Message string `json:"message"` -} - -func (err *JSONRPCError) Error() string { - return fmt.Sprintf("eth [code: %d] %s", err.Code, err.Message) -} - func NewJSONRPCResult(id json.RawMessage, res interface{}) (*JSONRPCResult, error) { rawResult, err := json.Marshal(res) if err != nil { diff --git a/pkg/internal/tests_common.go b/pkg/internal/tests_common.go index 8b0cb076..bdd00ff2 100644 --- a/pkg/internal/tests_common.go +++ b/pkg/internal/tests_common.go @@ -27,8 +27,8 @@ type Doer interface { AddRawResponse(requestType string, rawResponse []byte) AddResponse(requestType string, responseResult interface{}) error AddResponseWithRequestID(requestID int, requestType string, responseResult interface{}) error - AddError(requestType string, responseError *eth.JSONRPCError) error - AddErrorWithRequestID(requestID int, requestType string, responseError *eth.JSONRPCError) error + AddError(requestType string, responseError eth.JSONRPCError) error + AddErrorWithRequestID(requestID int, requestType string, responseError eth.JSONRPCError) error } func NewDoerMappedMock() *doerMappedMock { @@ -90,7 +90,7 @@ func PrepareEthRPCRequest(id int, params []json.RawMessage) (*eth.JSONRPCRequest return &requestRPC, nil } -func prepareRawResponse(requestID int, responseResult interface{}, responseError *eth.JSONRPCError) ([]byte, error) { +func prepareRawResponse(requestID int, responseResult interface{}, responseError eth.JSONRPCError) ([]byte, error) { requestIDRaw, err := json.Marshal(requestID) if err != nil { return nil, err @@ -176,7 +176,7 @@ func (d *doerMappedMock) AddResponseWithRequestID(requestID int, requestType str return nil } -func (d *doerMappedMock) AddError(requestType string, responseError *eth.JSONRPCError) error { +func (d *doerMappedMock) AddError(requestType string, responseError eth.JSONRPCError) error { d.mutex.Lock() defer d.mutex.Unlock() requestID := d.latestId + 1 @@ -190,7 +190,7 @@ func (d *doerMappedMock) AddError(requestType string, responseError *eth.JSONRPC return nil } -func (d *doerMappedMock) AddErrorWithRequestID(requestID int, requestType string, responseError *eth.JSONRPCError) error { +func (d *doerMappedMock) AddErrorWithRequestID(requestID int, requestType string, responseError eth.JSONRPCError) error { d.mutex.Lock() defer d.mutex.Unlock() responseRaw, err := prepareRawResponse(requestID, nil, responseError) diff --git a/pkg/notifier/agent.go b/pkg/notifier/agent.go index 2dc25ee8..36b1def8 100644 --- a/pkg/notifier/agent.go +++ b/pkg/notifier/agent.go @@ -20,7 +20,7 @@ var agentConfigNewHeadsInterval = 10 * time.Second // Allows dependency injection of eth rpc calls as the transformer package imports this package type Transformer interface { - Transform(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) + Transform(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) } func NewAgent(ctx context.Context, qtum *qtum.Qtum, transformer Transformer) *Agent { @@ -348,13 +348,13 @@ func (a *Agent) run() { if err != nil { panic(fmt.Sprintf("Failed to serialize eth_getBlockByHash request parameters: %s", err)) } - result, err := transformer.Transform(ð.JSONRPCRequest{ + result, jsonErr := transformer.Transform(ð.JSONRPCRequest{ JSONRPC: "2.0", Method: "eth_getBlockByHash", Params: params, }, nil) - if err != nil { - a.qtum.GetErrorLogger().Log("msg", "Failed to eth_getBlockByHash", "hash", blockchainInfo.Bestblockhash, "err", err) + if jsonErr != nil { + a.qtum.GetErrorLogger().Log("msg", "Failed to eth_getBlockByHash", "hash", blockchainInfo.Bestblockhash, "err", jsonErr) } else { getBlockByHashResponse, ok := result.(*eth.GetBlockByHashResponse) if !ok { diff --git a/pkg/qtum/client.go b/pkg/qtum/client.go index 1fe09254..6e1c0500 100644 --- a/pkg/qtum/client.go +++ b/pkg/qtum/client.go @@ -31,6 +31,7 @@ var maximumBackoff = (2 * time.Second).Milliseconds() type Client struct { URL string + url *url.URL doer doer // hex addresses to return for eth_accounts @@ -66,10 +67,16 @@ func NewClient(isMain bool, rpcURL string, opts ...func(*Client) error) (*Client return nil, err } + url, err := url.Parse(rpcURL) + if err != nil { + return nil, errors.Wrap(err, "Failed to parse rpc url") + } + c := &Client{ isMain: isMain, doer: http.DefaultClient, URL: rpcURL, + url: url, logger: log.NewNopLogger(), debug: false, id: big.NewInt(0), @@ -87,6 +94,10 @@ func NewClient(isMain bool, rpcURL string, opts ...func(*Client) error) (*Client return c, nil } +func (c *Client) GetURL() *url.URL { + return c.url +} + func (c *Client) IsMain() bool { return c.isMain } diff --git a/pkg/qtum/jsonrpc.go b/pkg/qtum/jsonrpc.go index aee8e9e4..96b96fb4 100644 --- a/pkg/qtum/jsonrpc.go +++ b/pkg/qtum/jsonrpc.go @@ -99,16 +99,13 @@ func GetErrorCode(err error) int { return errorCode } -func GetErrorResponse(err error) *eth.JSONRPCError { +func GetErrorResponse(err error) eth.JSONRPCError { errorCode := GetErrorCode(err) if errorCode == 0 { return nil } - return ð.JSONRPCError{ - Code: errorCode, - Message: err.Error(), - } + return eth.NewJSONRPCError(errorCode, err.Error(), nil) } var ( diff --git a/pkg/server/handler.go b/pkg/server/handler.go index a1c97203..22a26f1c 100644 --- a/pkg/server/handler.go +++ b/pkg/server/handler.go @@ -39,20 +39,16 @@ func httpHandler(c echo.Context) error { // level.Debug(cc.logger).Log("msg", "after call transformer#Transform") if err != nil { - err1 := errors.Cause(err) - if err != err1 { + if err.Error() == nil { cc.GetErrorLogger().Log("err", err.Error()) - return cc.JSONRPCError(ð.JSONRPCError{ - Code: 100, - Message: err1.Error(), - }) + return cc.JSONRPCError(err) } - return err + return err.Error() } // Allow transformer to return an explicit JSON error - if jerr, isJSONErr := result.(*eth.JSONRPCError); isJSONErr { + if jerr, isJSONErr := result.(eth.JSONRPCError); isJSONErr { return cc.JSONRPCError(jerr) } @@ -280,23 +276,19 @@ func websocketHandler(c echo.Context) error { cc.rpcReq = &rpcReq - result, err := cc.transformer.Transform(&rpcReq, c) + result, jsonError := cc.transformer.Transform(&rpcReq, c) response := result - if err != nil { - err1 := errors.Cause(err) - if err != err1 { - cc.GetErrorLogger().Log("err", err.Error()) - response = cc.GetJSONRPCError(ð.JSONRPCError{ - Code: 100, - Message: err1.Error(), - }) + if jsonError != nil { + if jsonError.Error() == nil { + cc.GetErrorLogger().Log("err", jsonError.Error()) + response = jsonError } } // Allow transformer to return an explicit JSON error - if jerr, isJSONErr := response.(*eth.JSONRPCError); isJSONErr { + if jerr, isJSONErr := response.(eth.JSONRPCError); isJSONErr { response = cc.GetJSONRPCError(jerr) } else { response, err = cc.GetJSONRPCResult(response) @@ -340,10 +332,7 @@ func errorHandler(err error, c echo.Context) { cc, ok := myctx.(*myCtx) if ok { cc.GetErrorLogger().Log("err", err.Error()) - if err := cc.JSONRPCError(ð.JSONRPCError{ - Code: 100, - Message: err.Error(), - }); err != nil { + if err := cc.JSONRPCError(eth.NewJSONRPCError(100, err.Error(), nil)); err != nil { cc.GetErrorLogger().Log("msg", "reply to client", "err", err.Error()) } return diff --git a/pkg/server/myctx.go b/pkg/server/myctx.go index 52fed762..d9a8f52f 100644 --- a/pkg/server/myctx.go +++ b/pkg/server/myctx.go @@ -33,7 +33,7 @@ func (c *myCtx) JSONRPCResult(result interface{}) error { return c.JSON(http.StatusOK, response) } -func (c *myCtx) GetJSONRPCError(err *eth.JSONRPCError) *eth.JSONRPCResult { +func (c *myCtx) GetJSONRPCError(err eth.JSONRPCError) *eth.JSONRPCResult { var id json.RawMessage if c.rpcReq != nil && c.rpcReq.ID != nil { id = c.rpcReq.ID @@ -45,11 +45,11 @@ func (c *myCtx) GetJSONRPCError(err *eth.JSONRPCError) *eth.JSONRPCResult { } } -func (c *myCtx) JSONRPCError(err *eth.JSONRPCError) error { +func (c *myCtx) JSONRPCError(err eth.JSONRPCError) error { resp := c.GetJSONRPCError(err) if !c.Response().Committed { - err := c.JSON(http.StatusInternalServerError, resp) + err := c.JSON(http.StatusOK, resp) c.logger.Log("Internal server error", err) return err } diff --git a/pkg/server/server.go b/pkg/server/server.go index 555957c7..008d5b27 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -113,7 +113,9 @@ func (s *Server) Start() error { } https := (s.httpsKey != "" && s.httpsCert != "") - level.Warn(s.logger).Log("listen", s.address, "qtum_rpc", s.qtumRPCClient.URL, "msg", "proxy started", "https", https) + // TODO: Upgrade golang to 1.15 to support s.qtumRPCClient.GetURL().Redacted() here + url := s.qtumRPCClient.URL + level.Info(s.logger).Log("listen", s.address, "qtum_rpc", url, "msg", "proxy started", "https", https) if https { level.Info(s.logger).Log("msg", "SSL enabled") diff --git a/pkg/transformer/eth_accounts.go b/pkg/transformer/eth_accounts.go index d16d5757..c8d6dac2 100644 --- a/pkg/transformer/eth_accounts.go +++ b/pkg/transformer/eth_accounts.go @@ -16,11 +16,11 @@ func (p *ProxyETHAccounts) Method() string { return "eth_accounts" } -func (p *ProxyETHAccounts) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHAccounts) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyETHAccounts) request() (eth.AccountsResponse, error) { +func (p *ProxyETHAccounts) request() (eth.AccountsResponse, eth.JSONRPCError) { var accounts eth.AccountsResponse for _, acc := range p.Accounts { diff --git a/pkg/transformer/eth_blockNumber.go b/pkg/transformer/eth_blockNumber.go index d68a5450..8b348617 100644 --- a/pkg/transformer/eth_blockNumber.go +++ b/pkg/transformer/eth_blockNumber.go @@ -16,14 +16,14 @@ func (p *ProxyETHBlockNumber) Method() string { return "eth_blockNumber" } -func (p *ProxyETHBlockNumber) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHBlockNumber) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyETHBlockNumber) request() (*eth.BlockNumberResponse, error) { +func (p *ProxyETHBlockNumber) request() (*eth.BlockNumberResponse, eth.JSONRPCError) { qtumresp, err := p.Qtum.GetBlockCount() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res diff --git a/pkg/transformer/eth_call.go b/pkg/transformer/eth_call.go index db0c9f53..83c89469 100644 --- a/pkg/transformer/eth_call.go +++ b/pkg/transformer/eth_call.go @@ -18,20 +18,21 @@ func (p *ProxyETHCall) Method() string { return "eth_call" } -func (p *ProxyETHCall) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHCall) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.CallRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Is this correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(&req) } -func (p *ProxyETHCall) request(ethreq *eth.CallRequest) (interface{}, error) { +func (p *ProxyETHCall) request(ethreq *eth.CallRequest) (interface{}, eth.JSONRPCError) { // eth req -> qtum req - qtumreq, err := p.ToRequest(ethreq) - if err != nil { - return nil, err + qtumreq, jsonErr := p.ToRequest(ethreq) + if jsonErr != nil { + return nil, jsonErr } qtumresp, err := p.CallContract(qtumreq) @@ -41,20 +42,20 @@ func (p *ProxyETHCall) request(ethreq *eth.CallRequest) (interface{}, error) { return &qtumresp, nil } - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res return p.ToResponse(qtumresp), nil } -func (p *ProxyETHCall) ToRequest(ethreq *eth.CallRequest) (*qtum.CallContractRequest, error) { +func (p *ProxyETHCall) ToRequest(ethreq *eth.CallRequest) (*qtum.CallContractRequest, eth.JSONRPCError) { from := ethreq.From var err error if utils.IsEthHexAddress(from) { from, err = p.FromHexAddress(from) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } } @@ -73,10 +74,11 @@ func (p *ProxyETHCall) ToRequest(ethreq *eth.CallRequest) (*qtum.CallContractReq func (p *ProxyETHCall) ToResponse(qresp *qtum.CallContractResponse) interface{} { if qresp.ExecutionResult.Output == "" { - return ð.JSONRPCError{ - Message: "Revert: executionResult output is empty", - Code: -32000, - } + return eth.NewJSONRPCError( + -32000, + "Revert: executionResult output is empty", + nil, + ) } data := utils.AddHexPrefix(qresp.ExecutionResult.Output) diff --git a/pkg/transformer/eth_chainId.go b/pkg/transformer/eth_chainId.go index 601fc04c..38da3de9 100644 --- a/pkg/transformer/eth_chainId.go +++ b/pkg/transformer/eth_chainId.go @@ -18,10 +18,10 @@ func (p *ProxyETHChainId) Method() string { return "eth_chainId" } -func (p *ProxyETHChainId) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHChainId) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var qtumresp *qtum.GetBlockChainInfoResponse if err := p.Qtum.Request(qtum.MethodGetBlockChainInfo, nil, &qtumresp); err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } var chainId *big.Int diff --git a/pkg/transformer/eth_estimateGas.go b/pkg/transformer/eth_estimateGas.go index 4029f44f..74af0b5d 100644 --- a/pkg/transformer/eth_estimateGas.go +++ b/pkg/transformer/eth_estimateGas.go @@ -21,10 +21,11 @@ func (p *ProxyETHEstimateGas) Method() string { return "eth_estimateGas" } -func (p *ProxyETHEstimateGas) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHEstimateGas) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var ethreq eth.CallRequest - if err := unmarshalRequest(rawreq.Params, ðreq); err != nil { - return nil, err + if jsonErr := unmarshalRequest(rawreq.Params, ðreq); jsonErr != nil { + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(jsonErr.Error()) } if ethreq.Data == "" { @@ -42,24 +43,23 @@ func (p *ProxyETHEstimateGas) Request(rawreq *eth.JSONRPCRequest, c echo.Context ethreq.Gas = nil // eth req -> qtum req - qtumreq, err := p.ToRequest(ðreq) - if err != nil { - return nil, err + qtumreq, jsonErr := p.ToRequest(ðreq) + if jsonErr != nil { + return nil, jsonErr } // qtum [code: -5] Incorrect address occurs here qtumresp, err := p.CallContract(qtumreq) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } return p.toResp(qtumresp) } -func (p *ProxyETHEstimateGas) toResp(qtumresp *qtum.CallContractResponse) (*eth.EstimateGasResponse, error) { +func (p *ProxyETHEstimateGas) toResp(qtumresp *qtum.CallContractResponse) (*eth.EstimateGasResponse, eth.JSONRPCError) { if qtumresp.ExecutionResult.Excepted != "None" { - // TODO: Return code -32000 - return nil, ErrExecutionReverted + return nil, eth.NewCallbackError(ErrExecutionReverted.Error()) } gas := eth.EstimateGasResponse(hexutil.EncodeUint64(uint64(qtumresp.ExecutionResult.GasUsed))) p.GetDebugLogger().Log(p.Method(), gas) diff --git a/pkg/transformer/eth_gasPrice.go b/pkg/transformer/eth_gasPrice.go index 57a476f2..1efe1a7e 100644 --- a/pkg/transformer/eth_gasPrice.go +++ b/pkg/transformer/eth_gasPrice.go @@ -18,10 +18,10 @@ func (p *ProxyETHGasPrice) Method() string { return "eth_gasPrice" } -func (p *ProxyETHGasPrice) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGasPrice) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { qtumresp, err := p.Qtum.GetGasPrice() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res diff --git a/pkg/transformer/eth_getBalance.go b/pkg/transformer/eth_getBalance.go index b2215313..5d3c1e34 100644 --- a/pkg/transformer/eth_getBalance.go +++ b/pkg/transformer/eth_getBalance.go @@ -19,10 +19,11 @@ func (p *ProxyETHGetBalance) Method() string { return "eth_getBalance" } -func (p *ProxyETHGetBalance) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetBalance) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetBalanceRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } addr := utils.RemoveHexPrefix(req.Address) @@ -44,7 +45,7 @@ func (p *ProxyETHGetBalance) Request(rawreq *eth.JSONRPCRequest, c echo.Context) base58Addr, err := p.FromHexAddress(addr) if err != nil { p.GetDebugLogger().Log("method", p.Method(), "address", req.Address, "msg", "error parsing address", "error", err) - return nil, err + return nil, eth.NewCallbackError(err.Error()) } qtumreq := qtum.GetAddressBalanceRequest{Address: base58Addr} @@ -55,7 +56,7 @@ func (p *ProxyETHGetBalance) Request(rawreq *eth.JSONRPCRequest, c echo.Context) return "0x0", nil } p.GetDebugLogger().Log("method", p.Method(), "address", req.Address, "msg", "error getting address balance", "error", err) - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // 1 QTUM = 10 ^ 8 Satoshi diff --git a/pkg/transformer/eth_getBlockByHash.go b/pkg/transformer/eth_getBlockByHash.go index 13712f48..bec5a76e 100644 --- a/pkg/transformer/eth_getBlockByHash.go +++ b/pkg/transformer/eth_getBlockByHash.go @@ -5,7 +5,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" "github.com/qtumproject/janus/pkg/utils" @@ -20,17 +19,18 @@ func (p *ProxyETHGetBlockByHash) Method() string { return "eth_getBlockByHash" } -func (p *ProxyETHGetBlockByHash) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetBlockByHash) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { req := new(eth.GetBlockByHashRequest) if err := unmarshalRequest(rawreq.Params, req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } req.BlockHash = utils.RemoveHexPrefix(req.BlockHash) return p.request(req) } -func (p *ProxyETHGetBlockByHash) request(req *eth.GetBlockByHashRequest) (*eth.GetBlockByHashResponse, error) { +func (p *ProxyETHGetBlockByHash) request(req *eth.GetBlockByHashRequest) (*eth.GetBlockByHashResponse, eth.JSONRPCError) { blockHeader, err := p.GetBlockHeader(req.BlockHash) if err != nil { if err == qtum.ErrInvalidAddress { @@ -39,11 +39,12 @@ func (p *ProxyETHGetBlockByHash) request(req *eth.GetBlockByHashRequest) (*eth.G return nil, nil } p.GetDebugLogger().Log("msg", "couldn't get block header", "blockHash", req.BlockHash) - return nil, errors.WithMessage(err, "couldn't get block header") + return nil, eth.NewCallbackError("couldn't get block header") } block, err := p.GetBlock(req.BlockHash) if err != nil { - return nil, errors.WithMessage(err, "couldn't get block") + p.GetDebugLogger().Log("msg", "couldn't get block", "blockHash", req.BlockHash) + return nil, eth.NewCallbackError("couldn't get block") } nonce := hexutil.EncodeUint64(uint64(block.Nonce)) // left pad nonce with 0 to length 16, eg: 0x0000000000000042 @@ -121,7 +122,8 @@ func (p *ProxyETHGetBlockByHash) request(req *eth.GetBlockByHashRequest) (*eth.G for _, txHash := range block.Txs { tx, err := getTransactionByHash(p.Qtum, txHash) if err != nil { - return nil, errors.WithMessage(err, "couldn't get transaction by hash") + p.GetDebugLogger().Log("msg", "Couldn't get transaction by hash", "hash", txHash) + return nil, eth.NewCallbackError("couldn't get transaction by hash") } if tx == nil { if block.Height == 0 { @@ -131,7 +133,7 @@ func (p *ProxyETHGetBlockByHash) request(req *eth.GetBlockByHashRequest) (*eth.G } else { p.GetDebugLogger().Log("msg", "Failed to get transaction by hash included in a block", "hash", txHash) if !p.GetFlagBool(qtum.FLAG_IGNORE_UNKNOWN_TX) { - return nil, errors.WithMessage(err, "couldn't get transaction by hash included in a block") + return nil, eth.NewCallbackError("couldn't get transaction by hash included in a block") } } } else { diff --git a/pkg/transformer/eth_getBlockByNumber.go b/pkg/transformer/eth_getBlockByNumber.go index aa46c097..315ee69f 100644 --- a/pkg/transformer/eth_getBlockByNumber.go +++ b/pkg/transformer/eth_getBlockByNumber.go @@ -4,7 +4,6 @@ import ( "math/big" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" ) @@ -18,23 +17,24 @@ func (p *ProxyETHGetBlockByNumber) Method() string { return "eth_getBlockByNumber" } -func (p *ProxyETHGetBlockByNumber) Request(rpcReq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetBlockByNumber) Request(rpcReq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { req := new(eth.GetBlockByNumberRequest) if err := unmarshalRequest(rpcReq.Params, req); err != nil { - return nil, errors.WithMessage(err, "couldn't unmarhsal rpc request") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(req) } -func (p *ProxyETHGetBlockByNumber) request(req *eth.GetBlockByNumberRequest) (*eth.GetBlockByNumberResponse, error) { +func (p *ProxyETHGetBlockByNumber) request(req *eth.GetBlockByNumberRequest) (*eth.GetBlockByNumberResponse, eth.JSONRPCError) { blockNum, err := getBlockNumberByRawParam(p.Qtum, req.BlockNumber, false) if err != nil { - return nil, errors.WithMessage(err, "couldn't get block number by parameter") + return nil, eth.NewCallbackError("couldn't get block number by parameter") } - blockHash, err := proxyETHGetBlockByHash(p, p.Qtum, blockNum) - if err != nil { - return nil, err + blockHash, jsonErr := proxyETHGetBlockByHash(p, p.Qtum, blockNum) + if jsonErr != nil { + return nil, jsonErr } if blockHash == nil { return nil, nil @@ -47,9 +47,10 @@ func (p *ProxyETHGetBlockByNumber) request(req *eth.GetBlockByNumberRequest) (*e } proxy = &ProxyETHGetBlockByHash{Qtum: p.Qtum} ) - block, err := proxy.request(getBlockByHashReq) - if err != nil { - return nil, errors.WithMessage(err, "couldn't get block by hash") + block, jsonErr := proxy.request(getBlockByHashReq) + if jsonErr != nil { + p.GetDebugLogger().Log("function", p.Method(), "msg", "couldn't get block by hash", "err", err) + return nil, eth.NewCallbackError("couldn't get block by hash") } if blockNum != nil { p.GetDebugLogger().Log("function", p.Method(), "request", string(req.BlockNumber), "msg", "Successfully got block by number", "result", blockNum.String()) @@ -58,7 +59,7 @@ func (p *ProxyETHGetBlockByNumber) request(req *eth.GetBlockByNumberRequest) (*e } // Properly handle unknown blocks -func proxyETHGetBlockByHash(p ETHProxy, q *qtum.Qtum, blockNum *big.Int) (*qtum.GetBlockHashResponse, error) { +func proxyETHGetBlockByHash(p ETHProxy, q *qtum.Qtum, blockNum *big.Int) (*qtum.GetBlockHashResponse, eth.JSONRPCError) { resp, err := q.GetBlockHash(blockNum) if err != nil { if err == qtum.ErrInvalidParameter { @@ -73,7 +74,7 @@ func proxyETHGetBlockByHash(p ETHProxy, q *qtum.Qtum, blockNum *big.Int) (*qtum. q.GetDebugLogger().Log("function", p.Method(), "request", blockNum.String(), "msg", "Unknown block") return nil, nil } - return nil, errors.WithMessage(err, "couldn't get block hash") + return nil, eth.NewCallbackError("couldn't get block hash") } - return &resp, err + return &resp, nil } diff --git a/pkg/transformer/eth_getCode.go b/pkg/transformer/eth_getCode.go index 653f7b01..68baa3f8 100644 --- a/pkg/transformer/eth_getCode.go +++ b/pkg/transformer/eth_getCode.go @@ -16,16 +16,17 @@ func (p *ProxyETHGetCode) Method() string { return "eth_getCode" } -func (p *ProxyETHGetCode) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetCode) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetCodeRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(&req) } -func (p *ProxyETHGetCode) request(ethreq *eth.GetCodeRequest) (eth.GetCodeResponse, error) { +func (p *ProxyETHGetCode) request(ethreq *eth.GetCodeRequest) (eth.GetCodeResponse, eth.JSONRPCError) { qtumreq := qtum.GetAccountInfoRequest(utils.RemoveHexPrefix(ethreq.Address)) qtumresp, err := p.GetAccountInfo(&qtumreq) @@ -41,7 +42,7 @@ func (p *ProxyETHGetCode) request(ethreq *eth.GetCodeRequest) (eth.GetCodeRespon **/ return "0x", nil } else { - return "", err + return "", eth.NewCallbackError(err.Error()) } } diff --git a/pkg/transformer/eth_getCompilers.go b/pkg/transformer/eth_getCompilers.go index 7578eff9..3ad73e9d 100644 --- a/pkg/transformer/eth_getCompilers.go +++ b/pkg/transformer/eth_getCompilers.go @@ -12,7 +12,7 @@ func (p *ETHGetCompilers) Method() string { return "eth_getCompilers" } -func (p *ETHGetCompilers) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHGetCompilers) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { // hardcoded to empty return []string{}, nil } diff --git a/pkg/transformer/eth_getFilterChanges.go b/pkg/transformer/eth_getFilterChanges.go index 0de669be..248c628d 100644 --- a/pkg/transformer/eth_getFilterChanges.go +++ b/pkg/transformer/eth_getFilterChanges.go @@ -5,7 +5,6 @@ import ( "math/big" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/conversion" "github.com/qtumproject/janus/pkg/eth" @@ -23,7 +22,7 @@ func (p *ProxyETHGetFilterChanges) Method() string { return "eth_getFilterChanges" } -func (p *ProxyETHGetFilterChanges) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetFilterChanges) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { filter, err := processFilter(p, rawreq) if err != nil { @@ -38,23 +37,22 @@ func (p *ProxyETHGetFilterChanges) Request(rawreq *eth.JSONRPCRequest, c echo.Co case eth.NewPendingTransactionFilterTy: fallthrough default: - - return nil, errors.New("Unknown filter type") + return nil, eth.NewInvalidParamsError("Unknown filter type") } } -func (p *ProxyETHGetFilterChanges) requestBlockFilter(filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err error) { +func (p *ProxyETHGetFilterChanges) requestBlockFilter(filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err eth.JSONRPCError) { qtumresp = make(eth.GetFilterChangesResponse, 0) _lastBlockNumber, ok := filter.Data.Load("lastBlockNumber") if !ok { - return qtumresp, errors.New("Could not get lastBlockNumber") + return qtumresp, eth.NewCallbackError("Could not get lastBlockNumber") } lastBlockNumber := _lastBlockNumber.(uint64) - blockCountBigInt, err := p.GetBlockCount() - if err != nil { - return qtumresp, err + blockCountBigInt, blockErr := p.GetBlockCount() + if blockErr != nil { + return qtumresp, eth.NewCallbackError(blockErr.Error()) } blockCount := blockCountBigInt.Uint64() @@ -66,7 +64,7 @@ func (p *ProxyETHGetFilterChanges) requestBlockFilter(filter *eth.Filter) (qtumr resp, err := p.GetBlockHash(blockNumber) if err != nil { - return qtumresp, err + return qtumresp, eth.NewCallbackError(err.Error()) } hashes[i] = utils.AddHexPrefix(string(resp)) @@ -76,18 +74,19 @@ func (p *ProxyETHGetFilterChanges) requestBlockFilter(filter *eth.Filter) (qtumr filter.Data.Store("lastBlockNumber", blockCount) return } -func (p *ProxyETHGetFilterChanges) requestFilter(filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err error) { + +func (p *ProxyETHGetFilterChanges) requestFilter(filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err eth.JSONRPCError) { qtumresp = make(eth.GetFilterChangesResponse, 0) _lastBlockNumber, ok := filter.Data.Load("lastBlockNumber") if !ok { - return qtumresp, errors.New("Could not get lastBlockNumber") + return qtumresp, eth.NewCallbackError("Could not get lastBlockNumber") } lastBlockNumber := _lastBlockNumber.(uint64) - blockCountBigInt, err := p.GetBlockCount() - if err != nil { - return qtumresp, err + blockCountBigInt, blockErr := p.GetBlockCount() + if blockErr != nil { + return qtumresp, eth.NewCallbackError(blockErr.Error()) } blockCount := blockCountBigInt.Uint64() @@ -105,7 +104,7 @@ func (p *ProxyETHGetFilterChanges) requestFilter(filter *eth.Filter) (qtumresp e return p.doSearchLogs(searchLogsReq) } -func (p *ProxyETHGetFilterChanges) doSearchLogs(req *qtum.SearchLogsRequest) (eth.GetFilterChangesResponse, error) { +func (p *ProxyETHGetFilterChanges) doSearchLogs(req *qtum.SearchLogsRequest) (eth.GetFilterChangesResponse, eth.JSONRPCError) { resp, err := conversion.SearchLogsAndFilterExtraTopics(p.Qtum, req) if err != nil { return nil, err @@ -128,7 +127,7 @@ func (p *ProxyETHGetFilterChanges) doSearchLogs(req *qtum.SearchLogsRequest) (et return results, nil } -func (p *ProxyETHGetFilterChanges) toSearchLogsReq(filter *eth.Filter, from, to *big.Int) (*qtum.SearchLogsRequest, error) { +func (p *ProxyETHGetFilterChanges) toSearchLogsReq(filter *eth.Filter, from, to *big.Int) (*qtum.SearchLogsRequest, eth.JSONRPCError) { ethreq := filter.Request.(*eth.NewFilterRequest) var err error var addresses []string @@ -136,12 +135,14 @@ func (p *ProxyETHGetFilterChanges) toSearchLogsReq(filter *eth.Filter, from, to if isBytesOfString(ethreq.Address) { var addr string if err = json.Unmarshal(ethreq.Address, &addr); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } addresses = append(addresses, addr) } else { if err = json.Unmarshal(ethreq.Address, &addresses); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } } for i := range addresses { diff --git a/pkg/transformer/eth_getFilterLogs.go b/pkg/transformer/eth_getFilterLogs.go index 32d902f9..209c6fb5 100644 --- a/pkg/transformer/eth_getFilterLogs.go +++ b/pkg/transformer/eth_getFilterLogs.go @@ -4,7 +4,6 @@ import ( "math/big" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" ) @@ -17,7 +16,7 @@ func (p *ProxyETHGetFilterLogs) Method() string { return "eth_getFilterLogs" } -func (p *ProxyETHGetFilterLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetFilterLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { filter, err := processFilter(p.ProxyETHGetFilterChanges, rawreq) if err != nil { @@ -28,22 +27,22 @@ func (p *ProxyETHGetFilterLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Conte case eth.NewFilterTy: return p.request(filter) default: - return nil, errors.New("filter not found") + return nil, eth.NewInvalidParamsError("filter not found") } } -func (p *ProxyETHGetFilterLogs) request(filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err error) { +func (p *ProxyETHGetFilterLogs) request(filter *eth.Filter) (qtumresp eth.GetFilterChangesResponse, err eth.JSONRPCError) { qtumresp = make(eth.GetFilterChangesResponse, 0) _lastBlockNumber, ok := filter.Data.Load("lastBlockNumber") if !ok { - return qtumresp, errors.New("Could not get lastBlockNumber") + return qtumresp, eth.NewCallbackError("Could not get lastBlockNumber") } lastBlockNumber := _lastBlockNumber.(uint64) _toBlock, ok := filter.Data.Load("toBlock") if !ok { - return qtumresp, errors.New("Could not get toBlock") + return qtumresp, eth.NewCallbackError("Could not get toBlock") } toBlock := _toBlock.(uint64) diff --git a/pkg/transformer/eth_getLogs.go b/pkg/transformer/eth_getLogs.go index 999deda1..5c9c21a9 100644 --- a/pkg/transformer/eth_getLogs.go +++ b/pkg/transformer/eth_getLogs.go @@ -19,10 +19,11 @@ func (p *ProxyETHGetLogs) Method() string { return "eth_getLogs" } -func (p *ProxyETHGetLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetLogsRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } // TODO: Graph Node is sending the topic @@ -39,7 +40,7 @@ func (p *ProxyETHGetLogs) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (i return p.request(qtumreq) } -func (p *ProxyETHGetLogs) request(req *qtum.SearchLogsRequest) (*eth.GetLogsResponse, error) { +func (p *ProxyETHGetLogs) request(req *qtum.SearchLogsRequest) (*eth.GetLogsResponse, eth.JSONRPCError) { receipts, err := conversion.SearchLogsAndFilterExtraTopics(p.Qtum, req) if err != nil { return nil, err @@ -55,7 +56,7 @@ func (p *ProxyETHGetLogs) request(req *qtum.SearchLogsRequest) (*eth.GetLogsResp return &resp, nil } -func (p *ProxyETHGetLogs) ToRequest(ethreq *eth.GetLogsRequest) (*qtum.SearchLogsRequest, error) { +func (p *ProxyETHGetLogs) ToRequest(ethreq *eth.GetLogsRequest) (*qtum.SearchLogsRequest, eth.JSONRPCError) { //transform EthRequest fromBlock to QtumReq fromBlock: from, err := getBlockNumberByRawParam(p.Qtum, ethreq.FromBlock, true) if err != nil { @@ -73,13 +74,13 @@ func (p *ProxyETHGetLogs) ToRequest(ethreq *eth.GetLogsRequest) (*qtum.SearchLog if ethreq.Address != nil { if isBytesOfString(ethreq.Address) { var addr string - if err = json.Unmarshal(ethreq.Address, &addr); err != nil { - return nil, err + if jsonErr := json.Unmarshal(ethreq.Address, &addr); jsonErr != nil { + return nil, eth.NewInvalidParamsError(jsonErr.Error()) } addresses = append(addresses, addr) } else { - if err = json.Unmarshal(ethreq.Address, &addresses); err != nil { - return nil, err + if jsonErr := json.Unmarshal(ethreq.Address, &addresses); jsonErr != nil { + return nil, eth.NewInvalidParamsError(jsonErr.Error()) } } for i := range addresses { @@ -88,9 +89,9 @@ func (p *ProxyETHGetLogs) ToRequest(ethreq *eth.GetLogsRequest) (*qtum.SearchLog } //transform EthReq topics to QtumReq topics: - topics, err := eth.TranslateTopics(ethreq.Topics) - if err != nil { - return nil, err + topics, topicsErr := eth.TranslateTopics(ethreq.Topics) + if topicsErr != nil { + return nil, eth.NewCallbackError(topicsErr.Error()) } return &qtum.SearchLogsRequest{ diff --git a/pkg/transformer/eth_getStorageAt.go b/pkg/transformer/eth_getStorageAt.go index b8d18ccb..4345a71f 100644 --- a/pkg/transformer/eth_getStorageAt.go +++ b/pkg/transformer/eth_getStorageAt.go @@ -18,10 +18,11 @@ func (p *ProxyETHGetStorageAt) Method() string { return "eth_getStorageAt" } -func (p *ProxyETHGetStorageAt) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetStorageAt) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetStorageRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } qtumAddress := utils.RemoveHexPrefix(req.Address) @@ -37,10 +38,10 @@ func (p *ProxyETHGetStorageAt) Request(rawreq *eth.JSONRPCRequest, c echo.Contex }, utils.RemoveHexPrefix(req.Index)) } -func (p *ProxyETHGetStorageAt) request(ethreq *qtum.GetStorageRequest, index string) (*eth.GetStorageResponse, error) { +func (p *ProxyETHGetStorageAt) request(ethreq *qtum.GetStorageRequest, index string) (*eth.GetStorageResponse, eth.JSONRPCError) { qtumresp, err := p.Qtum.GetStorage(ethreq) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res diff --git a/pkg/transformer/eth_getTransactionByBlockHashAndIndex.go b/pkg/transformer/eth_getTransactionByBlockHashAndIndex.go index d895dccc..0bfe411c 100644 --- a/pkg/transformer/eth_getTransactionByBlockHashAndIndex.go +++ b/pkg/transformer/eth_getTransactionByBlockHashAndIndex.go @@ -5,7 +5,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" ) @@ -19,30 +18,33 @@ func (p *ProxyETHGetTransactionByBlockHashAndIndex) Method() string { return "eth_getTransactionByBlockHashAndIndex" } -func (p *ProxyETHGetTransactionByBlockHashAndIndex) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetTransactionByBlockHashAndIndex) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetTransactionByBlockHashAndIndex if err := json.Unmarshal(rawreq.Params, &req); err != nil { - return nil, errors.Wrap(err, "couldn't unmarshal request") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } if req.BlockHash == "" { - return nil, errors.New("invalid argument 0: empty hex string") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("invalid argument 0: empty hex string") } return p.request(&req) } -func (p *ProxyETHGetTransactionByBlockHashAndIndex) request(req *eth.GetTransactionByBlockHashAndIndex) (interface{}, error) { +func (p *ProxyETHGetTransactionByBlockHashAndIndex) request(req *eth.GetTransactionByBlockHashAndIndex) (interface{}, eth.JSONRPCError) { transactionIndex, err := hexutil.DecodeUint64(req.TransactionIndex) if err != nil { - return nil, errors.Wrap(err, "invalid argument 1") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("invalid argument 1") } // Proxy eth_getBlockByHash and return the transaction at requested index getBlockByNumber := ProxyETHGetBlockByHash{p.Qtum} - blockByNumber, err := getBlockByNumber.request(ð.GetBlockByHashRequest{BlockHash: req.BlockHash, FullTransaction: true}) + blockByNumber, jsonErr := getBlockByNumber.request(ð.GetBlockByHashRequest{BlockHash: req.BlockHash, FullTransaction: true}) - if err != nil { - return nil, err + if jsonErr != nil { + return nil, jsonErr } if blockByNumber == nil { diff --git a/pkg/transformer/eth_getTransactionByBlockNumberAndIndex.go b/pkg/transformer/eth_getTransactionByBlockNumberAndIndex.go index 159906c0..40445ac5 100644 --- a/pkg/transformer/eth_getTransactionByBlockNumberAndIndex.go +++ b/pkg/transformer/eth_getTransactionByBlockNumberAndIndex.go @@ -5,7 +5,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" ) @@ -19,28 +18,30 @@ func (p *ProxyETHGetTransactionByBlockNumberAndIndex) Method() string { return "eth_getTransactionByBlockNumberAndIndex" } -func (p *ProxyETHGetTransactionByBlockNumberAndIndex) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetTransactionByBlockNumberAndIndex) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetTransactionByBlockNumberAndIndex if err := json.Unmarshal(rawreq.Params, &req); err != nil { - return nil, errors.Wrap(err, "couldn't unmarshal request") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("couldn't unmarshal request") } if req.BlockNumber == "" { - return nil, errors.New("invalid argument 0: empty hex string") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("invalid argument 0: empty hex string") } return p.request(&req) } -func (p *ProxyETHGetTransactionByBlockNumberAndIndex) request(req *eth.GetTransactionByBlockNumberAndIndex) (interface{}, error) { +func (p *ProxyETHGetTransactionByBlockNumberAndIndex) request(req *eth.GetTransactionByBlockNumberAndIndex) (interface{}, eth.JSONRPCError) { // Decoded by ProxyETHGetTransactionByBlockHashAndIndex, quickly decode so we can fail cheaply without making any calls - _, err := hexutil.DecodeUint64(req.TransactionIndex) - if err != nil { - return nil, errors.Wrap(err, "invalid argument 1") + _, decodeErr := hexutil.DecodeUint64(req.TransactionIndex) + if decodeErr != nil { + return nil, eth.NewInvalidParamsError("invalid argument 1") } blockNum, err := getBlockNumberByParam(p.Qtum, req.BlockNumber, false) if err != nil { - return nil, errors.WithMessage(err, "couldn't get block number by parameter") + return nil, eth.NewCallbackError("couldn't get block number by parameter") } blockHash, err := proxyETHGetBlockByHash(p, p.Qtum, blockNum) diff --git a/pkg/transformer/eth_getTransactionByHash.go b/pkg/transformer/eth_getTransactionByHash.go index 190c6fd7..48fa58e4 100644 --- a/pkg/transformer/eth_getTransactionByHash.go +++ b/pkg/transformer/eth_getTransactionByHash.go @@ -20,13 +20,15 @@ func (p *ProxyETHGetTransactionByHash) Method() string { return "eth_getTransactionByHash" } -func (p *ProxyETHGetTransactionByHash) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetTransactionByHash) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var txHash eth.GetTransactionByHashRequest if err := json.Unmarshal(req.Params, &txHash); err != nil { - return nil, errors.Wrap(err, "couldn't unmarshal request") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("couldn't unmarshal request") } if txHash == "" { - return nil, errors.New("transaction hash is empty") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("transaction hash is empty") } qtumReq := &qtum.GetTransactionRequest{ @@ -35,7 +37,7 @@ func (p *ProxyETHGetTransactionByHash) Request(req *eth.JSONRPCRequest, c echo.C return p.request(qtumReq) } -func (p *ProxyETHGetTransactionByHash) request(req *qtum.GetTransactionRequest) (*eth.GetTransactionByHashResponse, error) { +func (p *ProxyETHGetTransactionByHash) request(req *qtum.GetTransactionRequest) (*eth.GetTransactionByHashResponse, eth.JSONRPCError) { ethTx, err := getTransactionByHash(p.Qtum, req.TxID) if err != nil { return nil, err @@ -44,11 +46,11 @@ func (p *ProxyETHGetTransactionByHash) request(req *qtum.GetTransactionRequest) } // TODO: think of returning flag if it's a reward transaction for miner -func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashResponse, error) { +func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashResponse, eth.JSONRPCError) { qtumTx, err := p.GetTransaction(hash) if err != nil { if errors.Cause(err) != qtum.ErrInvalidAddress { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } ethTx, err := getRewardTransactionByHash(p, hash) if err != nil { @@ -60,7 +62,7 @@ func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashR if errors.Cause(err) == qtum.ErrInvalidAddress { return nil, nil } - return nil, err + return nil, eth.NewCallbackError(err.Error()) } else { qtumTx = &qtum.GetTransactionResponse{ BlockHash: rawTx.BlockHash, @@ -73,7 +75,7 @@ func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashR } qtumDecodedRawTx, err := p.DecodeRawTransaction(qtumTx.Hex) if err != nil { - return nil, errors.WithMessage(err, "couldn't get raw transaction") + return nil, eth.NewCallbackError("couldn't get raw transaction") } ethTx := ð.GetTransactionByHashResponse{ @@ -90,7 +92,7 @@ func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashR if !qtumTx.IsPending() { // otherwise, the following values must be nulls blockNumber, err := getBlockNumberByHash(p, qtumTx.BlockHash) if err != nil { - return nil, errors.WithMessage(err, "couldn't get block number by hash") + return nil, eth.NewCallbackError("couldn't get block number by hash") } ethTx.BlockNumber = hexutil.EncodeUint64(blockNumber) ethTx.BlockHash = utils.AddHexPrefix(qtumTx.BlockHash) @@ -99,13 +101,14 @@ func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashR ethAmount, err := formatQtumAmount(qtumDecodedRawTx.CalcAmount()) if err != nil { - return nil, errors.WithMessage(err, "couldn't format amount") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("couldn't format amount") } ethTx.Value = ethAmount qtumTxContractInfo, isContractTx, err := qtumDecodedRawTx.ExtractContractInfo() if err != nil { - return nil, errors.WithMessage(err, "couldn't extract contract info") + return nil, eth.NewCallbackError("couldn't extract contract info") } if isContractTx { // TODO: research is this allowed? ethTx.Input = utils.AddHexPrefix(qtumTxContractInfo.UserInput) @@ -177,6 +180,7 @@ func getTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashR return ethTx, nil } +// TODO: Does this need to return eth.JSONRPCError // TODO: discuss // ? There are `witness` transactions, that is not acquireable nither via `gettransaction`, nor `getrawtransaction` func getRewardTransactionByHash(p *qtum.Qtum, hash string) (*eth.GetTransactionByHashResponse, error) { diff --git a/pkg/transformer/eth_getTransactionCount.go b/pkg/transformer/eth_getTransactionCount.go index bbf44139..b1b08738 100644 --- a/pkg/transformer/eth_getTransactionCount.go +++ b/pkg/transformer/eth_getTransactionCount.go @@ -18,7 +18,7 @@ func (p *ProxyETHTxCount) Method() string { return "eth_getTransactionCount" } -func (p *ProxyETHTxCount) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHTxCount) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { /* not sure we need this. Need to figure out how to best unmarshal this in the future. For now this will work. var req eth.GetTransactionCountRequest @@ -27,7 +27,7 @@ func (p *ProxyETHTxCount) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (i }*/ qtumresp, err := p.Qtum.GetTransactionCount("", "") if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res diff --git a/pkg/transformer/eth_getTransactionReceipt.go b/pkg/transformer/eth_getTransactionReceipt.go index 8b4fb00a..e59058e9 100644 --- a/pkg/transformer/eth_getTransactionReceipt.go +++ b/pkg/transformer/eth_getTransactionReceipt.go @@ -22,13 +22,15 @@ func (p *ProxyETHGetTransactionReceipt) Method() string { return "eth_getTransactionReceipt" } -func (p *ProxyETHGetTransactionReceipt) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHGetTransactionReceipt) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.GetTransactionReceiptRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } if req == "" { - return nil, errors.New("empty transaction hash") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("empty transaction hash") } var ( txHash = utils.RemoveHexPrefix(string(req)) @@ -37,7 +39,7 @@ func (p *ProxyETHGetTransactionReceipt) Request(rawreq *eth.JSONRPCRequest, c ec return p.request(&qtumReq) } -func (p *ProxyETHGetTransactionReceipt) request(req *qtum.GetTransactionReceiptRequest) (*eth.GetTransactionReceiptResponse, error) { +func (p *ProxyETHGetTransactionReceipt) request(req *qtum.GetTransactionReceiptRequest) (*eth.GetTransactionReceiptResponse, eth.JSONRPCError) { qtumReceipt, err := p.Qtum.GetTransactionReceipt(string(*req)) if err != nil { ethTx, getRewardTransactionErr := getRewardTransactionByHash(p.Qtum, string(*req)) @@ -47,7 +49,7 @@ func (p *ProxyETHGetTransactionReceipt) request(req *qtum.GetTransactionReceiptR return nil, nil } p.Qtum.GetDebugLogger().Log("msg", "Transaction does not exist", "txid", string(*req)) - return nil, err + return nil, eth.NewCallbackError(err.Error()) } return ð.GetTransactionReceiptResponse{ TransactionHash: ethTx.Hash, @@ -95,11 +97,13 @@ func (p *ProxyETHGetTransactionReceipt) request(req *qtum.GetTransactionReceiptR qtumTx, err := p.Qtum.GetRawTransaction(qtumReceipt.TransactionHash, false) if err != nil { - return nil, errors.WithMessage(err, "couldn't get transaction") + p.GetDebugLogger().Log("msg", "couldn't get transaction", "err", err) + return nil, eth.NewCallbackError("couldn't get transaction") } decodedRawQtumTx, err := p.Qtum.DecodeRawTransaction(qtumTx.Hex) if err != nil { - return nil, errors.WithMessage(err, "couldn't decode raw transaction") + p.GetDebugLogger().Log("msg", "couldn't decode raw transaction", "err", err) + return nil, eth.NewCallbackError("couldn't decode raw transaction") } if decodedRawQtumTx.IsContractCreation() { ethReceipt.To = "" diff --git a/pkg/transformer/eth_getUncleByBlockHashAndIndex.go b/pkg/transformer/eth_getUncleByBlockHashAndIndex.go index dea331fa..849d12d0 100644 --- a/pkg/transformer/eth_getUncleByBlockHashAndIndex.go +++ b/pkg/transformer/eth_getUncleByBlockHashAndIndex.go @@ -12,7 +12,7 @@ func (p *ETHGetUncleByBlockHashAndIndex) Method() string { return "eth_getUncleByBlockHashAndIndex" } -func (p *ETHGetUncleByBlockHashAndIndex) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHGetUncleByBlockHashAndIndex) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { // hardcoded to nil return nil, nil } diff --git a/pkg/transformer/eth_getUncleCountByBlockHash.go b/pkg/transformer/eth_getUncleCountByBlockHash.go index 7dd1210d..f3b18e9c 100644 --- a/pkg/transformer/eth_getUncleCountByBlockHash.go +++ b/pkg/transformer/eth_getUncleCountByBlockHash.go @@ -12,7 +12,7 @@ func (p *ETHGetUncleCountByBlockHash) Method() string { return "eth_getUncleCountByBlockHash" } -func (p *ETHGetUncleCountByBlockHash) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHGetUncleCountByBlockHash) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { // hardcoded to 0 return 0, nil } diff --git a/pkg/transformer/eth_getUncleCountByBlockNumber.go b/pkg/transformer/eth_getUncleCountByBlockNumber.go index f5ae8d81..670612bb 100644 --- a/pkg/transformer/eth_getUncleCountByBlockNumber.go +++ b/pkg/transformer/eth_getUncleCountByBlockNumber.go @@ -12,7 +12,7 @@ func (p *ETHGetUncleCountByBlockNumber) Method() string { return "eth_getUncleCountByBlockNumber" } -func (p *ETHGetUncleCountByBlockNumber) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHGetUncleCountByBlockNumber) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { // hardcoded to 0 return "0x0", nil } diff --git a/pkg/transformer/eth_hashrate.go b/pkg/transformer/eth_hashrate.go index b96c39f9..51055321 100644 --- a/pkg/transformer/eth_hashrate.go +++ b/pkg/transformer/eth_hashrate.go @@ -18,14 +18,14 @@ func (p *ProxyETHHashrate) Method() string { return "eth_hashrate" } -func (p *ProxyETHHashrate) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHHashrate) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyETHHashrate) request() (*eth.HashrateResponse, error) { +func (p *ProxyETHHashrate) request() (*eth.HashrateResponse, eth.JSONRPCError) { qtumresp, err := p.Qtum.GetHashrate() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res diff --git a/pkg/transformer/eth_mining.go b/pkg/transformer/eth_mining.go index 3bf48ba2..da82267d 100644 --- a/pkg/transformer/eth_mining.go +++ b/pkg/transformer/eth_mining.go @@ -15,14 +15,14 @@ func (p *ProxyETHMining) Method() string { return "eth_mining" } -func (p *ProxyETHMining) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHMining) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyETHMining) request() (*eth.MiningResponse, error) { +func (p *ProxyETHMining) request() (*eth.MiningResponse, eth.JSONRPCError) { qtumresp, err := p.Qtum.GetMining() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } // qtum res -> eth res diff --git a/pkg/transformer/eth_net_listening.go b/pkg/transformer/eth_net_listening.go index 05720c90..246cc78b 100644 --- a/pkg/transformer/eth_net_listening.go +++ b/pkg/transformer/eth_net_listening.go @@ -15,11 +15,11 @@ func (p *ProxyNetListening) Method() string { return "net_listening" } -func (p *ProxyNetListening) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyNetListening) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { networkInfo, err := p.GetNetworkInfo() if err != nil { p.GetDebugLogger().Log("method", p.Method(), "msg", "Failed to query network info", "err", err) - return false, err + return false, eth.NewCallbackError(err.Error()) } p.GetDebugLogger().Log("method", p.Method(), "network active", networkInfo.NetworkActive) diff --git a/pkg/transformer/eth_net_peerCount.go b/pkg/transformer/eth_net_peerCount.go index 36014e7e..36c91458 100644 --- a/pkg/transformer/eth_net_peerCount.go +++ b/pkg/transformer/eth_net_peerCount.go @@ -16,14 +16,14 @@ func (p *ProxyNetPeerCount) Method() string { return "net_peerCount" } -func (p *ProxyNetPeerCount) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyNetPeerCount) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyNetPeerCount) request() (*eth.NetPeerCountResponse, error) { +func (p *ProxyNetPeerCount) request() (*eth.NetPeerCountResponse, eth.JSONRPCError) { peerInfos, err := p.GetPeerInfo() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } resp := eth.NetPeerCountResponse(hexutil.EncodeUint64(uint64(len(peerInfos)))) diff --git a/pkg/transformer/eth_net_version.go b/pkg/transformer/eth_net_version.go index c08826cd..6eb6cca7 100644 --- a/pkg/transformer/eth_net_version.go +++ b/pkg/transformer/eth_net_version.go @@ -15,14 +15,14 @@ func (p *ProxyETHNetVersion) Method() string { return "net_version" } -func (p *ProxyETHNetVersion) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHNetVersion) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyETHNetVersion) request() (*eth.NetVersionResponse, error) { +func (p *ProxyETHNetVersion) request() (*eth.NetVersionResponse, eth.JSONRPCError) { var qtumresp *qtum.GetBlockChainInfoResponse if err := p.Qtum.Request(qtum.MethodGetBlockChainInfo, nil, &qtumresp); err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } var networkID string diff --git a/pkg/transformer/eth_newBlockFilter.go b/pkg/transformer/eth_newBlockFilter.go index 1e2cbf0b..6f5b9a2a 100644 --- a/pkg/transformer/eth_newBlockFilter.go +++ b/pkg/transformer/eth_newBlockFilter.go @@ -17,14 +17,14 @@ func (p *ProxyETHNewBlockFilter) Method() string { return "eth_newBlockFilter" } -func (p *ProxyETHNewBlockFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHNewBlockFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return p.request() } -func (p *ProxyETHNewBlockFilter) request() (eth.NewBlockFilterResponse, error) { +func (p *ProxyETHNewBlockFilter) request() (eth.NewBlockFilterResponse, eth.JSONRPCError) { blockCount, err := p.GetBlockCount() if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } filter := p.filter.New(eth.NewBlockFilterTy) diff --git a/pkg/transformer/eth_newFilter.go b/pkg/transformer/eth_newFilter.go index bab2de3e..9a6c765c 100644 --- a/pkg/transformer/eth_newFilter.go +++ b/pkg/transformer/eth_newFilter.go @@ -19,16 +19,17 @@ func (p *ProxyETHNewFilter) Method() string { return "eth_newFilter" } -func (p *ProxyETHNewFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHNewFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.NewFilterRequest if err := json.Unmarshal(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(&req) } -func (p *ProxyETHNewFilter) request(ethreq *eth.NewFilterRequest) (*eth.NewFilterResponse, error) { +func (p *ProxyETHNewFilter) request(ethreq *eth.NewFilterRequest) (*eth.NewFilterResponse, eth.JSONRPCError) { from, err := getBlockNumberByRawParam(p.Qtum, ethreq.FromBlock, true) if err != nil { @@ -48,7 +49,7 @@ func (p *ProxyETHNewFilter) request(ethreq *eth.NewFilterRequest) (*eth.NewFilte if len(ethreq.Topics) > 0 { topics, err := eth.TranslateTopics(ethreq.Topics) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } filter.Data.Store("topics", qtum.NewSearchLogsTopics(topics)) } diff --git a/pkg/transformer/eth_personal_unlockAccount.go b/pkg/transformer/eth_personal_unlockAccount.go index bc13bc6a..a104ce72 100644 --- a/pkg/transformer/eth_personal_unlockAccount.go +++ b/pkg/transformer/eth_personal_unlockAccount.go @@ -12,6 +12,6 @@ func (p *ProxyETHPersonalUnlockAccount) Method() string { return "personal_unlockAccount" } -func (p *ProxyETHPersonalUnlockAccount) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHPersonalUnlockAccount) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return eth.PersonalUnlockAccountResponse(true), nil } diff --git a/pkg/transformer/eth_protocolVersion.go b/pkg/transformer/eth_protocolVersion.go index b84f3c3b..bbf5197c 100644 --- a/pkg/transformer/eth_protocolVersion.go +++ b/pkg/transformer/eth_protocolVersion.go @@ -12,6 +12,6 @@ func (p *ETHProtocolVersion) Method() string { return "eth_protocolVersion" } -func (p *ETHProtocolVersion) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHProtocolVersion) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return "0x41", nil } diff --git a/pkg/transformer/eth_sendRawTransaction.go b/pkg/transformer/eth_sendRawTransaction.go index 3782b497..1ef43ce3 100644 --- a/pkg/transformer/eth_sendRawTransaction.go +++ b/pkg/transformer/eth_sendRawTransaction.go @@ -2,7 +2,6 @@ package transformer import ( "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" "github.com/qtumproject/janus/pkg/utils" @@ -19,19 +18,21 @@ func (p *ProxyETHSendRawTransaction) Method() string { return "eth_sendRawTransaction" } -func (p *ProxyETHSendRawTransaction) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHSendRawTransaction) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var params eth.SendRawTransactionRequest if err := unmarshalRequest(req.Params, ¶ms); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } if params[0] == "" { - return nil, errors.Errorf("invalid parameter: raw transaction hexed string is empty") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("invalid parameter: raw transaction hexed string is empty") } return p.request(params) } -func (p *ProxyETHSendRawTransaction) request(params eth.SendRawTransactionRequest) (eth.SendRawTransactionResponse, error) { +func (p *ProxyETHSendRawTransaction) request(params eth.SendRawTransactionRequest) (eth.SendRawTransactionResponse, eth.JSONRPCError) { var ( qtumHexedRawTx = utils.RemoveHexPrefix(params[0]) req = qtum.SendRawTransactionRequest([1]string{qtumHexedRawTx}) @@ -45,11 +46,11 @@ func (p *ProxyETHSendRawTransaction) request(params eth.SendRawTransactionReques rawTx, err := p.Qtum.DecodeRawTransaction(qtumHexedRawTx) if err != nil { p.GetErrorLogger().Log("msg", "Error decoding raw transaction for duplicate raw transaction", "err", err) - return eth.SendRawTransactionResponse(""), err + return eth.SendRawTransactionResponse(""), eth.NewCallbackError(err.Error()) } qtumresp = &qtum.SendRawTransactionResponse{Result: rawTx.Hash} } else { - return eth.SendRawTransactionResponse(""), err + return eth.SendRawTransactionResponse(""), eth.NewCallbackError(err.Error()) } } else { if p.CanGenerate() { diff --git a/pkg/transformer/eth_sendTransaction.go b/pkg/transformer/eth_sendTransaction.go index 238344bb..a16f0d54 100644 --- a/pkg/transformer/eth_sendTransaction.go +++ b/pkg/transformer/eth_sendTransaction.go @@ -2,7 +2,6 @@ package transformer import ( "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" "github.com/qtumproject/janus/pkg/utils" @@ -18,36 +17,38 @@ func (p *ProxyETHSendTransaction) Method() string { return "eth_sendTransaction" } -func (p *ProxyETHSendTransaction) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHSendTransaction) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.SendTransactionRequest err := unmarshalRequest(rawreq.Params, &req) if err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } var result interface{} + var jsonErr eth.JSONRPCError if req.IsCreateContract() { - result, err = p.requestCreateContract(&req) + result, jsonErr = p.requestCreateContract(&req) } else if req.IsSendEther() { - result, err = p.requestSendToAddress(&req) + result, jsonErr = p.requestSendToAddress(&req) } else if req.IsCallContract() { - result, err = p.requestSendToContract(&req) + result, jsonErr = p.requestSendToContract(&req) } else { - return nil, errors.New("Unknown operation") + return nil, eth.NewInvalidParamsError("Unknown operation") } if p.CanGenerate() { p.GenerateIfPossible() } - return result, err + return result, jsonErr } -func (p *ProxyETHSendTransaction) requestSendToContract(ethtx *eth.SendTransactionRequest) (*eth.SendTransactionResponse, error) { +func (p *ProxyETHSendTransaction) requestSendToContract(ethtx *eth.SendTransactionRequest) (*eth.SendTransactionResponse, eth.JSONRPCError) { gasLimit, gasPrice, err := EthGasToQtum(ethtx) if err != nil { - return nil, err + return nil, eth.NewInvalidParamsError(err.Error()) } amount := decimal.NewFromFloat(0.0) @@ -55,7 +56,7 @@ func (p *ProxyETHSendTransaction) requestSendToContract(ethtx *eth.SendTransacti var err error amount, err = EthValueToQtumAmount(ethtx.Value, ZeroSatoshi) if err != nil { - return nil, errors.Wrap(err, "EthValueToQtumAmount:") + return nil, eth.NewInvalidParamsError(err.Error()) } } @@ -70,21 +71,21 @@ func (p *ProxyETHSendTransaction) requestSendToContract(ethtx *eth.SendTransacti if from := ethtx.From; from != "" && utils.IsEthHexAddress(from) { from, err = p.FromHexAddress(from) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } qtumreq.SenderAddress = from } var resp *qtum.SendToContractResponse if err := p.Qtum.Request(qtum.MethodSendToContract, &qtumreq, &resp); err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } ethresp := eth.SendTransactionResponse(utils.AddHexPrefix(resp.Txid)) return ðresp, nil } -func (p *ProxyETHSendTransaction) requestSendToAddress(req *eth.SendTransactionRequest) (*eth.SendTransactionResponse, error) { +func (p *ProxyETHSendTransaction) requestSendToAddress(req *eth.SendTransactionRequest) (*eth.SendTransactionResponse, eth.JSONRPCError) { getQtumWalletAddress := func(addr string) (string, error) { if utils.IsEthHexAddress(addr) { return p.FromHexAddress(utils.RemoveHexPrefix(addr)) @@ -94,17 +95,17 @@ func (p *ProxyETHSendTransaction) requestSendToAddress(req *eth.SendTransactionR from, err := getQtumWalletAddress(req.From) if err != nil { - return nil, err + return nil, eth.NewInvalidParamsError(err.Error()) } to, err := getQtumWalletAddress(req.To) if err != nil { - return nil, err + return nil, eth.NewInvalidParamsError(err.Error()) } amount, err := EthValueToQtumAmount(req.Value, ZeroSatoshi) if err != nil { - return nil, errors.Wrap(err, "EthValueToQtumAmount:") + return nil, eth.NewInvalidParamsError(err.Error()) } p.GetDebugLogger().Log("msg", "successfully converted from wei to QTUM", "wei", req.Value, "qtum", amount) @@ -124,7 +125,7 @@ func (p *ProxyETHSendTransaction) requestSendToAddress(req *eth.SendTransactionR // } // this can happen if there are enough coins but some required are untrusted // you can get the trusted coin balance via getbalances rpc call - return nil, err + return nil, eth.NewCallbackError(err.Error()) } ethresp := eth.SendTransactionResponse(utils.AddHexPrefix(string(qtumresp))) @@ -132,10 +133,10 @@ func (p *ProxyETHSendTransaction) requestSendToAddress(req *eth.SendTransactionR return ðresp, nil } -func (p *ProxyETHSendTransaction) requestCreateContract(req *eth.SendTransactionRequest) (*eth.SendTransactionResponse, error) { +func (p *ProxyETHSendTransaction) requestCreateContract(req *eth.SendTransactionRequest) (*eth.SendTransactionResponse, eth.JSONRPCError) { gasLimit, gasPrice, err := EthGasToQtum(req) if err != nil { - return nil, err + return nil, eth.NewInvalidParamsError(err.Error()) } qtumreq := &qtum.CreateContractRequest{ @@ -149,7 +150,7 @@ func (p *ProxyETHSendTransaction) requestCreateContract(req *eth.SendTransaction if utils.IsEthHexAddress(from) { from, err = p.FromHexAddress(from) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } } @@ -158,7 +159,7 @@ func (p *ProxyETHSendTransaction) requestCreateContract(req *eth.SendTransaction var resp *qtum.CreateContractResponse if err := p.Qtum.Request(qtum.MethodCreateContract, qtumreq, &resp); err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } ethresp := eth.SendTransactionResponse(utils.AddHexPrefix(string(resp.Txid))) diff --git a/pkg/transformer/eth_sign.go b/pkg/transformer/eth_sign.go index 312afa56..fc1ba2fc 100644 --- a/pkg/transformer/eth_sign.go +++ b/pkg/transformer/eth_sign.go @@ -4,11 +4,11 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "fmt" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" "github.com/qtumproject/janus/pkg/utils" @@ -23,11 +23,12 @@ func (p *ProxyETHSign) Method() string { return "eth_sign" } -func (p *ProxyETHSign) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHSign) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.SignRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { p.GetDebugLogger().Log("method", p.Method(), "error", err) - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } addr := utils.RemoveHexPrefix(req.Account) @@ -35,13 +36,13 @@ func (p *ProxyETHSign) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (inte acc := p.Qtum.Accounts.FindByHexAddress(addr) if acc == nil { p.GetDebugLogger().Log("method", p.Method(), "account", addr, "msg", "Unknown account") - return nil, errors.Errorf("No such account: %s", addr) + return nil, eth.NewInvalidParamsError(fmt.Sprintf("No such account: %s", addr)) } sig, err := signMessage(acc.PrivKey, req.Message) if err != nil { p.GetDebugLogger().Log("method", p.Method(), "msg", "Failed to sign message", "error", err) - return nil, err + return nil, eth.NewCallbackError(err.Error()) } p.GetDebugLogger().Log("method", p.Method(), "msg", "Successfully signed message") diff --git a/pkg/transformer/eth_signTransaction.go b/pkg/transformer/eth_signTransaction.go index 223299d1..81387b2b 100644 --- a/pkg/transformer/eth_signTransaction.go +++ b/pkg/transformer/eth_signTransaction.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" "github.com/qtumproject/janus/pkg/utils" @@ -21,10 +20,11 @@ func (p *ProxyETHSignTransaction) Method() string { return "eth_signTransaction" } -func (p *ProxyETHSignTransaction) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHSignTransaction) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.SendTransactionRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } if req.IsCreateContract() { @@ -40,7 +40,7 @@ func (p *ProxyETHSignTransaction) Request(rawreq *eth.JSONRPCRequest, c echo.Con p.GetDebugLogger().Log("method", p.Method(), "msg", "transaction is an unknown request") } - return nil, errors.New("Unknown operation") + return nil, eth.NewInvalidParamsError("Unknown operation") } func (p *ProxyETHSignTransaction) getRequiredUtxos(from string, neededAmount decimal.Decimal) ([]qtum.RawTxInputs, decimal.Decimal, error) { @@ -83,10 +83,10 @@ func calculateNeededAmount(value, gasLimit, gasPrice decimal.Decimal) decimal.De return value.Add(gasLimit.Mul(gasPrice)) } -func (p *ProxyETHSignTransaction) requestSendToContract(ethtx *eth.SendTransactionRequest) (string, error) { +func (p *ProxyETHSignTransaction) requestSendToContract(ethtx *eth.SendTransactionRequest) (string, eth.JSONRPCError) { gasLimit, gasPrice, err := EthGasToQtum(ethtx) if err != nil { - return "", err + return "", eth.NewInvalidParamsError(err.Error()) } amount := decimal.NewFromFloat(0.0) @@ -94,24 +94,24 @@ func (p *ProxyETHSignTransaction) requestSendToContract(ethtx *eth.SendTransacti var err error amount, err = EthValueToQtumAmount(ethtx.Value, ZeroSatoshi) if err != nil { - return "", errors.Wrap(err, "EthValueToQtumAmount:") + return "", eth.NewInvalidParamsError(err.Error()) } } newGasPrice, err := decimal.NewFromString(gasPrice) if err != nil { - return "", err + return "", eth.NewInvalidParamsError(err.Error()) } neededAmount := calculateNeededAmount(amount, decimal.NewFromBigInt(gasLimit, 0), newGasPrice) inputs, balance, err := p.getRequiredUtxos(ethtx.From, neededAmount) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } change, err := calculateChange(balance, neededAmount) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } contractInteractTx := &qtum.SendToContractRawRequest{ @@ -125,7 +125,7 @@ func (p *ProxyETHSignTransaction) requestSendToContract(ethtx *eth.SendTransacti if from := ethtx.From; from != "" && utils.IsEthHexAddress(from) { from, err = p.FromHexAddress(from) if err != nil { - return "", err + return "", eth.NewInvalidParamsError(err.Error()) } contractInteractTx.SenderAddress = from } @@ -134,26 +134,26 @@ func (p *ProxyETHSignTransaction) requestSendToContract(ethtx *eth.SendTransacti acc := p.Qtum.Accounts.FindByHexAddress(strings.ToLower(fromAddr)) if acc == nil { - return "", errors.Errorf("No such account: %s", fromAddr) + return "", eth.NewInvalidParamsError(fmt.Sprintf("No such account: %s", fromAddr)) } rawtxreq := []interface{}{inputs, []interface{}{map[string]*qtum.SendToContractRawRequest{"contract": contractInteractTx}, map[string]decimal.Decimal{contractInteractTx.SenderAddress: change}}} var rawTx string if err := p.Qtum.Request(qtum.MethodCreateRawTx, rawtxreq, &rawTx); err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } var resp *qtum.SignRawTxResponse if err := p.Qtum.Request(qtum.MethodSignRawTx, []interface{}{rawTx}, &resp); err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } if !resp.Complete { - return "", fmt.Errorf("something went wrong with signing the transaction; transaction incomplete") + return "", eth.NewCallbackError("something went wrong with signing the transaction; transaction incomplete") } return utils.AddHexPrefix(resp.Hex), nil } -func (p *ProxyETHSignTransaction) requestSendToAddress(req *eth.SendTransactionRequest) (string, error) { +func (p *ProxyETHSignTransaction) requestSendToAddress(req *eth.SendTransactionRequest) (string, eth.JSONRPCError) { getQtumWalletAddress := func(addr string) (string, error) { if utils.IsEthHexAddress(addr) { return p.FromHexAddress(utils.RemoveHexPrefix(addr)) @@ -163,58 +163,58 @@ func (p *ProxyETHSignTransaction) requestSendToAddress(req *eth.SendTransactionR to, err := getQtumWalletAddress(req.To) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } from, err := getQtumWalletAddress(req.From) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } amount, err := EthValueToQtumAmount(req.Value, ZeroSatoshi) if err != nil { - return "", errors.Wrap(err, "EthValueToQtumAmount:") + return "", eth.NewInvalidParamsError(err.Error()) } inputs, balance, err := p.getRequiredUtxos(req.From, amount) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } change, err := calculateChange(balance, amount) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } var addressValMap = map[string]decimal.Decimal{to: amount, from: change} rawtxreq := []interface{}{inputs, addressValMap} var rawTx string if err := p.Qtum.Request(qtum.MethodCreateRawTx, rawtxreq, &rawTx); err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } var resp *qtum.SignRawTxResponse signrawtxreq := []interface{}{rawTx} if err := p.Qtum.Request(qtum.MethodSignRawTx, signrawtxreq, &resp); err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } if !resp.Complete { - return "", fmt.Errorf("something went wrong with signing the transaction; transaction incomplete") + return "", eth.NewCallbackError("something went wrong with signing the transaction; transaction incomplete") } return utils.AddHexPrefix(resp.Hex), nil } -func (p *ProxyETHSignTransaction) requestCreateContract(req *eth.SendTransactionRequest) (string, error) { +func (p *ProxyETHSignTransaction) requestCreateContract(req *eth.SendTransactionRequest) (string, eth.JSONRPCError) { gasLimit, gasPrice, err := EthGasToQtum(req) if err != nil { - return "", err + return "", eth.NewInvalidParamsError(err.Error()) } from := req.From if utils.IsEthHexAddress(from) { from, err = p.FromHexAddress(from) if err != nil { - return "", err + return "", eth.NewInvalidParamsError(err.Error()) } } @@ -227,33 +227,33 @@ func (p *ProxyETHSignTransaction) requestCreateContract(req *eth.SendTransaction newGasPrice, err := decimal.NewFromString(gasPrice) if err != nil { - return "", err + return "", eth.NewInvalidParamsError(err.Error()) } neededAmount := calculateNeededAmount(decimal.NewFromFloat(0.0), decimal.NewFromBigInt(gasLimit, 0), newGasPrice) inputs, balance, err := p.getRequiredUtxos(req.From, neededAmount) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } change, err := calculateChange(balance, neededAmount) if err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } rawtxreq := []interface{}{inputs, []interface{}{map[string]*qtum.CreateContractRawRequest{"contract": contractDeploymentTx}, map[string]decimal.Decimal{from: change}}} var rawTx string if err := p.Qtum.Request(qtum.MethodCreateRawTx, rawtxreq, &rawTx); err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } var resp *qtum.SignRawTxResponse signrawtxreq := []interface{}{rawTx} if err := p.Qtum.Request(qtum.MethodSignRawTx, signrawtxreq, &resp); err != nil { - return "", err + return "", eth.NewCallbackError(err.Error()) } if !resp.Complete { - return "", fmt.Errorf("something went wrong with signing the transaction; transaction incomplete") + return "", eth.NewCallbackError("something went wrong with signing the transaction; transaction incomplete") } return utils.AddHexPrefix(resp.Hex), nil } diff --git a/pkg/transformer/eth_subscribe.go b/pkg/transformer/eth_subscribe.go index a7fa453e..1c1b70ad 100644 --- a/pkg/transformer/eth_subscribe.go +++ b/pkg/transformer/eth_subscribe.go @@ -2,7 +2,6 @@ package transformer import ( "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/notifier" "github.com/qtumproject/janus/pkg/qtum" @@ -18,7 +17,7 @@ func (p *ETHSubscribe) Method() string { return "eth_subscribe" } -func (p *ETHSubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHSubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { notifier := getNotifier(c) if notifier == nil { p.GetLogger().Log("msg", "eth_subscribe only supported over websocket") @@ -33,20 +32,21 @@ func (p *ETHSubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (inte } } */ - return nil, errors.New("The method eth_subscribe does not exist/is not available") + return nil, eth.NewMethodNotFoundError("eth_subscribe") } var req eth.EthSubscriptionRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(&req, notifier) } -func (p *ETHSubscribe) request(req *eth.EthSubscriptionRequest, notifier *notifier.Notifier) (*eth.EthSubscriptionResponse, error) { +func (p *ETHSubscribe) request(req *eth.EthSubscriptionRequest, notifier *notifier.Notifier) (*eth.EthSubscriptionResponse, eth.JSONRPCError) { notifier.ResponseRequired() id, err := p.NewSubscription(notifier, req) response := eth.EthSubscriptionResponse(id) - return &response, err + return &response, eth.NewCallbackError(err.Error()) } diff --git a/pkg/transformer/eth_uninstallFilter.go b/pkg/transformer/eth_uninstallFilter.go index 5054969d..1c48f4ba 100644 --- a/pkg/transformer/eth_uninstallFilter.go +++ b/pkg/transformer/eth_uninstallFilter.go @@ -17,19 +17,20 @@ func (p *ProxyETHUninstallFilter) Method() string { return "eth_uninstallFilter" } -func (p *ProxyETHUninstallFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyETHUninstallFilter) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var req eth.UninstallFilterRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(&req) } -func (p *ProxyETHUninstallFilter) request(ethreq *eth.UninstallFilterRequest) (eth.UninstallFilterResponse, error) { +func (p *ProxyETHUninstallFilter) request(ethreq *eth.UninstallFilterRequest) (eth.UninstallFilterResponse, eth.JSONRPCError) { id, err := hexutil.DecodeUint64(string(*ethreq)) if err != nil { - return false, err + return false, eth.NewInvalidParamsError(err.Error()) } // uninstall diff --git a/pkg/transformer/eth_unsubscribe.go b/pkg/transformer/eth_unsubscribe.go index eb7a1756..81ed621b 100644 --- a/pkg/transformer/eth_unsubscribe.go +++ b/pkg/transformer/eth_unsubscribe.go @@ -2,7 +2,6 @@ package transformer import ( "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/notifier" "github.com/qtumproject/janus/pkg/qtum" @@ -18,7 +17,7 @@ func (p *ETHUnsubscribe) Method() string { return "eth_unsubscribe" } -func (p *ETHUnsubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ETHUnsubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { notifier := getNotifier(c) if notifier == nil { p.GetLogger().Log("msg", "eth_unsubscribe only supported over websocket") @@ -33,21 +32,22 @@ func (p *ETHUnsubscribe) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (in } } */ - return nil, errors.New("The method eth_subscribe does not exist/is not available") + return nil, eth.NewMethodNotFoundError("eth_subscribe") } var req eth.EthUnsubscribeRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } return p.request(&req, notifier) } -func (p *ETHUnsubscribe) request(req *eth.EthUnsubscribeRequest, notifier *notifier.Notifier) (eth.EthUnsubscribeResponse, error) { +func (p *ETHUnsubscribe) request(req *eth.EthUnsubscribeRequest, notifier *notifier.Notifier) (eth.EthUnsubscribeResponse, eth.JSONRPCError) { if len(*req) != 1 { - // TODO: Proper error response - return false, errors.New("requires one parameter") + // TODO: Correct error code? + return false, eth.NewInvalidParamsError("requires one parameter") } param := (*req)[0] success := notifier.Unsubscribe(param) diff --git a/pkg/transformer/qtum_getUTXOs.go b/pkg/transformer/qtum_getUTXOs.go index 519534a6..27278896 100644 --- a/pkg/transformer/qtum_getUTXOs.go +++ b/pkg/transformer/qtum_getUTXOs.go @@ -2,7 +2,6 @@ package transformer import ( "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" "github.com/qtumproject/janus/pkg/qtum" "github.com/qtumproject/janus/pkg/utils" @@ -19,24 +18,26 @@ func (p *ProxyQTUMGetUTXOs) Method() string { return "qtum_getUTXOs" } -func (p *ProxyQTUMGetUTXOs) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *ProxyQTUMGetUTXOs) Request(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var params eth.GetUTXOsRequest if err := unmarshalRequest(req.Params, ¶ms); err != nil { - return nil, errors.WithMessage(err, "couldn't unmarshal request parameters") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("couldn't unmarshal request parameters") } err := params.CheckHasValidValues() if err != nil { - return nil, errors.WithMessage(err, "couldn't validate parameters value") + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError("couldn't validate parameters value") } return p.request(params) } -func (p *ProxyQTUMGetUTXOs) request(params eth.GetUTXOsRequest) (*eth.GetUTXOsResponse, error) { +func (p *ProxyQTUMGetUTXOs) request(params eth.GetUTXOsRequest) (*eth.GetUTXOsResponse, eth.JSONRPCError) { address, err := convertETHAddress(utils.RemoveHexPrefix(params.Address), p.Chain()) if err != nil { - return nil, errors.WithMessage(err, "couldn't convert Ethereum address to Qtum address") + return nil, eth.NewInvalidParamsError("couldn't convert Ethereum address to Qtum address") } req := qtum.GetAddressUTXOsRequest{ @@ -45,7 +46,7 @@ func (p *ProxyQTUMGetUTXOs) request(params eth.GetUTXOsRequest) (*eth.GetUTXOsRe resp, err := p.Qtum.GetAddressUTXOs(&req) if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } //Convert minSumAmount to Satoshis @@ -61,7 +62,7 @@ func (p *ProxyQTUMGetUTXOs) request(params eth.GetUTXOsRequest) (*eth.GetUTXOsRe } } - return nil, errors.Errorf("required minimum amount is greater than total amount of UTXOs") + return nil, eth.NewCallbackError("required minimum amount is greater than total amount of UTXOs") } func toEthResponseType(utxo qtum.UTXO) eth.QtumUTXO { diff --git a/pkg/transformer/tests_common.go b/pkg/transformer/tests_common.go index 8e7fbe6c..a4ee9015 100644 --- a/pkg/transformer/tests_common.go +++ b/pkg/transformer/tests_common.go @@ -24,9 +24,9 @@ func testETHProxyRequest(t *testing.T, initializer ETHProxyInitializer, requestP //preparing proxy & executing request proxyEth := initializer(qtumClient) - got, err := proxyEth.Request(request, nil) - if err != nil { - t.Fatalf("Failed to process request on %T.Request(%s): %s", proxyEth, requestParams, err) + got, jsonErr := proxyEth.Request(request, nil) + if jsonErr != nil { + t.Fatalf("Failed to process request on %T.Request(%s): %s", proxyEth, requestParams, jsonErr) } if !reflect.DeepEqual(got, want) { diff --git a/pkg/transformer/transformer.go b/pkg/transformer/transformer.go index 255551ef..e767a18b 100644 --- a/pkg/transformer/transformer.go +++ b/pkg/transformer/transformer.go @@ -60,22 +60,22 @@ func (t *Transformer) Register(p ETHProxy) error { } // Transform takes a Transformer and transforms the request from ETH request and returns the proxy request -func (t *Transformer) Transform(req *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (t *Transformer) Transform(req *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { proxy, err := t.getProxy(req.Method) if err != nil { - return nil, errors.WithMessage(err, "couldn't get proxy") + return nil, err } resp, err := proxy.Request(req, c) if err != nil { - return nil, errors.WithMessagef(err, "couldn't proxy %s request", req.Method) + return nil, err } return resp, nil } -func (t *Transformer) getProxy(method string) (ETHProxy, error) { +func (t *Transformer) getProxy(method string) (ETHProxy, eth.JSONRPCError) { proxy, ok := t.transformers[method] if !ok { - return nil, errors.Errorf("The method %s does not exist/is not available", method) + return nil, eth.NewMethodNotFoundError(method) } return proxy, nil } diff --git a/pkg/transformer/type.go b/pkg/transformer/type.go index 935d99e8..2eefd071 100644 --- a/pkg/transformer/type.go +++ b/pkg/transformer/type.go @@ -12,6 +12,6 @@ var UnmarshalRequestErr = errors.New("Input is invalid") type Option func(*Transformer) error type ETHProxy interface { - Request(*eth.JSONRPCRequest, echo.Context) (interface{}, error) + Request(*eth.JSONRPCRequest, echo.Context) (interface{}, eth.JSONRPCError) Method() string } diff --git a/pkg/transformer/util.go b/pkg/transformer/util.go index 82f7f900..8566fe93 100644 --- a/pkg/transformer/util.go +++ b/pkg/transformer/util.go @@ -209,26 +209,26 @@ func formatQtumNonce(nonce int) string { // - string "earliest" for the genesis block // - string "pending" - for the pending state/transactions // Uses defaultVal to differntiate from a eth_getBlockByNumber req and eth_getLogs/eth_newFilter -func getBlockNumberByRawParam(p *qtum.Qtum, rawParam json.RawMessage, defaultVal bool) (*big.Int, error) { +func getBlockNumberByRawParam(p *qtum.Qtum, rawParam json.RawMessage, defaultVal bool) (*big.Int, eth.JSONRPCError) { if !isBytesOfString(rawParam) { - return nil, errors.Errorf("invalid parameter format - string is expected") + return nil, eth.NewInvalidParamsError("invalid parameter format - string is expected") } param := string(rawParam[1 : len(rawParam)-1]) // trim \" runes return getBlockNumberByParam(p, param, defaultVal) } -func getBlockNumberByParam(p *qtum.Qtum, param string, defaultVal bool) (*big.Int, error) { +func getBlockNumberByParam(p *qtum.Qtum, param string, defaultVal bool) (*big.Int, eth.JSONRPCError) { if len(param) < 1 { if defaultVal { res, err := p.GetBlockChainInfo() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } p.GetDebugLogger().Log("function", "getBlockNumberByParam", "msg", "returning default value ("+strconv.Itoa(int(res.Blocks))+")") return big.NewInt(res.Blocks), nil } else { - return nil, errors.Errorf("empty parameter value") + return nil, eth.NewInvalidParamsError("empty parameter value") } } @@ -237,7 +237,7 @@ func getBlockNumberByParam(p *qtum.Qtum, param string, defaultVal bool) (*big.In case "latest": res, err := p.GetBlockChainInfo() if err != nil { - return nil, err + return nil, eth.NewCallbackError(err.Error()) } p.GetDebugLogger().Log("latest", res.Blocks, "msg", "Got latest block") return big.NewInt(res.Blocks), nil @@ -250,13 +250,13 @@ func getBlockNumberByParam(p *qtum.Qtum, param string, defaultVal bool) (*big.In case "pending": // TODO: discuss // ! Researching - return nil, errors.New("TODO: tag is in implementation") + return nil, eth.NewInvalidRequestError("TODO: tag is in implementation") default: // hex number n, err := utils.DecodeBig(param) if err != nil { p.GetDebugLogger().Log("function", "getBlockNumberByParam", "msg", "Failed to decode hex parameter", "value", param) - return nil, errors.Wrap(err, "couldn't decode hex number to big int") + return nil, eth.NewInvalidParamsError("couldn't decode hex number to big int") } return n, nil } @@ -324,20 +324,21 @@ func convertQtumAddress(address string) (ethAddress string, _ error) { return hex.EncodeToString(ethAddrBytes), nil } -func processFilter(p *ProxyETHGetFilterChanges, rawreq *eth.JSONRPCRequest) (*eth.Filter, error) { +func processFilter(p *ProxyETHGetFilterChanges, rawreq *eth.JSONRPCRequest) (*eth.Filter, eth.JSONRPCError) { var req eth.GetFilterChangesRequest if err := unmarshalRequest(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } filterID, err := hexutil.DecodeUint64(string(req)) if err != nil { - return nil, err + return nil, eth.NewInvalidParamsError(err.Error()) } _filter, ok := p.filter.Filter(filterID) if !ok { - return nil, errors.New("Invalid filter id") + return nil, eth.NewCallbackError("Invalid filter id") } filter := _filter.(*eth.Filter) diff --git a/pkg/transformer/web3_clientVersion.go b/pkg/transformer/web3_clientVersion.go index 1d4cbffb..09d729db 100644 --- a/pkg/transformer/web3_clientVersion.go +++ b/pkg/transformer/web3_clientVersion.go @@ -14,7 +14,7 @@ func (p *Web3ClientVersion) Method() string { return "web3_clientVersion" } -func (p *Web3ClientVersion) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *Web3ClientVersion) Request(_ *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { return "QTUM ETHTestRPC/ethereum-js", nil } diff --git a/pkg/transformer/web3_sha3.go b/pkg/transformer/web3_sha3.go index 74658e48..3a9681ba 100644 --- a/pkg/transformer/web3_sha3.go +++ b/pkg/transformer/web3_sha3.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/labstack/echo" - "github.com/pkg/errors" "github.com/qtumproject/janus/pkg/eth" ) @@ -16,11 +15,12 @@ func (p *Web3Sha3) Method() string { return "web3_sha3" } -func (p *Web3Sha3) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, error) { +func (p *Web3Sha3) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interface{}, eth.JSONRPCError) { var err error var req eth.Web3Sha3Request if err = json.Unmarshal(rawreq.Params, &req); err != nil { - return nil, err + // TODO: Correct error code? + return nil, eth.NewInvalidParamsError(err.Error()) } message := req.Message @@ -29,7 +29,7 @@ func (p *Web3Sha3) Request(rawreq *eth.JSONRPCRequest, c echo.Context) (interfac if len(message) != 0 { decoded, err = hexutil.Decode(string(message)) if err != nil { - return nil, errors.Wrap(err, "Failed to decode") + return nil, eth.NewCallbackError("Failed to decode") } }