protocol.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. "errors"
  19. "fmt"
  20. "io"
  21. "math/big"
  22. "github.com/ethereum/go-ethereum/common"
  23. "github.com/ethereum/go-ethereum/core/forkid"
  24. "github.com/ethereum/go-ethereum/core/types"
  25. "github.com/ethereum/go-ethereum/rlp"
  26. )
  27. // Constants to match up protocol versions and messages
  28. const (
  29. ETH65 = 65
  30. ETH66 = 66
  31. )
  32. // ProtocolName is the official short name of the `eth` protocol used during
  33. // devp2p capability negotiation.
  34. const ProtocolName = "eth"
  35. // ProtocolVersions are the supported versions of the `eth` protocol (first
  36. // is primary).
  37. var ProtocolVersions = []uint{ETH66, ETH65}
  38. // protocolLengths are the number of implemented message corresponding to
  39. // different protocol versions.
  40. var protocolLengths = map[uint]uint64{ETH66: 17, ETH65: 17}
  41. // maxMessageSize is the maximum cap on the size of a protocol message.
  42. const maxMessageSize = 10 * 1024 * 1024
  43. const (
  44. // Protocol messages in eth/64
  45. StatusMsg = 0x00
  46. NewBlockHashesMsg = 0x01
  47. TransactionsMsg = 0x02
  48. GetBlockHeadersMsg = 0x03
  49. BlockHeadersMsg = 0x04
  50. GetBlockBodiesMsg = 0x05
  51. BlockBodiesMsg = 0x06
  52. NewBlockMsg = 0x07
  53. GetNodeDataMsg = 0x0d
  54. NodeDataMsg = 0x0e
  55. GetReceiptsMsg = 0x0f
  56. ReceiptsMsg = 0x10
  57. // Protocol messages overloaded in eth/65
  58. NewPooledTransactionHashesMsg = 0x08
  59. GetPooledTransactionsMsg = 0x09
  60. PooledTransactionsMsg = 0x0a
  61. )
  62. var (
  63. errNoStatusMsg = errors.New("no status message")
  64. errMsgTooLarge = errors.New("message too long")
  65. errDecode = errors.New("invalid message")
  66. errInvalidMsgCode = errors.New("invalid message code")
  67. errProtocolVersionMismatch = errors.New("protocol version mismatch")
  68. errNetworkIDMismatch = errors.New("network ID mismatch")
  69. errGenesisMismatch = errors.New("genesis mismatch")
  70. errForkIDRejected = errors.New("fork ID rejected")
  71. )
  72. // Packet represents a p2p message in the `eth` protocol.
  73. type Packet interface {
  74. Name() string // Name returns a string corresponding to the message type.
  75. Kind() byte // Kind returns the message type.
  76. }
  77. // StatusPacket is the network packet for the status message for eth/64 and later.
  78. type StatusPacket struct {
  79. ProtocolVersion uint32
  80. NetworkID uint64
  81. TD *big.Int
  82. Head common.Hash
  83. Genesis common.Hash
  84. ForkID forkid.ID
  85. }
  86. // NewBlockHashesPacket is the network packet for the block announcements.
  87. type NewBlockHashesPacket []struct {
  88. Hash common.Hash // Hash of one particular block being announced
  89. Number uint64 // Number of one particular block being announced
  90. }
  91. // Unpack retrieves the block hashes and numbers from the announcement packet
  92. // and returns them in a split flat format that's more consistent with the
  93. // internal data structures.
  94. func (p *NewBlockHashesPacket) Unpack() ([]common.Hash, []uint64) {
  95. var (
  96. hashes = make([]common.Hash, len(*p))
  97. numbers = make([]uint64, len(*p))
  98. )
  99. for i, body := range *p {
  100. hashes[i], numbers[i] = body.Hash, body.Number
  101. }
  102. return hashes, numbers
  103. }
  104. // TransactionsPacket is the network packet for broadcasting new transactions.
  105. type TransactionsPacket []*types.Transaction
  106. // GetBlockHeadersPacket represents a block header query.
  107. type GetBlockHeadersPacket struct {
  108. Origin HashOrNumber // Block from which to retrieve headers
  109. Amount uint64 // Maximum number of headers to retrieve
  110. Skip uint64 // Blocks to skip between consecutive headers
  111. Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis)
  112. }
  113. // GetBlockHeadersPacket represents a block header query over eth/66
  114. type GetBlockHeadersPacket66 struct {
  115. RequestId uint64
  116. *GetBlockHeadersPacket
  117. }
  118. // HashOrNumber is a combined field for specifying an origin block.
  119. type HashOrNumber struct {
  120. Hash common.Hash // Block hash from which to retrieve headers (excludes Number)
  121. Number uint64 // Block hash from which to retrieve headers (excludes Hash)
  122. }
  123. // EncodeRLP is a specialized encoder for HashOrNumber to encode only one of the
  124. // two contained union fields.
  125. func (hn *HashOrNumber) EncodeRLP(w io.Writer) error {
  126. if hn.Hash == (common.Hash{}) {
  127. return rlp.Encode(w, hn.Number)
  128. }
  129. if hn.Number != 0 {
  130. return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
  131. }
  132. return rlp.Encode(w, hn.Hash)
  133. }
  134. // DecodeRLP is a specialized decoder for HashOrNumber to decode the contents
  135. // into either a block hash or a block number.
  136. func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error {
  137. _, size, err := s.Kind()
  138. switch {
  139. case err != nil:
  140. return err
  141. case size == 32:
  142. hn.Number = 0
  143. return s.Decode(&hn.Hash)
  144. case size <= 8:
  145. hn.Hash = common.Hash{}
  146. return s.Decode(&hn.Number)
  147. default:
  148. return fmt.Errorf("invalid input size %d for origin", size)
  149. }
  150. }
  151. // BlockHeadersPacket represents a block header response.
  152. type BlockHeadersPacket []*types.Header
  153. // BlockHeadersPacket represents a block header response over eth/66.
  154. type BlockHeadersPacket66 struct {
  155. RequestId uint64
  156. BlockHeadersPacket
  157. }
  158. // NewBlockPacket is the network packet for the block propagation message.
  159. type NewBlockPacket struct {
  160. Block *types.Block
  161. TD *big.Int
  162. }
  163. // sanityCheck verifies that the values are reasonable, as a DoS protection
  164. func (request *NewBlockPacket) sanityCheck() error {
  165. if err := request.Block.SanityCheck(); err != nil {
  166. return err
  167. }
  168. //TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
  169. // larger, it will still fit within 100 bits
  170. if tdlen := request.TD.BitLen(); tdlen > 100 {
  171. return fmt.Errorf("too large block TD: bitlen %d", tdlen)
  172. }
  173. return nil
  174. }
  175. // GetBlockBodiesPacket represents a block body query.
  176. type GetBlockBodiesPacket []common.Hash
  177. // GetBlockBodiesPacket represents a block body query over eth/66.
  178. type GetBlockBodiesPacket66 struct {
  179. RequestId uint64
  180. GetBlockBodiesPacket
  181. }
  182. // BlockBodiesPacket is the network packet for block content distribution.
  183. type BlockBodiesPacket []*BlockBody
  184. // BlockBodiesPacket is the network packet for block content distribution over eth/66.
  185. type BlockBodiesPacket66 struct {
  186. RequestId uint64
  187. BlockBodiesPacket
  188. }
  189. // BlockBodiesRLPPacket is used for replying to block body requests, in cases
  190. // where we already have them RLP-encoded, and thus can avoid the decode-encode
  191. // roundtrip.
  192. type BlockBodiesRLPPacket []rlp.RawValue
  193. // BlockBodiesRLPPacket66 is the BlockBodiesRLPPacket over eth/66
  194. type BlockBodiesRLPPacket66 struct {
  195. RequestId uint64
  196. BlockBodiesRLPPacket
  197. }
  198. // BlockBody represents the data content of a single block.
  199. type BlockBody struct {
  200. Transactions []*types.Transaction // Transactions contained within a block
  201. Uncles []*types.Header // Uncles contained within a block
  202. }
  203. // Unpack retrieves the transactions and uncles from the range packet and returns
  204. // them in a split flat format that's more consistent with the internal data structures.
  205. func (p *BlockBodiesPacket) Unpack() ([][]*types.Transaction, [][]*types.Header) {
  206. var (
  207. txset = make([][]*types.Transaction, len(*p))
  208. uncleset = make([][]*types.Header, len(*p))
  209. )
  210. for i, body := range *p {
  211. txset[i], uncleset[i] = body.Transactions, body.Uncles
  212. }
  213. return txset, uncleset
  214. }
  215. // GetNodeDataPacket represents a trie node data query.
  216. type GetNodeDataPacket []common.Hash
  217. // GetNodeDataPacket represents a trie node data query over eth/66.
  218. type GetNodeDataPacket66 struct {
  219. RequestId uint64
  220. GetNodeDataPacket
  221. }
  222. // NodeDataPacket is the network packet for trie node data distribution.
  223. type NodeDataPacket [][]byte
  224. // NodeDataPacket is the network packet for trie node data distribution over eth/66.
  225. type NodeDataPacket66 struct {
  226. RequestId uint64
  227. NodeDataPacket
  228. }
  229. // GetReceiptsPacket represents a block receipts query.
  230. type GetReceiptsPacket []common.Hash
  231. // GetReceiptsPacket represents a block receipts query over eth/66.
  232. type GetReceiptsPacket66 struct {
  233. RequestId uint64
  234. GetReceiptsPacket
  235. }
  236. // ReceiptsPacket is the network packet for block receipts distribution.
  237. type ReceiptsPacket [][]*types.Receipt
  238. // ReceiptsPacket is the network packet for block receipts distribution over eth/66.
  239. type ReceiptsPacket66 struct {
  240. RequestId uint64
  241. ReceiptsPacket
  242. }
  243. // ReceiptsRLPPacket is used for receipts, when we already have it encoded
  244. type ReceiptsRLPPacket []rlp.RawValue
  245. // ReceiptsPacket66 is the eth-66 version of ReceiptsRLPPacket
  246. type ReceiptsRLPPacket66 struct {
  247. RequestId uint64
  248. ReceiptsRLPPacket
  249. }
  250. // NewPooledTransactionHashesPacket represents a transaction announcement packet.
  251. type NewPooledTransactionHashesPacket []common.Hash
  252. // GetPooledTransactionsPacket represents a transaction query.
  253. type GetPooledTransactionsPacket []common.Hash
  254. type GetPooledTransactionsPacket66 struct {
  255. RequestId uint64
  256. GetPooledTransactionsPacket
  257. }
  258. // PooledTransactionsPacket is the network packet for transaction distribution.
  259. type PooledTransactionsPacket []*types.Transaction
  260. // PooledTransactionsPacket is the network packet for transaction distribution over eth/66.
  261. type PooledTransactionsPacket66 struct {
  262. RequestId uint64
  263. PooledTransactionsPacket
  264. }
  265. // PooledTransactionsPacket is the network packet for transaction distribution, used
  266. // in the cases we already have them in rlp-encoded form
  267. type PooledTransactionsRLPPacket []rlp.RawValue
  268. // PooledTransactionsRLPPacket66 is the eth/66 form of PooledTransactionsRLPPacket
  269. type PooledTransactionsRLPPacket66 struct {
  270. RequestId uint64
  271. PooledTransactionsRLPPacket
  272. }
  273. func (*StatusPacket) Name() string { return "Status" }
  274. func (*StatusPacket) Kind() byte { return StatusMsg }
  275. func (*NewBlockHashesPacket) Name() string { return "NewBlockHashes" }
  276. func (*NewBlockHashesPacket) Kind() byte { return NewBlockHashesMsg }
  277. func (*TransactionsPacket) Name() string { return "Transactions" }
  278. func (*TransactionsPacket) Kind() byte { return TransactionsMsg }
  279. func (*GetBlockHeadersPacket) Name() string { return "GetBlockHeaders" }
  280. func (*GetBlockHeadersPacket) Kind() byte { return GetBlockHeadersMsg }
  281. func (*BlockHeadersPacket) Name() string { return "BlockHeaders" }
  282. func (*BlockHeadersPacket) Kind() byte { return BlockHeadersMsg }
  283. func (*GetBlockBodiesPacket) Name() string { return "GetBlockBodies" }
  284. func (*GetBlockBodiesPacket) Kind() byte { return GetBlockBodiesMsg }
  285. func (*BlockBodiesPacket) Name() string { return "BlockBodies" }
  286. func (*BlockBodiesPacket) Kind() byte { return BlockBodiesMsg }
  287. func (*NewBlockPacket) Name() string { return "NewBlock" }
  288. func (*NewBlockPacket) Kind() byte { return NewBlockMsg }
  289. func (*GetNodeDataPacket) Name() string { return "GetNodeData" }
  290. func (*GetNodeDataPacket) Kind() byte { return GetNodeDataMsg }
  291. func (*NodeDataPacket) Name() string { return "NodeData" }
  292. func (*NodeDataPacket) Kind() byte { return NodeDataMsg }
  293. func (*GetReceiptsPacket) Name() string { return "GetReceipts" }
  294. func (*GetReceiptsPacket) Kind() byte { return GetReceiptsMsg }
  295. func (*ReceiptsPacket) Name() string { return "Receipts" }
  296. func (*ReceiptsPacket) Kind() byte { return ReceiptsMsg }
  297. func (*NewPooledTransactionHashesPacket) Name() string { return "NewPooledTransactionHashes" }
  298. func (*NewPooledTransactionHashesPacket) Kind() byte { return NewPooledTransactionHashesMsg }
  299. func (*GetPooledTransactionsPacket) Name() string { return "GetPooledTransactions" }
  300. func (*GetPooledTransactionsPacket) Kind() byte { return GetPooledTransactionsMsg }
  301. func (*PooledTransactionsPacket) Name() string { return "PooledTransactions" }
  302. func (*PooledTransactionsPacket) Kind() byte { return PooledTransactionsMsg }