mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-26 15:22:15 +00:00
RPCResponse.Result is json.RawMessage
This commit is contained in:
parent
0bcae125c2
commit
aff561d8c3
@ -2,6 +2,7 @@ package rpcclient
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -22,8 +23,8 @@ func NewClientJSONRPC(remote string) *ClientJSONRPC {
|
|||||||
return &ClientJSONRPC{remote}
|
return &ClientJSONRPC{remote}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientJSONRPC) Call(method string, params []interface{}) (interface{}, error) {
|
func (c *ClientJSONRPC) Call(method string, params []interface{}, result interface{}) (interface{}, error) {
|
||||||
return CallHTTP_JSONRPC(c.remote, method, params)
|
return CallHTTP_JSONRPC(c.remote, method, params, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI takes params as a map
|
// URI takes params as a map
|
||||||
@ -38,11 +39,11 @@ func NewClientURI(remote string) *ClientURI {
|
|||||||
return &ClientURI{remote}
|
return &ClientURI{remote}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientURI) Call(method string, params map[string]interface{}) (interface{}, error) {
|
func (c *ClientURI) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||||
return CallHTTP_URI(c.remote, method, params)
|
return CallHTTP_URI(c.remote, method, params, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallHTTP_JSONRPC(remote string, method string, params []interface{}) (interface{}, error) {
|
func CallHTTP_JSONRPC(remote string, method string, params []interface{}, result interface{}) (interface{}, error) {
|
||||||
// Make request and get responseBytes
|
// Make request and get responseBytes
|
||||||
request := rpctypes.RPCRequest{
|
request := rpctypes.RPCRequest{
|
||||||
JSONRPC: "2.0",
|
JSONRPC: "2.0",
|
||||||
@ -63,10 +64,10 @@ func CallHTTP_JSONRPC(remote string, method string, params []interface{}) (inter
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Info(Fmt("RPC response: %v", string(responseBytes)))
|
log.Info(Fmt("RPC response: %v", string(responseBytes)))
|
||||||
return unmarshalResponseBytes(responseBytes)
|
return unmarshalResponseBytes(responseBytes, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallHTTP_URI(remote string, method string, params map[string]interface{}) (interface{}, error) {
|
func CallHTTP_URI(remote string, method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||||
values, err := argsToURLValues(params)
|
values, err := argsToURLValues(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -81,18 +82,18 @@ func CallHTTP_URI(remote string, method string, params map[string]interface{}) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return unmarshalResponseBytes(responseBytes)
|
return unmarshalResponseBytes(responseBytes, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
|
|
||||||
func unmarshalResponseBytes(responseBytes []byte) (interface{}, error) {
|
func unmarshalResponseBytes(responseBytes []byte, result interface{}) (interface{}, error) {
|
||||||
// read response
|
// read response
|
||||||
// if rpc/core/types is imported, the result will unmarshal
|
// if rpc/core/types is imported, the result will unmarshal
|
||||||
// into the correct type
|
// into the correct type
|
||||||
var err error
|
var err error
|
||||||
response := &rpctypes.RPCResponse{}
|
response := &rpctypes.RPCResponse{}
|
||||||
wire.ReadJSON(response, responseBytes, &err)
|
err = json.Unmarshal(responseBytes, response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -100,7 +101,9 @@ func unmarshalResponseBytes(responseBytes []byte) (interface{}, error) {
|
|||||||
if errorStr != "" {
|
if errorStr != "" {
|
||||||
return nil, errors.New(errorStr)
|
return nil, errors.New(errorStr)
|
||||||
}
|
}
|
||||||
return response.Result, err
|
// unmarshal the RawMessage into the result
|
||||||
|
result = wire.ReadJSONPtr(result, *response.Result, &err)
|
||||||
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func argsToURLValues(args map[string]interface{}) (url.Values, error) {
|
func argsToURLValues(args map[string]interface{}) (url.Values, error) {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package rpcclient
|
package rpcclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
. "github.com/tendermint/go-common"
|
. "github.com/tendermint/go-common"
|
||||||
"github.com/tendermint/go-rpc/types"
|
"github.com/tendermint/go-rpc/types"
|
||||||
"github.com/tendermint/go-wire"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -79,7 +79,7 @@ func (wsc *WSClient) receiveEventsRoutine() {
|
|||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
var response rpctypes.RPCResponse
|
var response rpctypes.RPCResponse
|
||||||
wire.ReadJSON(&response, data, &err)
|
err := json.Unmarshal(data, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("WSClient failed to parse message", "error", err, "data", string(data))
|
log.Info("WSClient failed to parse message", "error", err, "data", string(data))
|
||||||
wsc.Stop()
|
wsc.Stop()
|
||||||
|
@ -19,6 +19,8 @@ import (
|
|||||||
"github.com/tendermint/go-wire"
|
"github.com/tendermint/go-wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Adds a route for each function in the funcMap, as well as general jsonrpc and websocket handlers for all functions.
|
||||||
|
// "result" is the interface on which the result objects are registered, and is popualted with every RPCResponse
|
||||||
func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc) {
|
func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc) {
|
||||||
// HTTP endpoints
|
// HTTP endpoints
|
||||||
for funcName, rpcFunc := range funcMap {
|
for funcName, rpcFunc := range funcMap {
|
||||||
@ -433,7 +435,6 @@ func (wsc *wsConnection) readRoutine() {
|
|||||||
// receives on a write channel and writes out on the socket
|
// receives on a write channel and writes out on the socket
|
||||||
func (wsc *wsConnection) writeRoutine() {
|
func (wsc *wsConnection) writeRoutine() {
|
||||||
defer wsc.baseConn.Close()
|
defer wsc.baseConn.Close()
|
||||||
var n, err = int(0), error(nil)
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-wsc.Quit:
|
case <-wsc.Quit:
|
||||||
@ -446,14 +447,12 @@ func (wsc *wsConnection) writeRoutine() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
case msg := <-wsc.writeChan:
|
case msg := <-wsc.writeChan:
|
||||||
buf := new(bytes.Buffer)
|
jsonBytes, err := json.Marshal(msg)
|
||||||
wire.WriteJSON(msg, buf, &n, &err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to marshal RPCResponse to JSON", "error", err)
|
log.Error("Failed to marshal RPCResponse to JSON", "error", err)
|
||||||
} else {
|
} else {
|
||||||
wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds))
|
wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds))
|
||||||
bufBytes := buf.Bytes()
|
if err = wsc.baseConn.WriteMessage(websocket.TextMessage, jsonBytes); err != nil {
|
||||||
if err = wsc.baseConn.WriteMessage(websocket.TextMessage, bufBytes); err != nil {
|
|
||||||
log.Warn("Failed to write response on websocket", "error", err)
|
log.Warn("Failed to write response on websocket", "error", err)
|
||||||
wsc.Stop()
|
wsc.Stop()
|
||||||
return
|
return
|
||||||
@ -507,13 +506,18 @@ func (wm *WebsocketManager) WebsocketHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
// rpc.websocket
|
// rpc.websocket
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// returns is result struct and error. If error is not nil, return it
|
// NOTE: assume returns is result struct and error. If error is not nil, return it
|
||||||
func unreflectResult(returns []reflect.Value) (interface{}, error) {
|
func unreflectResult(returns []reflect.Value) (interface{}, error) {
|
||||||
errV := returns[1]
|
errV := returns[1]
|
||||||
if errV.Interface() != nil {
|
if errV.Interface() != nil {
|
||||||
return nil, fmt.Errorf("%v", errV.Interface())
|
return nil, fmt.Errorf("%v", errV.Interface())
|
||||||
}
|
}
|
||||||
return returns[0].Interface(), nil
|
rv := returns[0]
|
||||||
|
// the result is a registered interface,
|
||||||
|
// we need a pointer to it so we can marshal with type byte
|
||||||
|
rvp := reflect.New(rv.Type())
|
||||||
|
rvp.Elem().Set(rv)
|
||||||
|
return rvp.Interface(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes a list of available rpc endpoints as an html page
|
// writes a list of available rpc endpoints as an html page
|
||||||
|
@ -3,6 +3,7 @@ package rpcserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -12,7 +13,7 @@ import (
|
|||||||
"github.com/tendermint/go-alert"
|
"github.com/tendermint/go-alert"
|
||||||
. "github.com/tendermint/go-common"
|
. "github.com/tendermint/go-common"
|
||||||
. "github.com/tendermint/go-rpc/types"
|
. "github.com/tendermint/go-rpc/types"
|
||||||
"github.com/tendermint/go-wire"
|
//"github.com/tendermint/go-wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, error) {
|
func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, error) {
|
||||||
@ -32,7 +33,11 @@ func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WriteRPCResponseHTTP(w http.ResponseWriter, res RPCResponse) {
|
func WriteRPCResponseHTTP(w http.ResponseWriter, res RPCResponse) {
|
||||||
jsonBytes := wire.JSONBytesPretty(res)
|
// jsonBytes := wire.JSONBytesPretty(res)
|
||||||
|
jsonBytes, err := json.Marshal(res)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
w.Write(jsonBytes)
|
w.Write(jsonBytes)
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package rpctypes
|
package rpctypes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/tendermint/go-events"
|
"github.com/tendermint/go-events"
|
||||||
|
"github.com/tendermint/go-wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RPCRequest struct {
|
type RPCRequest struct {
|
||||||
@ -41,15 +44,16 @@ type Result interface {
|
|||||||
type RPCResponse struct {
|
type RPCResponse struct {
|
||||||
JSONRPC string `json:"jsonrpc"`
|
JSONRPC string `json:"jsonrpc"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Result Result `json:"result"`
|
Result *json.RawMessage `json:"result"`
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRPCResponse(id string, res Result, err string) RPCResponse {
|
func NewRPCResponse(id string, res interface{}, err string) RPCResponse {
|
||||||
|
raw := json.RawMessage(wire.JSONBytes(res))
|
||||||
return RPCResponse{
|
return RPCResponse{
|
||||||
JSONRPC: "2.0",
|
JSONRPC: "2.0",
|
||||||
ID: id,
|
ID: id,
|
||||||
Result: res,
|
Result: &raw,
|
||||||
Error: err,
|
Error: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user