protocol.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright 2014 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package eth
  17. import (
  18. "fmt"
  19. "io"
  20. "math/big"
  21. "github.com/ethereum/go-ethereum/common"
  22. "github.com/ethereum/go-ethereum/core/types"
  23. "github.com/ethereum/go-ethereum/rlp"
  24. )
  25. // Constants to match up protocol versions and messages
  26. const (
  27. eth61 = 61
  28. eth62 = 62
  29. eth63 = 63
  30. eth64 = 64
  31. )
  32. // Supported versions of the eth protocol (first is primary).
  33. var ProtocolVersions = []uint{eth64, eth63, eth62, eth61}
  34. // Number of implemented message corresponding to different protocol versions.
  35. var ProtocolLengths = []uint64{15, 12, 8, 9}
  36. const (
  37. NetworkId = 1
  38. ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
  39. )
  40. // eth protocol message codes
  41. const (
  42. // Protocol messages belonging to eth/61
  43. StatusMsg = 0x00
  44. NewBlockHashesMsg = 0x01
  45. TxMsg = 0x02
  46. GetBlockHashesMsg = 0x03
  47. BlockHashesMsg = 0x04
  48. GetBlocksMsg = 0x05
  49. BlocksMsg = 0x06
  50. NewBlockMsg = 0x07
  51. GetBlockHashesFromNumberMsg = 0x08
  52. // Protocol messages belonging to eth/62 (new protocol from scratch)
  53. // StatusMsg = 0x00 (uncomment after eth/61 deprecation)
  54. // NewBlockHashesMsg = 0x01 (uncomment after eth/61 deprecation)
  55. // TxMsg = 0x02 (uncomment after eth/61 deprecation)
  56. GetBlockHeadersMsg = 0x03
  57. BlockHeadersMsg = 0x04
  58. GetBlockBodiesMsg = 0x05
  59. BlockBodiesMsg = 0x06
  60. // NewBlockMsg = 0x07 (uncomment after eth/61 deprecation)
  61. // Protocol messages belonging to eth/63
  62. GetNodeDataMsg = 0x0d
  63. NodeDataMsg = 0x0e
  64. GetReceiptsMsg = 0x0f
  65. ReceiptsMsg = 0x10
  66. // Protocol messages belonging to eth/64
  67. GetAcctProofMsg = 0x11
  68. GetStorageDataProof = 0x12
  69. Proof = 0x13
  70. )
  71. type errCode int
  72. const (
  73. ErrMsgTooLarge = iota
  74. ErrDecode
  75. ErrInvalidMsgCode
  76. ErrProtocolVersionMismatch
  77. ErrNetworkIdMismatch
  78. ErrGenesisBlockMismatch
  79. ErrNoStatusMsg
  80. ErrExtraStatusMsg
  81. ErrSuspendedPeer
  82. )
  83. func (e errCode) String() string {
  84. return errorToString[int(e)]
  85. }
  86. // XXX change once legacy code is out
  87. var errorToString = map[int]string{
  88. ErrMsgTooLarge: "Message too long",
  89. ErrDecode: "Invalid message",
  90. ErrInvalidMsgCode: "Invalid message code",
  91. ErrProtocolVersionMismatch: "Protocol version mismatch",
  92. ErrNetworkIdMismatch: "NetworkId mismatch",
  93. ErrGenesisBlockMismatch: "Genesis block mismatch",
  94. ErrNoStatusMsg: "No status message",
  95. ErrExtraStatusMsg: "Extra status message",
  96. ErrSuspendedPeer: "Suspended peer",
  97. }
  98. type txPool interface {
  99. // AddTransactions should add the given transactions to the pool.
  100. AddTransactions([]*types.Transaction)
  101. // GetTransactions should return pending transactions.
  102. // The slice should be modifiable by the caller.
  103. GetTransactions() types.Transactions
  104. }
  105. type chainManager interface {
  106. GetBlockHashesFromHash(hash common.Hash, amount uint64) (hashes []common.Hash)
  107. GetBlock(hash common.Hash) (block *types.Block)
  108. Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash)
  109. }
  110. // statusData is the network packet for the status message.
  111. type statusData struct {
  112. ProtocolVersion uint32
  113. NetworkId uint32
  114. TD *big.Int
  115. CurrentBlock common.Hash
  116. GenesisBlock common.Hash
  117. }
  118. // newBlockHashesData is the network packet for the block announcements.
  119. type newBlockHashesData []struct {
  120. Hash common.Hash // Hash of one particular block being announced
  121. Number uint64 // Number of one particular block being announced
  122. }
  123. // getBlockHashesData is the network packet for the hash based hash retrieval.
  124. type getBlockHashesData struct {
  125. Hash common.Hash
  126. Amount uint64
  127. }
  128. // getBlockHashesFromNumberData is the network packet for the number based hash
  129. // retrieval.
  130. type getBlockHashesFromNumberData struct {
  131. Number uint64
  132. Amount uint64
  133. }
  134. // getBlockHeadersData represents a block header query.
  135. type getBlockHeadersData struct {
  136. Origin hashOrNumber // Block from which to retrieve headers
  137. Amount uint64 // Maximum number of headers to retrieve
  138. Skip uint64 // Blocks to skip between consecutive headers
  139. Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis)
  140. }
  141. // hashOrNumber is a combined field for specifying an origin block.
  142. type hashOrNumber struct {
  143. Hash common.Hash // Block hash from which to retrieve headers (excludes Number)
  144. Number uint64 // Block hash from which to retrieve headers (excludes Hash)
  145. }
  146. // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the
  147. // two contained union fields.
  148. func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
  149. if hn.Hash == (common.Hash{}) {
  150. return rlp.Encode(w, hn.Number)
  151. }
  152. if hn.Number != 0 {
  153. return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
  154. }
  155. return rlp.Encode(w, hn.Hash)
  156. }
  157. // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents
  158. // into either a block hash or a block number.
  159. func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
  160. _, size, _ := s.Kind()
  161. origin, err := s.Raw()
  162. if err == nil {
  163. switch {
  164. case size == 32:
  165. err = rlp.DecodeBytes(origin, &hn.Hash)
  166. case size <= 8:
  167. err = rlp.DecodeBytes(origin, &hn.Number)
  168. default:
  169. err = fmt.Errorf("invalid input size %d for origin", size)
  170. }
  171. }
  172. return err
  173. }
  174. // newBlockData is the network packet for the block propagation message.
  175. type newBlockData struct {
  176. Block *types.Block
  177. TD *big.Int
  178. }
  179. // blockBody represents the data content of a single block.
  180. type blockBody struct {
  181. Transactions []*types.Transaction // Transactions contained within a block
  182. Uncles []*types.Header // Uncles contained within a block
  183. }
  184. // blockBodiesData is the network packet for block content distribution.
  185. type blockBodiesData []*blockBody
  186. // nodeDataData is the network response packet for a node data retrieval.
  187. type nodeDataData []struct {
  188. Value []byte
  189. }