github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/rpc/types.go (about)

     1  package rpc
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"strings"
     8  	"sync"
     9  
    10  	"github.com/quickchainproject/quickchain/common/hexutil"
    11  	"gopkg.in/fatih/set.v0"
    12  )
    13  
    14  // API describes the set of methods offered over the RPC interface
    15  type API struct {
    16  	Namespace string      // namespace under which the rpc methods of Service are exposed
    17  	Version   string      // api version for DApp's
    18  	Service   interface{} // receiver instance which holds the methods
    19  	Public    bool        // indication if the methods must be considered safe for public use
    20  }
    21  
    22  // callback is a method callback which was registered in the server
    23  type callback struct {
    24  	rcvr        reflect.Value  // receiver of method
    25  	method      reflect.Method // callback
    26  	argTypes    []reflect.Type // input argument types
    27  	hasCtx      bool           // method's first argument is a context (not included in argTypes)
    28  	errPos      int            // err return idx, of -1 when method cannot return error
    29  	isSubscribe bool           // indication if the callback is a subscription
    30  }
    31  
    32  // service represents a registered object
    33  type service struct {
    34  	name          string        // name for service
    35  	typ           reflect.Type  // receiver type
    36  	callbacks     callbacks     // registered handlers
    37  	subscriptions subscriptions // available subscriptions/notifications
    38  }
    39  
    40  // serverRequest is an incoming request
    41  type serverRequest struct {
    42  	id            interface{}
    43  	svcname       string
    44  	callb         *callback
    45  	args          []reflect.Value
    46  	isUnsubscribe bool
    47  	err           Error
    48  }
    49  
    50  type serviceRegistry map[string]*service // collection of services
    51  type callbacks map[string]*callback      // collection of RPC callbacks
    52  type subscriptions map[string]*callback  // collection of subscription callbacks
    53  
    54  // Server represents a RPC server
    55  type Server struct {
    56  	services serviceRegistry
    57  
    58  	run      int32
    59  	codecsMu sync.Mutex
    60  	codecs   *set.Set
    61  }
    62  
    63  // rpcRequest represents a raw incoming RPC request
    64  type rpcRequest struct {
    65  	service  string
    66  	method   string
    67  	id       interface{}
    68  	isPubSub bool
    69  	params   interface{}
    70  	err      Error // invalid batch element
    71  }
    72  
    73  // Error wraps RPC errors, which contain an error code in addition to the message.
    74  type Error interface {
    75  	Error() string  // returns the message
    76  	ErrorCode() int // returns the code
    77  }
    78  
    79  // ServerCodec implements reading, parsing and writing RPC messages for the server side of
    80  // a RPC session. Implementations must be go-routine safe since the codec can be called in
    81  // multiple go-routines concurrently.
    82  type ServerCodec interface {
    83  	// Read next request
    84  	ReadRequestHeaders() ([]rpcRequest, bool, Error)
    85  	// Parse request argument to the given types
    86  	ParseRequestArguments(argTypes []reflect.Type, params interface{}) ([]reflect.Value, Error)
    87  	// Assemble success response, expects response id and payload
    88  	CreateResponse(id interface{}, reply interface{}) interface{}
    89  	// Assemble error response, expects response id and error
    90  	CreateErrorResponse(id interface{}, err Error) interface{}
    91  	// Assemble error response with extra information about the error through info
    92  	CreateErrorResponseWithInfo(id interface{}, err Error, info interface{}) interface{}
    93  	// Create notification response
    94  	CreateNotification(id, namespace string, event interface{}) interface{}
    95  	// Write msg to client.
    96  	Write(msg interface{}) error
    97  	// Close underlying data stream
    98  	Close()
    99  	// Closed when underlying connection is closed
   100  	Closed() <-chan interface{}
   101  }
   102  
   103  type BlockNumber int64
   104  
   105  const (
   106  	PendingBlockNumber  = BlockNumber(-2)
   107  	LatestBlockNumber   = BlockNumber(-1)
   108  	EarliestBlockNumber = BlockNumber(0)
   109  )
   110  
   111  // UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
   112  // - "latest", "earliest" or "pending" as string arguments
   113  // - the block number
   114  // Returned errors:
   115  // - an invalid block number error when the given argument isn't a known strings
   116  // - an out of range error when the given block number is either too little or too large
   117  func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
   118  	input := strings.TrimSpace(string(data))
   119  	if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' {
   120  		input = input[1 : len(input)-1]
   121  	}
   122  
   123  	switch input {
   124  	case "earliest":
   125  		*bn = EarliestBlockNumber
   126  		return nil
   127  	case "latest":
   128  		*bn = LatestBlockNumber
   129  		return nil
   130  	case "pending":
   131  		*bn = PendingBlockNumber
   132  		return nil
   133  	}
   134  
   135  	blckNum, err := hexutil.DecodeUint64(input)
   136  	if err != nil {
   137  		return err
   138  	}
   139  	if blckNum > math.MaxInt64 {
   140  		return fmt.Errorf("Blocknumber too high")
   141  	}
   142  
   143  	*bn = BlockNumber(blckNum)
   144  	return nil
   145  }
   146  
   147  func (bn BlockNumber) Int64() int64 {
   148  	return (int64)(bn)
   149  }