github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/rpc/lib/types/types.go (about)

     1  package types
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  
     8  	"github.com/pkg/errors"
     9  	tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
    10  )
    11  
    12  type RPCRequest struct {
    13  	JSONRPC string          `json:"jsonrpc"`
    14  	ID      string          `json:"id"`
    15  	Method  string          `json:"method"`
    16  	Params  json.RawMessage `json:"params,omitempty"` // must be map[string]interface{} or []interface{}
    17  }
    18  
    19  func NewRPCRequest(id string, method string, params json.RawMessage) RPCRequest {
    20  	return RPCRequest{
    21  		JSONRPC: "2.0",
    22  		ID:      id,
    23  		Method:  method,
    24  		Params:  params,
    25  	}
    26  }
    27  
    28  func (req RPCRequest) String() string {
    29  	return fmt.Sprintf("[%s %s]", req.ID, req.Method)
    30  }
    31  
    32  func NewRequest(id string, method string, params interface{}) (RPCRequest, error) {
    33  	var payload json.RawMessage
    34  	var err error
    35  	if params != nil {
    36  		payload, err = json.Marshal(params)
    37  		if err != nil {
    38  			return RPCRequest{}, err
    39  		}
    40  	}
    41  	request := NewRPCRequest(id, method, payload)
    42  	return request, nil
    43  }
    44  
    45  type RPCError struct {
    46  	Code    RPCErrorCode    `json:"code"`
    47  	Message string          `json:"message"`
    48  	Data    json.RawMessage `json:"data,omitempty"`
    49  }
    50  
    51  func (err *RPCError) IsServerError() bool {
    52  	return err.Code.IsServerError()
    53  }
    54  
    55  func (err *RPCError) Error() string {
    56  	const baseFormat = "%v - %s"
    57  	if len(err.Data) > 0 {
    58  		return fmt.Sprintf(baseFormat+": %s", err.Code, err.Message, err.Data)
    59  	}
    60  	return fmt.Sprintf(baseFormat, err.Code, err.Message)
    61  }
    62  
    63  func (err *RPCError) HTTPStatusCode() int {
    64  	if err == nil {
    65  		return 200
    66  	}
    67  	return err.Code.HTTPStatusCode()
    68  }
    69  
    70  type RPCResponse struct {
    71  	JSONRPC string          `json:"jsonrpc"`
    72  	ID      string          `json:"id"`
    73  	Result  json.RawMessage `json:"result,omitempty"`
    74  	Error   *RPCError       `json:"error,omitempty"`
    75  }
    76  
    77  func NewRPCSuccessResponse(id string, res interface{}) RPCResponse {
    78  	var rawMsg json.RawMessage
    79  
    80  	if res != nil {
    81  		var err error
    82  		rawMsg, err = json.Marshal(res)
    83  		if err != nil {
    84  			return RPCInternalError(id, errors.Wrap(err, "Error marshalling response"))
    85  		}
    86  	}
    87  
    88  	return RPCResponse{JSONRPC: "2.0", ID: id, Result: rawMsg}
    89  }
    90  
    91  func NewRPCErrorResponse(id string, code RPCErrorCode, data string) RPCResponse {
    92  	var bs []byte
    93  	if data != "" {
    94  		var err error
    95  		bs, err = json.Marshal(data)
    96  		if err != nil {
    97  			panic(fmt.Errorf("unexpected error JSON marshalling string: %w", err))
    98  		}
    99  	}
   100  	return RPCResponse{
   101  		JSONRPC: "2.0",
   102  		ID:      id,
   103  		Error:   &RPCError{Code: code, Message: code.String(), Data: bs},
   104  	}
   105  }
   106  
   107  func (resp RPCResponse) String() string {
   108  	if resp.Error == nil {
   109  		return fmt.Sprintf("[%s %v]", resp.ID, resp.Result)
   110  	}
   111  	return fmt.Sprintf("[%s %s]", resp.ID, resp.Error)
   112  }
   113  
   114  func RPCParseError(id string, err error) RPCResponse {
   115  	return NewRPCErrorResponse(id, RPCErrorCodeParseError, err.Error())
   116  }
   117  
   118  func RPCInvalidRequestError(id string, err error) RPCResponse {
   119  	return NewRPCErrorResponse(id, RPCErrorCodeInvalidRequest, err.Error())
   120  }
   121  
   122  func RPCMethodNotFoundError(id string) RPCResponse {
   123  	return NewRPCErrorResponse(id, RPCErrorCodeMethodNotFound, "")
   124  }
   125  
   126  func RPCInvalidParamsError(id string, err error) RPCResponse {
   127  	return NewRPCErrorResponse(id, RPCErrorCodeInvalidParams, err.Error())
   128  }
   129  
   130  func RPCInternalError(id string, err error) RPCResponse {
   131  	return NewRPCErrorResponse(id, RPCErrorCodeInternalError, err.Error())
   132  }
   133  
   134  // EventSubscriber mirros tendermint/tendermint/types.EventBusSubscriber
   135  type EventSubscriber interface {
   136  	Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, out chan<- interface{}) error
   137  	Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error
   138  	UnsubscribeAll(ctx context.Context, subscriber string) error
   139  }