tendermint/rpc/lib/types/types.go

154 lines
3.8 KiB
Go
Raw Normal View History

2016-01-12 13:50:06 -08:00
package rpctypes
import (
2016-01-13 15:37:35 -08:00
"encoding/json"
"fmt"
2016-02-18 13:07:49 -08:00
"strings"
2016-01-13 15:37:35 -08:00
"github.com/pkg/errors"
2017-04-21 14:51:11 -07:00
events "github.com/tendermint/tmlibs/events"
2016-01-12 13:50:06 -08:00
)
//----------------------------------------
// REQUEST
2016-01-12 13:50:06 -08:00
type RPCRequest struct {
JSONRPC string `json:"jsonrpc"`
ID string `json:"id"`
Method string `json:"method"`
Params *json.RawMessage `json:"params"` // must be map[string]interface{} or []interface{}
2016-01-12 13:50:06 -08:00
}
func NewRPCRequest(id string, method string, params json.RawMessage) RPCRequest {
2016-01-12 13:50:06 -08:00
return RPCRequest{
JSONRPC: "2.0",
ID: id,
Method: method,
Params: &params,
}
}
func (req RPCRequest) String() string {
return fmt.Sprintf("[%s %s]", req.ID, req.Method)
}
func MapToRequest(id string, method string, params map[string]interface{}) (RPCRequest, error) {
payload, err := json.Marshal(params)
if err != nil {
return RPCRequest{}, err
}
request := NewRPCRequest(id, method, payload)
return request, nil
}
func ArrayToRequest(id string, method string, params []interface{}) (RPCRequest, error) {
payload, err := json.Marshal(params)
if err != nil {
return RPCRequest{}, err
2016-01-12 13:50:06 -08:00
}
request := NewRPCRequest(id, method, payload)
return request, nil
2016-01-12 13:50:06 -08:00
}
//----------------------------------------
// RESPONSE
type RpcError struct {
Code int `json:"code"`
Message string `json:"message"`
Data string `json:"data,omitempty"`
}
2016-01-12 13:50:06 -08:00
type RPCResponse struct {
2016-01-13 15:37:35 -08:00
JSONRPC string `json:"jsonrpc"`
ID string `json:"id,omitempty"`
Result *json.RawMessage `json:"result,omitempty"`
Error *RpcError `json:"error,omitempty"`
2016-01-12 13:50:06 -08:00
}
func NewRPCSuccessResponse(id string, res interface{}) RPCResponse {
2016-01-13 19:16:56 -08:00
var raw *json.RawMessage
2016-01-13 19:16:56 -08:00
if res != nil {
var js []byte
js, err := json.Marshal(res)
if err != nil {
return RPCInternalError(id, errors.Wrap(err, "Error marshalling response"))
}
rawMsg := json.RawMessage(js)
raw = &rawMsg
2016-01-13 19:16:56 -08:00
}
return RPCResponse{JSONRPC: "2.0", ID: id, Result: raw}
}
func NewRPCErrorResponse(id string, code int, msg string, data string) RPCResponse {
2016-01-12 13:50:06 -08:00
return RPCResponse{
JSONRPC: "2.0",
ID: id,
Error: &RpcError{Code: code, Message: msg, Data: data},
2016-01-12 13:50:06 -08:00
}
}
func (resp RPCResponse) String() string {
if resp.Error == "" {
return fmt.Sprintf("[%s %v]", resp.ID, resp.Result)
} else {
return fmt.Sprintf("[%s %s]", resp.ID, resp.Error)
}
}
func RPCParseError(id string, err error) RPCResponse {
return NewRPCErrorResponse(id, -32700, "Parse error. Invalid JSON", err.Error())
}
func RPCInvalidRequestError(id string, err error) RPCResponse {
return NewRPCErrorResponse(id, -32600, "Invalid Request", err.Error())
}
func RPCMethodNotFoundError(id string) RPCResponse {
return NewRPCErrorResponse(id, -32601, "Method not found", "")
}
func RPCInvalidParamsError(id string, err error) RPCResponse {
return NewRPCErrorResponse(id, -32602, "Invalid params", err.Error())
}
func RPCInternalError(id string, err error) RPCResponse {
return NewRPCErrorResponse(id, -32603, "Internal error", err.Error())
}
func RPCServerError(id string, err error) RPCResponse {
return NewRPCErrorResponse(id, -32000, "Server error", err.Error())
}
2016-01-12 13:50:06 -08:00
//----------------------------------------
// *wsConnection implements this interface.
type WSRPCConnection interface {
GetRemoteAddr() string
GetEventSwitch() events.EventSwitch
2016-01-12 13:50:06 -08:00
WriteRPCResponse(resp RPCResponse)
TryWriteRPCResponse(resp RPCResponse) bool
}
// websocket-only RPCFuncs take this as the first parameter.
type WSRPCContext struct {
Request RPCRequest
WSRPCConnection
}
2016-02-18 13:07:49 -08:00
//----------------------------------------
// SOCKETS
2016-02-18 13:07:49 -08:00
//
// Determine if its a unix or tcp socket.
// If tcp, must specify the port; `0.0.0.0` will return incorrectly as "unix" since there's no port
func SocketType(listenAddr string) string {
socketType := "unix"
2016-02-18 18:05:24 -08:00
if len(strings.Split(listenAddr, ":")) >= 2 {
2016-02-18 13:07:49 -08:00
socketType = "tcp"
}
return socketType
}