protocol.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2020 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 diff
  17. import (
  18. "errors"
  19. "fmt"
  20. "golang.org/x/crypto/sha3"
  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. Diff1 = 1
  28. )
  29. // ProtocolName is the official short name of the `diff` protocol used during
  30. // devp2p capability negotiation.
  31. const ProtocolName = "diff"
  32. // ProtocolVersions are the supported versions of the `diff` protocol (first
  33. // is primary).
  34. var ProtocolVersions = []uint{Diff1}
  35. // protocolLengths are the number of implemented message corresponding to
  36. // different protocol versions.
  37. var protocolLengths = map[uint]uint64{Diff1: 4}
  38. // maxMessageSize is the maximum cap on the size of a protocol message.
  39. const maxMessageSize = 10 * 1024 * 1024
  40. const (
  41. DiffCapMsg = 0x00
  42. GetDiffLayerMsg = 0x01
  43. DiffLayerMsg = 0x02
  44. FullDiffLayerMsg = 0x03
  45. )
  46. var defaultExtra = []byte{0x00}
  47. var (
  48. errMsgTooLarge = errors.New("message too long")
  49. errDecode = errors.New("invalid message")
  50. errInvalidMsgCode = errors.New("invalid message code")
  51. errUnexpectedMsg = errors.New("unexpected message code")
  52. errNoCapMsg = errors.New("miss cap message during handshake")
  53. )
  54. // Packet represents a p2p message in the `diff` protocol.
  55. type Packet interface {
  56. Name() string // Name returns a string corresponding to the message type.
  57. Kind() byte // Kind returns the message type.
  58. }
  59. type GetDiffLayersPacket struct {
  60. RequestId uint64
  61. BlockHashes []common.Hash
  62. }
  63. func (p *DiffLayersPacket) Unpack() ([]*types.DiffLayer, error) {
  64. diffLayers := make([]*types.DiffLayer, 0, len(*p))
  65. hasher := sha3.NewLegacyKeccak256()
  66. for _, rawData := range *p {
  67. var diff types.DiffLayer
  68. err := rlp.DecodeBytes(rawData, &diff)
  69. if err != nil {
  70. return nil, fmt.Errorf("%w: diff layer %v", errDecode, err)
  71. }
  72. diffLayers = append(diffLayers, &diff)
  73. _, err = hasher.Write(rawData)
  74. if err != nil {
  75. return nil, err
  76. }
  77. var diffHash common.Hash
  78. hasher.Sum(diffHash[:0])
  79. hasher.Reset()
  80. diff.DiffHash = diffHash
  81. }
  82. return diffLayers, nil
  83. }
  84. type DiffCapPacket struct {
  85. DiffSync bool
  86. Extra rlp.RawValue // for extension
  87. }
  88. type DiffLayersPacket []rlp.RawValue
  89. type FullDiffLayersPacket struct {
  90. RequestId uint64
  91. DiffLayersPacket
  92. }
  93. func (*GetDiffLayersPacket) Name() string { return "GetDiffLayers" }
  94. func (*GetDiffLayersPacket) Kind() byte { return GetDiffLayerMsg }
  95. func (*DiffLayersPacket) Name() string { return "DiffLayers" }
  96. func (*DiffLayersPacket) Kind() byte { return DiffLayerMsg }
  97. func (*FullDiffLayersPacket) Name() string { return "FullDiffLayers" }
  98. func (*FullDiffLayersPacket) Kind() byte { return FullDiffLayerMsg }
  99. func (*DiffCapPacket) Name() string { return "DiffCap" }
  100. func (*DiffCapPacket) Kind() byte { return DiffCapMsg }