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 }