github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/rpc/types.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:45</date> 10 //</624342665713946624> 11 12 13 package rpc 14 15 import ( 16 "fmt" 17 "math" 18 "reflect" 19 "strings" 20 "sync" 21 22 mapset "github.com/deckarep/golang-set" 23 "github.com/ethereum/go-ethereum/common/hexutil" 24 ) 25 26 //API描述了通过RPC接口提供的一组方法 27 type API struct { 28 Namespace string //暴露服务的RPC方法的命名空间 29 Version string //DAPP的API版本 30 Service interface{} //保存方法的接收器实例 31 Public bool //是否必须将这些方法视为公共使用安全的指示 32 } 33 34 //回调是在服务器中注册的方法回调 35 type callback struct { 36 rcvr reflect.Value //方法接受者 37 method reflect.Method //回调 38 argTypes []reflect.Type //输入参数类型 39 hasCtx bool //方法的第一个参数是上下文(不包括在argtype中) 40 errPos int //当方法无法返回错误时,错误返回IDX,共-1个 41 isSubscribe bool //指示回调是否为订阅 42 } 43 44 //服务表示已注册的对象 45 type service struct { 46 name string //服务的名称 47 typ reflect.Type //接收机类型 48 callbacks callbacks //已注册的处理程序 49 subscriptions subscriptions //可用订阅/通知 50 } 51 52 //ServerRequest是一个传入请求 53 type serverRequest struct { 54 id interface{} 55 svcname string 56 callb *callback 57 args []reflect.Value 58 isUnsubscribe bool 59 err Error 60 } 61 62 type serviceRegistry map[string]*service //服务收集 63 type callbacks map[string]*callback //RPC回调集合 64 type subscriptions map[string]*callback //认购回拨集合 65 66 //服务器表示RPC服务器 67 type Server struct { 68 services serviceRegistry 69 70 run int32 71 codecsMu sync.Mutex 72 codecs mapset.Set 73 } 74 75 //rpc request表示原始传入的rpc请求 76 type rpcRequest struct { 77 service string 78 method string 79 id interface{} 80 isPubSub bool 81 params interface{} 82 err Error //批元素无效 83 } 84 85 //错误包装了RPC错误,其中除消息外还包含错误代码。 86 type Error interface { 87 Error() string //返回消息 88 ErrorCode() int //返回代码 89 } 90 91 //ServerCodec实现对服务器端的RPC消息的读取、分析和写入 92 //一个RPC会话。由于可以调用编解码器,因此实现必须是安全的执行例程。 93 //同时执行多个go例程。 94 type ServerCodec interface { 95 //阅读下一个请求 96 ReadRequestHeaders() ([]rpcRequest, bool, Error) 97 //将请求参数解析为给定类型 98 ParseRequestArguments(argTypes []reflect.Type, params interface{}) ([]reflect.Value, Error) 99 //组装成功响应,期望响应ID和有效负载 100 CreateResponse(id interface{}, reply interface{}) interface{} 101 //组装错误响应,需要响应ID和错误 102 CreateErrorResponse(id interface{}, err Error) interface{} 103 //使用有关错误的额外信息通过信息组装错误响应 104 CreateErrorResponseWithInfo(id interface{}, err Error, info interface{}) interface{} 105 //创建通知响应 106 CreateNotification(id, namespace string, event interface{}) interface{} 107 //将消息写入客户端。 108 Write(msg interface{}) error 109 //关闭基础数据流 110 Close() 111 //当基础连接关闭时关闭 112 Closed() <-chan interface{} 113 } 114 115 type BlockNumber int64 116 117 const ( 118 PendingBlockNumber = BlockNumber(-2) 119 LatestBlockNumber = BlockNumber(-1) 120 EarliestBlockNumber = BlockNumber(0) 121 ) 122 123 //unmashaljson将给定的json片段解析为一个blocknumber。它支持: 124 //-“最新”、“最早”或“挂起”作为字符串参数 125 //-区块编号 126 //返回的错误: 127 //-当给定参数不是已知字符串时出现无效的块号错误 128 //-当给定的块号太小或太大时出现超出范围的错误。 129 func (bn *BlockNumber) UnmarshalJSON(data []byte) error { 130 input := strings.TrimSpace(string(data)) 131 if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' { 132 input = input[1 : len(input)-1] 133 } 134 135 switch input { 136 case "earliest": 137 *bn = EarliestBlockNumber 138 return nil 139 case "latest": 140 *bn = LatestBlockNumber 141 return nil 142 case "pending": 143 *bn = PendingBlockNumber 144 return nil 145 } 146 147 blckNum, err := hexutil.DecodeUint64(input) 148 if err != nil { 149 return err 150 } 151 if blckNum > math.MaxInt64 { 152 return fmt.Errorf("Blocknumber too high") 153 } 154 155 *bn = BlockNumber(blckNum) 156 return nil 157 } 158 159 func (bn BlockNumber) Int64() int64 { 160 return (int64)(bn) 161 } 162