protocol.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. "bytes"
  20. "crypto/ecdsa"
  21. "crypto/elliptic"
  22. "errors"
  23. "fmt"
  24. "io"
  25. "math/big"
  26. "github.com/ethereum/go-ethereum/common"
  27. "github.com/ethereum/go-ethereum/core"
  28. "github.com/ethereum/go-ethereum/core/rawdb"
  29. "github.com/ethereum/go-ethereum/crypto"
  30. "github.com/ethereum/go-ethereum/crypto/secp256k1"
  31. "github.com/ethereum/go-ethereum/rlp"
  32. )
  33. // Constants to match up protocol versions and messages
  34. const (
  35. lpv1 = 1
  36. lpv2 = 2
  37. )
  38. // Supported versions of the les protocol (first is primary)
  39. var (
  40. ClientProtocolVersions = []uint{lpv2, lpv1}
  41. ServerProtocolVersions = []uint{lpv2, lpv1}
  42. AdvertiseProtocolVersions = []uint{lpv2} // clients are searching for the first advertised protocol in the list
  43. )
  44. // Number of implemented message corresponding to different protocol versions.
  45. var ProtocolLengths = map[uint]uint64{lpv1: 15, lpv2: 22}
  46. const (
  47. NetworkId = 1
  48. ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
  49. )
  50. // les protocol message codes
  51. const (
  52. // Protocol messages belonging to LPV1
  53. StatusMsg = 0x00
  54. AnnounceMsg = 0x01
  55. GetBlockHeadersMsg = 0x02
  56. BlockHeadersMsg = 0x03
  57. GetBlockBodiesMsg = 0x04
  58. BlockBodiesMsg = 0x05
  59. GetReceiptsMsg = 0x06
  60. ReceiptsMsg = 0x07
  61. GetProofsV1Msg = 0x08
  62. ProofsV1Msg = 0x09
  63. GetCodeMsg = 0x0a
  64. CodeMsg = 0x0b
  65. SendTxMsg = 0x0c
  66. GetHeaderProofsMsg = 0x0d
  67. HeaderProofsMsg = 0x0e
  68. // Protocol messages belonging to LPV2
  69. GetProofsV2Msg = 0x0f
  70. ProofsV2Msg = 0x10
  71. GetHelperTrieProofsMsg = 0x11
  72. HelperTrieProofsMsg = 0x12
  73. SendTxV2Msg = 0x13
  74. GetTxStatusMsg = 0x14
  75. TxStatusMsg = 0x15
  76. )
  77. type errCode int
  78. const (
  79. ErrMsgTooLarge = iota
  80. ErrDecode
  81. ErrInvalidMsgCode
  82. ErrProtocolVersionMismatch
  83. ErrNetworkIdMismatch
  84. ErrGenesisBlockMismatch
  85. ErrNoStatusMsg
  86. ErrExtraStatusMsg
  87. ErrSuspendedPeer
  88. ErrUselessPeer
  89. ErrRequestRejected
  90. ErrUnexpectedResponse
  91. ErrInvalidResponse
  92. ErrTooManyTimeouts
  93. ErrMissingKey
  94. )
  95. func (e errCode) String() string {
  96. return errorToString[int(e)]
  97. }
  98. // XXX change once legacy code is out
  99. var errorToString = map[int]string{
  100. ErrMsgTooLarge: "Message too long",
  101. ErrDecode: "Invalid message",
  102. ErrInvalidMsgCode: "Invalid message code",
  103. ErrProtocolVersionMismatch: "Protocol version mismatch",
  104. ErrNetworkIdMismatch: "NetworkId mismatch",
  105. ErrGenesisBlockMismatch: "Genesis block mismatch",
  106. ErrNoStatusMsg: "No status message",
  107. ErrExtraStatusMsg: "Extra status message",
  108. ErrSuspendedPeer: "Suspended peer",
  109. ErrRequestRejected: "Request rejected",
  110. ErrUnexpectedResponse: "Unexpected response",
  111. ErrInvalidResponse: "Invalid response",
  112. ErrTooManyTimeouts: "Too many request timeouts",
  113. ErrMissingKey: "Key missing from list",
  114. }
  115. type announceBlock struct {
  116. Hash common.Hash // Hash of one particular block being announced
  117. Number uint64 // Number of one particular block being announced
  118. Td *big.Int // Total difficulty of one particular block being announced
  119. }
  120. // announceData is the network packet for the block announcements.
  121. type announceData struct {
  122. Hash common.Hash // Hash of one particular block being announced
  123. Number uint64 // Number of one particular block being announced
  124. Td *big.Int // Total difficulty of one particular block being announced
  125. ReorgDepth uint64
  126. Update keyValueList
  127. }
  128. // sign adds a signature to the block announcement by the given privKey
  129. func (a *announceData) sign(privKey *ecdsa.PrivateKey) {
  130. rlp, _ := rlp.EncodeToBytes(announceBlock{a.Hash, a.Number, a.Td})
  131. sig, _ := crypto.Sign(crypto.Keccak256(rlp), privKey)
  132. a.Update = a.Update.add("sign", sig)
  133. }
  134. // checkSignature verifies if the block announcement has a valid signature by the given pubKey
  135. func (a *announceData) checkSignature(pubKey *ecdsa.PublicKey) error {
  136. var sig []byte
  137. if err := a.Update.decode().get("sign", &sig); err != nil {
  138. return err
  139. }
  140. rlp, _ := rlp.EncodeToBytes(announceBlock{a.Hash, a.Number, a.Td})
  141. recPubkey, err := secp256k1.RecoverPubkey(crypto.Keccak256(rlp), sig)
  142. if err != nil {
  143. return err
  144. }
  145. pbytes := elliptic.Marshal(pubKey.Curve, pubKey.X, pubKey.Y)
  146. if bytes.Equal(pbytes, recPubkey) {
  147. return nil
  148. }
  149. return errors.New("Wrong signature")
  150. }
  151. type blockInfo struct {
  152. Hash common.Hash // Hash of one particular block being announced
  153. Number uint64 // Number of one particular block being announced
  154. Td *big.Int // Total difficulty of one particular block being announced
  155. }
  156. // getBlockHeadersData represents a block header query.
  157. type getBlockHeadersData struct {
  158. Origin hashOrNumber // Block from which to retrieve headers
  159. Amount uint64 // Maximum number of headers to retrieve
  160. Skip uint64 // Blocks to skip between consecutive headers
  161. Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis)
  162. }
  163. // hashOrNumber is a combined field for specifying an origin block.
  164. type hashOrNumber struct {
  165. Hash common.Hash // Block hash from which to retrieve headers (excludes Number)
  166. Number uint64 // Block hash from which to retrieve headers (excludes Hash)
  167. }
  168. // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the
  169. // two contained union fields.
  170. func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
  171. if hn.Hash == (common.Hash{}) {
  172. return rlp.Encode(w, hn.Number)
  173. }
  174. if hn.Number != 0 {
  175. return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
  176. }
  177. return rlp.Encode(w, hn.Hash)
  178. }
  179. // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents
  180. // into either a block hash or a block number.
  181. func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
  182. _, size, _ := s.Kind()
  183. origin, err := s.Raw()
  184. if err == nil {
  185. switch {
  186. case size == 32:
  187. err = rlp.DecodeBytes(origin, &hn.Hash)
  188. case size <= 8:
  189. err = rlp.DecodeBytes(origin, &hn.Number)
  190. default:
  191. err = fmt.Errorf("invalid input size %d for origin", size)
  192. }
  193. }
  194. return err
  195. }
  196. // CodeData is the network response packet for a node data retrieval.
  197. type CodeData []struct {
  198. Value []byte
  199. }
  200. type proofsData [][]rlp.RawValue
  201. type txStatus struct {
  202. Status core.TxStatus
  203. Lookup *rawdb.TxLookupEntry `rlp:"nil"`
  204. Error string
  205. }