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