github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/eth/protocol.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2014 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package eth
    26  
    27  import (
    28  	"fmt"
    29  	"io"
    30  	"math/big"
    31  
    32  	"github.com/ethereum/go-ethereum/common"
    33  	"github.com/ethereum/go-ethereum/core"
    34  	"github.com/ethereum/go-ethereum/core/types"
    35  	"github.com/ethereum/go-ethereum/event"
    36  	"github.com/ethereum/go-ethereum/rlp"
    37  )
    38  //用于匹配协议版本和消息的常量
    39  const (
    40  	eth62 = 62
    41  	eth63 = 63
    42  )
    43  
    44  //ProtocolName是在能力协商期间使用的协议的官方简称。
    45  var ProtocolName = "eth"
    46  
    47  //协议版本是ETH协议的支持版本(首先是主要版本)。
    48  var ProtocolVersions = []uint{eth63, eth62}
    49  
    50  //Protocollength是对应于不同协议版本的已实现消息数。
    51  var ProtocolLengths = []uint64{17, 8}
    52  
    53  const ProtocolMaxMsgSize = 10 * 1024 * 1024 //协议消息大小的最大上限
    54  
    55  //ETH协议报文代码
    56  const (
    57  //属于ETH/62的协议消息
    58  	StatusMsg          = 0x00
    59  	NewBlockHashesMsg  = 0x01
    60  	TxMsg              = 0x02
    61  	GetBlockHeadersMsg = 0x03
    62  	BlockHeadersMsg    = 0x04
    63  	GetBlockBodiesMsg  = 0x05
    64  	BlockBodiesMsg     = 0x06
    65  	NewBlockMsg        = 0x07
    66  
    67  //属于ETH/63的协议消息
    68  	GetNodeDataMsg = 0x0d
    69  	NodeDataMsg    = 0x0e
    70  	GetReceiptsMsg = 0x0f
    71  	ReceiptsMsg    = 0x10
    72  )
    73  
    74  type errCode int
    75  
    76  const (
    77  	ErrMsgTooLarge = iota
    78  	ErrDecode
    79  	ErrInvalidMsgCode
    80  	ErrProtocolVersionMismatch
    81  	ErrNetworkIdMismatch
    82  	ErrGenesisBlockMismatch
    83  	ErrNoStatusMsg
    84  	ErrExtraStatusMsg
    85  	ErrSuspendedPeer
    86  )
    87  
    88  func (e errCode) String() string {
    89  	return errorToString[int(e)]
    90  }
    91  
    92  //一旦旧代码用完,XXX就会更改
    93  var errorToString = map[int]string{
    94  	ErrMsgTooLarge:             "Message too long",
    95  	ErrDecode:                  "Invalid message",
    96  	ErrInvalidMsgCode:          "Invalid message code",
    97  	ErrProtocolVersionMismatch: "Protocol version mismatch",
    98  	ErrNetworkIdMismatch:       "NetworkId mismatch",
    99  	ErrGenesisBlockMismatch:    "Genesis block mismatch",
   100  	ErrNoStatusMsg:             "No status message",
   101  	ErrExtraStatusMsg:          "Extra status message",
   102  	ErrSuspendedPeer:           "Suspended peer",
   103  }
   104  
   105  type txPool interface {
   106  //AddRemotes应该将给定的事务添加到池中。
   107  	AddRemotes([]*types.Transaction) []error
   108  
   109  //挂起应返回挂起的事务。
   110  //该切片应由调用方可修改。
   111  	Pending() (map[common.Address]types.Transactions, error)
   112  
   113  //subscribenewtxsevent应返回的事件订阅
   114  //newtxSevent并将事件发送到给定的通道。
   115  	SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
   116  }
   117  
   118  //statusdata是状态消息的网络包。
   119  type statusData struct {
   120  	ProtocolVersion uint32
   121  	NetworkId       uint64
   122  	TD              *big.Int
   123  	CurrentBlock    common.Hash
   124  	GenesisBlock    common.Hash
   125  }
   126  
   127  //newblockhashesdata是块通知的网络包。
   128  type newBlockHashesData []struct {
   129  Hash   common.Hash //正在公布的一个特定块的哈希
   130  Number uint64      //公布的一个特定区块的编号
   131  }
   132  
   133  //GetBlockHeadersData表示块头查询。
   134  type getBlockHeadersData struct {
   135  Origin  hashOrNumber //从中检索邮件头的块
   136  Amount  uint64       //要检索的最大头数
   137  Skip    uint64       //要在连续标题之间跳过的块
   138  Reverse bool         //查询方向(假=上升到最新,真=下降到创世纪)
   139  }
   140  
   141  //hashornumber是用于指定源块的组合字段。
   142  type hashOrNumber struct {
   143  Hash   common.Hash //要从中检索头的块哈希(不包括数字)
   144  Number uint64      //要从中检索头的块哈希(不包括哈希)
   145  }
   146  
   147  //encoderlp是一个专门的编码器,用于hashornumber只对
   148  //两个包含联合字段。
   149  func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
   150  	if hn.Hash == (common.Hash{}) {
   151  		return rlp.Encode(w, hn.Number)
   152  	}
   153  	if hn.Number != 0 {
   154  		return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
   155  	}
   156  	return rlp.Encode(w, hn.Hash)
   157  }
   158  
   159  //decoderlp是一种特殊的译码器,用于hashornumber对内容进行译码。
   160  //分块散列或分块编号。
   161  func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
   162  	_, size, _ := s.Kind()
   163  	origin, err := s.Raw()
   164  	if err == nil {
   165  		switch {
   166  		case size == 32:
   167  			err = rlp.DecodeBytes(origin, &hn.Hash)
   168  		case size <= 8:
   169  			err = rlp.DecodeBytes(origin, &hn.Number)
   170  		default:
   171  			err = fmt.Errorf("invalid input size %d for origin", size)
   172  		}
   173  	}
   174  	return err
   175  }
   176  
   177  //newblockdata是块传播消息的网络包。
   178  type newBlockData struct {
   179  	Block *types.Block
   180  	TD    *big.Int
   181  }
   182  
   183  //BlockBody表示单个块的数据内容。
   184  type blockBody struct {
   185  Transactions []*types.Transaction //块中包含的事务
   186  Uncles       []*types.Header      //一个街区内的叔叔
   187  }
   188  
   189  //blockbodiesdata是用于块内容分发的网络包。
   190  type blockBodiesData []*blockBody