protocol.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright 2016 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 les implements the Light Ethereum Subprotocol.
  17. package les
  18. import (
  19. "fmt"
  20. "io"
  21. "math/big"
  22. "github.com/ethereum/go-ethereum/common"
  23. "github.com/ethereum/go-ethereum/core/types"
  24. "github.com/ethereum/go-ethereum/rlp"
  25. )
  26. // Constants to match up protocol versions and messages
  27. const (
  28. lpv1 = 1
  29. )
  30. // Supported versions of the les protocol (first is primary).
  31. var ProtocolVersions = []uint{lpv1}
  32. // Number of implemented message corresponding to different protocol versions.
  33. var ProtocolLengths = []uint64{15}
  34. const (
  35. NetworkId = 1
  36. ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
  37. )
  38. // les protocol message codes
  39. const (
  40. // Protocol messages belonging to LPV1
  41. StatusMsg = 0x00
  42. AnnounceMsg = 0x01
  43. GetBlockHeadersMsg = 0x02
  44. BlockHeadersMsg = 0x03
  45. GetBlockBodiesMsg = 0x04
  46. BlockBodiesMsg = 0x05
  47. GetReceiptsMsg = 0x06
  48. ReceiptsMsg = 0x07
  49. GetProofsMsg = 0x08
  50. ProofsMsg = 0x09
  51. GetCodeMsg = 0x0a
  52. CodeMsg = 0x0b
  53. SendTxMsg = 0x0c
  54. GetHeaderProofsMsg = 0x0d
  55. HeaderProofsMsg = 0x0e
  56. )
  57. type errCode int
  58. const (
  59. ErrMsgTooLarge = iota
  60. ErrDecode
  61. ErrInvalidMsgCode
  62. ErrProtocolVersionMismatch
  63. ErrNetworkIdMismatch
  64. ErrGenesisBlockMismatch
  65. ErrNoStatusMsg
  66. ErrExtraStatusMsg
  67. ErrSuspendedPeer
  68. ErrUselessPeer
  69. ErrRequestRejected
  70. ErrUnexpectedResponse
  71. ErrInvalidResponse
  72. ErrTooManyTimeouts
  73. ErrHandshakeMissingKey
  74. )
  75. func (e errCode) String() string {
  76. return errorToString[int(e)]
  77. }
  78. // XXX change once legacy code is out
  79. var errorToString = map[int]string{
  80. ErrMsgTooLarge: "Message too long",
  81. ErrDecode: "Invalid message",
  82. ErrInvalidMsgCode: "Invalid message code",
  83. ErrProtocolVersionMismatch: "Protocol version mismatch",
  84. ErrNetworkIdMismatch: "NetworkId mismatch",
  85. ErrGenesisBlockMismatch: "Genesis block mismatch",
  86. ErrNoStatusMsg: "No status message",
  87. ErrExtraStatusMsg: "Extra status message",
  88. ErrSuspendedPeer: "Suspended peer",
  89. ErrRequestRejected: "Request rejected",
  90. ErrUnexpectedResponse: "Unexpected response",
  91. ErrInvalidResponse: "Invalid response",
  92. ErrTooManyTimeouts: "Too many request timeouts",
  93. ErrHandshakeMissingKey: "Key missing from handshake message",
  94. }
  95. type chainManager interface {
  96. GetBlockHashesFromHash(hash common.Hash, amount uint64) (hashes []common.Hash)
  97. GetBlock(hash common.Hash) (block *types.Block)
  98. Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash)
  99. }
  100. // announceData is the network packet for the block announcements.
  101. type announceData struct {
  102. Hash common.Hash // Hash of one particular block being announced
  103. Number uint64 // Number of one particular block being announced
  104. Td *big.Int // Total difficulty of one particular block being announced
  105. ReorgDepth uint64
  106. Update keyValueList
  107. haveHeaders uint64 // we have the headers of the remote peer's chain up to this number
  108. headKnown bool
  109. requested bool
  110. next *announceData
  111. }
  112. type blockInfo struct {
  113. Hash common.Hash // Hash of one particular block being announced
  114. Number uint64 // Number of one particular block being announced
  115. Td *big.Int // Total difficulty of one particular block being announced
  116. }
  117. // getBlockHashesData is the network packet for the hash based hash retrieval.
  118. type getBlockHashesData struct {
  119. Hash common.Hash
  120. Amount uint64
  121. }
  122. // getBlockHeadersData represents a block header query.
  123. type getBlockHeadersData struct {
  124. Origin hashOrNumber // Block from which to retrieve headers
  125. Amount uint64 // Maximum number of headers to retrieve
  126. Skip uint64 // Blocks to skip between consecutive headers
  127. Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis)
  128. }
  129. // hashOrNumber is a combined field for specifying an origin block.
  130. type hashOrNumber struct {
  131. Hash common.Hash // Block hash from which to retrieve headers (excludes Number)
  132. Number uint64 // Block hash from which to retrieve headers (excludes Hash)
  133. }
  134. // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the
  135. // two contained union fields.
  136. func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
  137. if hn.Hash == (common.Hash{}) {
  138. return rlp.Encode(w, hn.Number)
  139. }
  140. if hn.Number != 0 {
  141. return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
  142. }
  143. return rlp.Encode(w, hn.Hash)
  144. }
  145. // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents
  146. // into either a block hash or a block number.
  147. func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
  148. _, size, _ := s.Kind()
  149. origin, err := s.Raw()
  150. if err == nil {
  151. switch {
  152. case size == 32:
  153. err = rlp.DecodeBytes(origin, &hn.Hash)
  154. case size <= 8:
  155. err = rlp.DecodeBytes(origin, &hn.Number)
  156. default:
  157. err = fmt.Errorf("invalid input size %d for origin", size)
  158. }
  159. }
  160. return err
  161. }
  162. // newBlockData is the network packet for the block propagation message.
  163. type newBlockData struct {
  164. Block *types.Block
  165. TD *big.Int
  166. }
  167. // blockBodiesData is the network packet for block content distribution.
  168. type blockBodiesData []*types.Body
  169. // CodeData is the network response packet for a node data retrieval.
  170. type CodeData []struct {
  171. Value []byte
  172. }
  173. type proofsData [][]rlp.RawValue