diff --git a/geth/rpc/call_raw.go b/geth/rpc/call_raw.go index a074f6f54..8094fdc69 100644 --- a/geth/rpc/call_raw.go +++ b/geth/rpc/call_raw.go @@ -28,20 +28,31 @@ func (c *Client) CallRaw(body string) string { return c.callRawContext(ctx, json.RawMessage(body)) } -// jsonrpcMessage represents JSON-RPC request, notification, successful response or -// error response. +// jsonrpcMessage represents JSON-RPC message type jsonrpcMessage struct { Version string `json:"jsonrpc"` - ID json.RawMessage `json:"id,omitempty"` - Method string `json:"method,omitempty"` - Params json.RawMessage `json:"params,omitempty"` - Error *jsonError `json:"error,omitempty"` - Result json.RawMessage `json:"result,omitempty"` + ID json.RawMessage `json:"id"` +} + +type jsonrpcRequest struct { + jsonrpcMessage + Method string `json:"method"` + Params json.RawMessage `json:"params,omitempty"` +} + +type jsonrpcSuccessfulResponse struct { + jsonrpcMessage + Result json.RawMessage `json:"result"` +} + +type jsonrpcErrorResponse struct { + jsonrpcMessage + Error jsonError `json:"error"` } // jsonError represents Error message for JSON-RPC responses. type jsonError struct { - Code int `json:"code,omitempty"` + Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data,omitempty"` } @@ -146,8 +157,8 @@ func methodAndParamsFromBody(body json.RawMessage) (string, []interface{}, json. } // unmarshalMessage tries to unmarshal JSON-RPC message. -func unmarshalMessage(body json.RawMessage) (*jsonrpcMessage, error) { - var msg jsonrpcMessage +func unmarshalMessage(body json.RawMessage) (*jsonrpcRequest, error) { + var msg jsonrpcRequest err := json.Unmarshal(body, &msg) return &msg, err } @@ -157,17 +168,12 @@ func newSuccessResponse(result json.RawMessage, id json.RawMessage) string { id = defaultMsgID } - // original response with `null` is lost due to geth RPC client - // conversion (unmarshalling). We'll have nil result object in this case, - // so handle it specially. `result` is required field in response. - if result == nil { - result = json.RawMessage("null") - } - - msg := &jsonrpcMessage{ - ID: id, - Version: jsonrpcVersion, - Result: result, + msg := &jsonrpcSuccessfulResponse{ + jsonrpcMessage: jsonrpcMessage{ + ID: id, + Version: jsonrpcVersion, + }, + Result: result, } data, _ := json.Marshal(msg) return string(data) @@ -178,10 +184,12 @@ func newErrorResponse(code int, err error, id json.RawMessage) string { id = defaultMsgID } - errMsg := &jsonrpcMessage{ - Version: jsonrpcVersion, - ID: id, - Error: &jsonError{ + errMsg := &jsonrpcErrorResponse{ + jsonrpcMessage: jsonrpcMessage{ + ID: id, + Version: jsonrpcVersion, + }, + Error: jsonError{ Code: code, Message: err.Error(), }, diff --git a/geth/rpc/call_raw_test.go b/geth/rpc/call_raw_test.go index 32ab397df..a75912223 100644 --- a/geth/rpc/call_raw_test.go +++ b/geth/rpc/call_raw_test.go @@ -42,10 +42,10 @@ func TestUnmarshalMessage(t *testing.T) { got, err := unmarshalMessage(body) require.NoError(t, err) - expected := &jsonrpcMessage{ - Version: "2.0", - Method: "subtract", - Params: json.RawMessage(`{"subtrahend": 23, "minuend": 42}`), + expected := &jsonrpcRequest{ + jsonrpcMessage: jsonrpcMessage{Version: "2.0"}, + Method: "subtract", + Params: json.RawMessage(`{"subtrahend": 23, "minuend": 42}`), } require.Equal(t, expected, got) }