github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/eth/protocol.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:39</date>
    10  //</624342636404150272>
    11  
    12  
    13  package eth
    14  
    15  import (
    16  	"fmt"
    17  	"io"
    18  	"math/big"
    19  
    20  	"github.com/ethereum/go-ethereum/common"
    21  	"github.com/ethereum/go-ethereum/core"
    22  	"github.com/ethereum/go-ethereum/core/types"
    23  	"github.com/ethereum/go-ethereum/event"
    24  	"github.com/ethereum/go-ethereum/rlp"
    25  )
    26  //用于匹配协议版本和消息的常量
    27  const (
    28  	eth62 = 62
    29  	eth63 = 63
    30  )
    31  
    32  //ProtocolName是在能力协商期间使用的协议的官方简称。
    33  var ProtocolName = "eth"
    34  
    35  //协议版本是ETH协议的支持版本(首先是主要版本)。
    36  var ProtocolVersions = []uint{eth63, eth62}
    37  
    38  //Protocollength是对应于不同协议版本的已实现消息数。
    39  var ProtocolLengths = []uint64{17, 8}
    40  
    41  const ProtocolMaxMsgSize = 10 * 1024 * 1024 //协议消息大小的最大上限
    42  
    43  //ETH协议报文代码
    44  const (
    45  //属于ETH/62的协议消息
    46  	StatusMsg          = 0x00
    47  	NewBlockHashesMsg  = 0x01
    48  	TxMsg              = 0x02
    49  	GetBlockHeadersMsg = 0x03
    50  	BlockHeadersMsg    = 0x04
    51  	GetBlockBodiesMsg  = 0x05
    52  	BlockBodiesMsg     = 0x06
    53  	NewBlockMsg        = 0x07
    54  
    55  //属于ETH/63的协议消息
    56  	GetNodeDataMsg = 0x0d
    57  	NodeDataMsg    = 0x0e
    58  	GetReceiptsMsg = 0x0f
    59  	ReceiptsMsg    = 0x10
    60  )
    61  
    62  type errCode int
    63  
    64  const (
    65  	ErrMsgTooLarge = iota
    66  	ErrDecode
    67  	ErrInvalidMsgCode
    68  	ErrProtocolVersionMismatch
    69  	ErrNetworkIdMismatch
    70  	ErrGenesisBlockMismatch
    71  	ErrNoStatusMsg
    72  	ErrExtraStatusMsg
    73  	ErrSuspendedPeer
    74  )
    75  
    76  func (e errCode) String() string {
    77  	return errorToString[int(e)]
    78  }
    79  
    80  //一旦旧代码用完,XXX就会更改
    81  var errorToString = map[int]string{
    82  	ErrMsgTooLarge:             "Message too long",
    83  	ErrDecode:                  "Invalid message",
    84  	ErrInvalidMsgCode:          "Invalid message code",
    85  	ErrProtocolVersionMismatch: "Protocol version mismatch",
    86  	ErrNetworkIdMismatch:       "NetworkId mismatch",
    87  	ErrGenesisBlockMismatch:    "Genesis block mismatch",
    88  	ErrNoStatusMsg:             "No status message",
    89  	ErrExtraStatusMsg:          "Extra status message",
    90  	ErrSuspendedPeer:           "Suspended peer",
    91  }
    92  
    93  type txPool interface {
    94  //AddRemotes应该将给定的事务添加到池中。
    95  	AddRemotes([]*types.Transaction) []error
    96  
    97  //挂起应返回挂起的事务。
    98  //该切片应由调用方可修改。
    99  	Pending() (map[common.Address]types.Transactions, error)
   100  
   101  //subscribenewtxsevent应返回的事件订阅
   102  //newtxSevent并将事件发送到给定的通道。
   103  	SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
   104  }
   105  
   106  //statusdata是状态消息的网络包。
   107  type statusData struct {
   108  	ProtocolVersion uint32
   109  	NetworkId       uint64
   110  	TD              *big.Int
   111  	CurrentBlock    common.Hash
   112  	GenesisBlock    common.Hash
   113  }
   114  
   115  //newblockhashesdata是块通知的网络包。
   116  type newBlockHashesData []struct {
   117  Hash   common.Hash //正在公布的一个特定块的哈希
   118  Number uint64      //公布的一个特定区块的编号
   119  }
   120  
   121  //GetBlockHeadersData表示块头查询。
   122  type getBlockHeadersData struct {
   123  Origin  hashOrNumber //从中检索邮件头的块
   124  Amount  uint64       //要检索的最大头数
   125  Skip    uint64       //要在连续标题之间跳过的块
   126  Reverse bool         //查询方向(假=上升到最新,真=下降到创世纪)
   127  }
   128  
   129  //hashornumber是用于指定源块的组合字段。
   130  type hashOrNumber struct {
   131  Hash   common.Hash //要从中检索头的块哈希(不包括数字)
   132  Number uint64      //要从中检索头的块哈希(不包括哈希)
   133  }
   134  
   135  //encoderlp是一个专门的编码器,用于hashornumber只对
   136  //两个包含联合字段。
   137  func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
   138  	if hn.Hash == (common.Hash{}) {
   139  		return rlp.Encode(w, hn.Number)
   140  	}
   141  	if hn.Number != 0 {
   142  		return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
   143  	}
   144  	return rlp.Encode(w, hn.Hash)
   145  }
   146  
   147  //decoderlp是一种特殊的译码器,用于hashornumber对内容进行译码。
   148  //分块散列或分块编号。
   149  func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
   150  	_, size, _ := s.Kind()
   151  	origin, err := s.Raw()
   152  	if err == nil {
   153  		switch {
   154  		case size == 32:
   155  			err = rlp.DecodeBytes(origin, &hn.Hash)
   156  		case size <= 8:
   157  			err = rlp.DecodeBytes(origin, &hn.Number)
   158  		default:
   159  			err = fmt.Errorf("invalid input size %d for origin", size)
   160  		}
   161  	}
   162  	return err
   163  }
   164  
   165  //newblockdata是块传播消息的网络包。
   166  type newBlockData struct {
   167  	Block *types.Block
   168  	TD    *big.Int
   169  }
   170  
   171  //BlockBody表示单个块的数据内容。
   172  type blockBody struct {
   173  Transactions []*types.Transaction //块中包含的事务
   174  Uncles       []*types.Header      //一个街区内的叔叔
   175  }
   176  
   177  //blockbodiesdata是用于块内容分发的网络包。
   178  type blockBodiesData []*blockBody
   179