github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/rpc/json.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 19:16:42</date>
    10  //</624450109135917056>
    11  
    12  
    13  package rpc
    14  
    15  import (
    16  	"bytes"
    17  	"encoding/json"
    18  	"fmt"
    19  	"io"
    20  	"reflect"
    21  	"strconv"
    22  	"strings"
    23  	"sync"
    24  
    25  	"github.com/ethereum/go-ethereum/log"
    26  )
    27  
    28  const (
    29  	jsonrpcVersion           = "2.0"
    30  	serviceMethodSeparator   = "_"
    31  	subscribeMethodSuffix    = "_subscribe"
    32  	unsubscribeMethodSuffix  = "_unsubscribe"
    33  	notificationMethodSuffix = "_subscription"
    34  )
    35  
    36  type jsonRequest struct {
    37  	Method  string          `json:"method"`
    38  	Version string          `json:"jsonrpc"`
    39  	Id      json.RawMessage `json:"id,omitempty"`
    40  	Payload json.RawMessage `json:"params,omitempty"`
    41  }
    42  
    43  type jsonSuccessResponse struct {
    44  	Version string      `json:"jsonrpc"`
    45  	Id      interface{} `json:"id,omitempty"`
    46  	Result  interface{} `json:"result"`
    47  }
    48  
    49  type jsonError struct {
    50  	Code    int         `json:"code"`
    51  	Message string      `json:"message"`
    52  	Data    interface{} `json:"data,omitempty"`
    53  }
    54  
    55  type jsonErrResponse struct {
    56  	Version string      `json:"jsonrpc"`
    57  	Id      interface{} `json:"id,omitempty"`
    58  	Error   jsonError   `json:"error"`
    59  }
    60  
    61  type jsonSubscription struct {
    62  	Subscription string      `json:"subscription"`
    63  	Result       interface{} `json:"result,omitempty"`
    64  }
    65  
    66  type jsonNotification struct {
    67  	Version string           `json:"jsonrpc"`
    68  	Method  string           `json:"method"`
    69  	Params  jsonSubscription `json:"params"`
    70  }
    71  
    72  //jsondec读取JSON-RPC消息并将其写入基础连接。它
    73  //还支持解析参数和序列化(结果)对象。
    74  type jsonCodec struct {
    75  closer sync.Once                 //关闭关闭通道一次
    76  closed chan interface{}          //关闭关闭
    77  decMu  sync.Mutex                //保护解码器
    78  decode func(v interface{}) error //允许多个传输的解码器
    79  encMu  sync.Mutex                //保护编码器
    80  encode func(v interface{}) error //允许多个传输的编码器
    81  rw     io.ReadWriteCloser        //连接
    82  }
    83  
    84  func (err *jsonError) Error() string {
    85  	if err.Message == "" {
    86  		return fmt.Sprintf("json-rpc error %d", err.Code)
    87  	}
    88  	return err.Message
    89  }
    90  
    91  func (err *jsonError) ErrorCode() int {
    92  	return err.Code
    93  }
    94  
    95  //Newcodec创建了一个新的RPC服务器编解码器,支持基于JSON-RPC2.0的
    96  //关于显式给定的编码和解码方法。
    97  func NewCodec(rwc io.ReadWriteCloser, encode, decode func(v interface{}) error) ServerCodec {
    98  	return &jsonCodec{
    99  		closed: make(chan interface{}),
   100  		encode: encode,
   101  		decode: decode,
   102  		rw:     rwc,
   103  	}
   104  }
   105  
   106  //newjsondec创建了一个新的RPC服务器编解码器,支持json-rpc 2.0。
   107  func NewJSONCodec(rwc io.ReadWriteCloser) ServerCodec {
   108  	enc := json.NewEncoder(rwc)
   109  	dec := json.NewDecoder(rwc)
   110  	dec.UseNumber()
   111  
   112  	return &jsonCodec{
   113  		closed: make(chan interface{}),
   114  		encode: enc.Encode,
   115  		decode: dec.Decode,
   116  		rw:     rwc,
   117  	}
   118  }
   119  
   120  //当第一个非空白字符为“[”时,isbatch返回true
   121  func isBatch(msg json.RawMessage) bool {
   122  	for _, c := range msg {
   123  //跳过不重要的空白(http://www.ietf.org/rfc/rfc4627.txt)
   124  		if c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d {
   125  			continue
   126  		}
   127  		return c == '['
   128  	}
   129  	return false
   130  }
   131  
   132  //readRequestHeaders将在不分析参数的情况下读取新请求。它将
   133  //返回请求集合,指示这些请求是否成批
   134  //窗体或传入消息无法读取/分析时出错。
   135  func (c *jsonCodec) ReadRequestHeaders() ([]rpcRequest, bool, Error) {
   136  	c.decMu.Lock()
   137  	defer c.decMu.Unlock()
   138  
   139  	var incomingMsg json.RawMessage
   140  	if err := c.decode(&incomingMsg); err != nil {
   141  		return nil, false, &invalidRequestError{err.Error()}
   142  	}
   143  	if isBatch(incomingMsg) {
   144  		return parseBatchRequest(incomingMsg)
   145  	}
   146  	return parseRequest(incomingMsg)
   147  }
   148  
   149  //当给定的reqid对rpc方法调用无效时,checkreqid返回一个错误。
   150  //有效ID是字符串、数字或空值
   151  func checkReqId(reqId json.RawMessage) error {
   152  	if len(reqId) == 0 {
   153  		return fmt.Errorf("missing request id")
   154  	}
   155  	if _, err := strconv.ParseFloat(string(reqId), 64); err == nil {
   156  		return nil
   157  	}
   158  	var str string
   159  	if err := json.Unmarshal(reqId, &str); err == nil {
   160  		return nil
   161  	}
   162  	return fmt.Errorf("invalid request id")
   163  }
   164  
   165  //ParseRequest将解析来自给定rawMessage的单个请求。它会回来
   166  //解析的请求,指示请求是批处理还是错误,当
   167  //无法分析请求。
   168  func parseRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, Error) {
   169  	var in jsonRequest
   170  	if err := json.Unmarshal(incomingMsg, &in); err != nil {
   171  		return nil, false, &invalidMessageError{err.Error()}
   172  	}
   173  
   174  	if err := checkReqId(in.Id); err != nil {
   175  		return nil, false, &invalidMessageError{err.Error()}
   176  	}
   177  
   178  //订阅是特殊的,它们将始终使用'subscripbemethod'作为有效负载中的第一个参数
   179  	if strings.HasSuffix(in.Method, subscribeMethodSuffix) {
   180  		reqs := []rpcRequest{{id: &in.Id, isPubSub: true}}
   181  		if len(in.Payload) > 0 {
   182  //第一个参数必须是订阅名称
   183  			var subscribeMethod [1]string
   184  			if err := json.Unmarshal(in.Payload, &subscribeMethod); err != nil {
   185  				log.Debug(fmt.Sprintf("Unable to parse subscription method: %v\n", err))
   186  				return nil, false, &invalidRequestError{"Unable to parse subscription request"}
   187  			}
   188  
   189  			reqs[0].service, reqs[0].method = strings.TrimSuffix(in.Method, subscribeMethodSuffix), subscribeMethod[0]
   190  			reqs[0].params = in.Payload
   191  			return reqs, false, nil
   192  		}
   193  		return nil, false, &invalidRequestError{"Unable to parse subscription request"}
   194  	}
   195  
   196  	if strings.HasSuffix(in.Method, unsubscribeMethodSuffix) {
   197  		return []rpcRequest{{id: &in.Id, isPubSub: true,
   198  			method: in.Method, params: in.Payload}}, false, nil
   199  	}
   200  
   201  	elems := strings.Split(in.Method, serviceMethodSeparator)
   202  	if len(elems) != 2 {
   203  		return nil, false, &methodNotFoundError{in.Method, ""}
   204  	}
   205  
   206  //常规RPC调用
   207  	if len(in.Payload) == 0 {
   208  		return []rpcRequest{{service: elems[0], method: elems[1], id: &in.Id}}, false, nil
   209  	}
   210  
   211  	return []rpcRequest{{service: elems[0], method: elems[1], id: &in.Id, params: in.Payload}}, false, nil
   212  }
   213  
   214  //ParseBatchRequest将批处理请求解析为来自给定rawMessage的请求集合,指示
   215  //如果请求是批处理或无法读取请求时出错。
   216  func parseBatchRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, Error) {
   217  	var in []jsonRequest
   218  	if err := json.Unmarshal(incomingMsg, &in); err != nil {
   219  		return nil, false, &invalidMessageError{err.Error()}
   220  	}
   221  
   222  	requests := make([]rpcRequest, len(in))
   223  	for i, r := range in {
   224  		if err := checkReqId(r.Id); err != nil {
   225  			return nil, false, &invalidMessageError{err.Error()}
   226  		}
   227  
   228  		id := &in[i].Id
   229  
   230  //订阅是特殊的,它们将始终使用'subscriptionmethod'作为有效负载中的第一个参数
   231  		if strings.HasSuffix(r.Method, subscribeMethodSuffix) {
   232  			requests[i] = rpcRequest{id: id, isPubSub: true}
   233  			if len(r.Payload) > 0 {
   234  //第一个参数必须是订阅名称
   235  				var subscribeMethod [1]string
   236  				if err := json.Unmarshal(r.Payload, &subscribeMethod); err != nil {
   237  					log.Debug(fmt.Sprintf("Unable to parse subscription method: %v\n", err))
   238  					return nil, false, &invalidRequestError{"Unable to parse subscription request"}
   239  				}
   240  
   241  				requests[i].service, requests[i].method = strings.TrimSuffix(r.Method, subscribeMethodSuffix), subscribeMethod[0]
   242  				requests[i].params = r.Payload
   243  				continue
   244  			}
   245  
   246  			return nil, true, &invalidRequestError{"Unable to parse (un)subscribe request arguments"}
   247  		}
   248  
   249  		if strings.HasSuffix(r.Method, unsubscribeMethodSuffix) {
   250  			requests[i] = rpcRequest{id: id, isPubSub: true, method: r.Method, params: r.Payload}
   251  			continue
   252  		}
   253  
   254  		if len(r.Payload) == 0 {
   255  			requests[i] = rpcRequest{id: id, params: nil}
   256  		} else {
   257  			requests[i] = rpcRequest{id: id, params: r.Payload}
   258  		}
   259  		if elem := strings.Split(r.Method, serviceMethodSeparator); len(elem) == 2 {
   260  			requests[i].service, requests[i].method = elem[0], elem[1]
   261  		} else {
   262  			requests[i].err = &methodNotFoundError{r.Method, ""}
   263  		}
   264  	}
   265  
   266  	return requests, true, nil
   267  }
   268  
   269  //ParseRequestArguments尝试使用给定的
   270  //类型。它返回已分析的值,或者在分析失败时返回错误。
   271  func (c *jsonCodec) ParseRequestArguments(argTypes []reflect.Type, params interface{}) ([]reflect.Value, Error) {
   272  	if args, ok := params.(json.RawMessage); !ok {
   273  		return nil, &invalidParamsError{"Invalid params supplied"}
   274  	} else {
   275  		return parsePositionalArguments(args, argTypes)
   276  	}
   277  }
   278  
   279  //ParsePositionalArguments尝试将给定的参数解析为具有
   280  //给定类型。它返回已分析的值,或者当参数不能
   281  //解析。缺少的可选参数作为reflect.zero值返回。
   282  func parsePositionalArguments(rawArgs json.RawMessage, types []reflect.Type) ([]reflect.Value, Error) {
   283  //读取args数组的开头。
   284  	dec := json.NewDecoder(bytes.NewReader(rawArgs))
   285  	if tok, _ := dec.Token(); tok != json.Delim('[') {
   286  		return nil, &invalidParamsError{"non-array args"}
   287  	}
   288  //读取ARG。
   289  	args := make([]reflect.Value, 0, len(types))
   290  	for i := 0; dec.More(); i++ {
   291  		if i >= len(types) {
   292  			return nil, &invalidParamsError{fmt.Sprintf("too many arguments, want at most %d", len(types))}
   293  		}
   294  		argval := reflect.New(types[i])
   295  		if err := dec.Decode(argval.Interface()); err != nil {
   296  			return nil, &invalidParamsError{fmt.Sprintf("invalid argument %d: %v", i, err)}
   297  		}
   298  		if argval.IsNil() && types[i].Kind() != reflect.Ptr {
   299  			return nil, &invalidParamsError{fmt.Sprintf("missing value for required argument %d", i)}
   300  		}
   301  		args = append(args, argval.Elem())
   302  	}
   303  //读取args数组的结尾。
   304  	if _, err := dec.Token(); err != nil {
   305  		return nil, &invalidParamsError{err.Error()}
   306  	}
   307  //将所有缺少的参数设置为零。
   308  	for i := len(args); i < len(types); i++ {
   309  		if types[i].Kind() != reflect.Ptr {
   310  			return nil, &invalidParamsError{fmt.Sprintf("missing value for required argument %d", i)}
   311  		}
   312  		args = append(args, reflect.Zero(types[i]))
   313  	}
   314  	return args, nil
   315  }
   316  
   317  //createResponse将使用给定的ID创建一个JSON-RPC成功响应,并作为结果进行回复。
   318  func (c *jsonCodec) CreateResponse(id interface{}, reply interface{}) interface{} {
   319  	return &jsonSuccessResponse{Version: jsonrpcVersion, Id: id, Result: reply}
   320  }
   321  
   322  //CreateErrorResponse将使用给定的ID和错误创建JSON-RPC错误响应。
   323  func (c *jsonCodec) CreateErrorResponse(id interface{}, err Error) interface{} {
   324  	return &jsonErrResponse{Version: jsonrpcVersion, Id: id, Error: jsonError{Code: err.ErrorCode(), Message: err.Error()}}
   325  }
   326  
   327  //CreateErrorResponseWithInfo将使用给定的ID和错误创建JSON-RPC错误响应。
   328  //信息是可选的,包含有关错误的其他信息。当传递空字符串时,它将被忽略。
   329  func (c *jsonCodec) CreateErrorResponseWithInfo(id interface{}, err Error, info interface{}) interface{} {
   330  	return &jsonErrResponse{Version: jsonrpcVersion, Id: id,
   331  		Error: jsonError{Code: err.ErrorCode(), Message: err.Error(), Data: info}}
   332  }
   333  
   334  //createNotification将创建一个具有给定订阅ID和事件作为参数的JSON-RPC通知。
   335  func (c *jsonCodec) CreateNotification(subid, namespace string, event interface{}) interface{} {
   336  	return &jsonNotification{Version: jsonrpcVersion, Method: namespace + notificationMethodSuffix,
   337  		Params: jsonSubscription{Subscription: subid, Result: event}}
   338  }
   339  
   340  //向客户端写入消息
   341  func (c *jsonCodec) Write(res interface{}) error {
   342  	c.encMu.Lock()
   343  	defer c.encMu.Unlock()
   344  
   345  	return c.encode(res)
   346  }
   347  
   348  //关闭基础连接
   349  func (c *jsonCodec) Close() {
   350  	c.closer.Do(func() {
   351  		close(c.closed)
   352  		c.rw.Close()
   353  	})
   354  }
   355  
   356  //CLOSED返回调用CLOSE时将关闭的通道
   357  func (c *jsonCodec) Closed() <-chan interface{} {
   358  	return c.closed
   359  }
   360