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