You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.0 KiB

  1. package statesync
  2. import (
  3. "errors"
  4. "fmt"
  5. amino "github.com/tendermint/go-amino"
  6. "github.com/tendermint/tendermint/types"
  7. )
  8. const (
  9. // snapshotMsgSize is the maximum size of a snapshotResponseMessage
  10. snapshotMsgSize = int(4e6)
  11. // chunkMsgSize is the maximum size of a chunkResponseMessage
  12. chunkMsgSize = int(16e6)
  13. // maxMsgSize is the maximum size of any message
  14. maxMsgSize = chunkMsgSize
  15. )
  16. var cdc = amino.NewCodec()
  17. func init() {
  18. cdc.RegisterInterface((*Message)(nil), nil)
  19. cdc.RegisterConcrete(&snapshotsRequestMessage{}, "tendermint/SnapshotsRequestMessage", nil)
  20. cdc.RegisterConcrete(&snapshotsResponseMessage{}, "tendermint/SnapshotsResponseMessage", nil)
  21. cdc.RegisterConcrete(&chunkRequestMessage{}, "tendermint/ChunkRequestMessage", nil)
  22. cdc.RegisterConcrete(&chunkResponseMessage{}, "tendermint/ChunkResponseMessage", nil)
  23. types.RegisterBlockAmino(cdc)
  24. }
  25. // decodeMsg decodes a message.
  26. func decodeMsg(bz []byte) (Message, error) {
  27. if len(bz) > maxMsgSize {
  28. return nil, fmt.Errorf("msg exceeds max size (%d > %d)", len(bz), maxMsgSize)
  29. }
  30. var msg Message
  31. err := cdc.UnmarshalBinaryBare(bz, &msg)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return msg, nil
  36. }
  37. // Message is a message sent and received by the reactor.
  38. type Message interface {
  39. ValidateBasic() error
  40. }
  41. // snapshotsRequestMessage requests recent snapshots from a peer.
  42. type snapshotsRequestMessage struct{}
  43. // ValidateBasic implements Message.
  44. func (m *snapshotsRequestMessage) ValidateBasic() error {
  45. if m == nil {
  46. return errors.New("nil message")
  47. }
  48. return nil
  49. }
  50. // SnapshotResponseMessage contains information about a single snapshot.
  51. type snapshotsResponseMessage struct {
  52. Height uint64
  53. Format uint32
  54. Chunks uint32
  55. Hash []byte
  56. Metadata []byte
  57. }
  58. // ValidateBasic implements Message.
  59. func (m *snapshotsResponseMessage) ValidateBasic() error {
  60. if m == nil {
  61. return errors.New("nil message")
  62. }
  63. if m.Height == 0 {
  64. return errors.New("height cannot be 0")
  65. }
  66. if len(m.Hash) == 0 {
  67. return errors.New("snapshot has no hash")
  68. }
  69. if m.Chunks == 0 {
  70. return errors.New("snapshot has no chunks")
  71. }
  72. return nil
  73. }
  74. // chunkRequestMessage requests a single chunk from a peer.
  75. type chunkRequestMessage struct {
  76. Height uint64
  77. Format uint32
  78. Index uint32
  79. }
  80. // ValidateBasic implements Message.
  81. func (m *chunkRequestMessage) ValidateBasic() error {
  82. if m == nil {
  83. return errors.New("nil message")
  84. }
  85. if m.Height == 0 {
  86. return errors.New("height cannot be 0")
  87. }
  88. return nil
  89. }
  90. // chunkResponseMessage contains a single chunk from a peer.
  91. type chunkResponseMessage struct {
  92. Height uint64
  93. Format uint32
  94. Index uint32
  95. Chunk []byte
  96. Missing bool
  97. }
  98. // ValidateBasic implements Message.
  99. func (m *chunkResponseMessage) ValidateBasic() error {
  100. if m == nil {
  101. return errors.New("nil message")
  102. }
  103. if m.Height == 0 {
  104. return errors.New("height cannot be 0")
  105. }
  106. if m.Missing && len(m.Chunk) > 0 {
  107. return errors.New("missing chunk cannot have contents")
  108. }
  109. if !m.Missing && m.Chunk == nil {
  110. return errors.New("chunk cannot be nil")
  111. }
  112. return nil
  113. }