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.

298 lines
6.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "sync"
  7. "github.com/pkg/errors"
  8. "github.com/tendermint/tendermint/crypto/merkle"
  9. "github.com/tendermint/tendermint/libs/bits"
  10. tmbytes "github.com/tendermint/tendermint/libs/bytes"
  11. tmmath "github.com/tendermint/tendermint/libs/math"
  12. )
  13. var (
  14. ErrPartSetUnexpectedIndex = errors.New("error part set unexpected index")
  15. ErrPartSetInvalidProof = errors.New("error part set invalid proof")
  16. )
  17. type Part struct {
  18. Index int `json:"index"`
  19. Bytes tmbytes.HexBytes `json:"bytes"`
  20. Proof merkle.SimpleProof `json:"proof"`
  21. }
  22. // ValidateBasic performs basic validation.
  23. func (part *Part) ValidateBasic() error {
  24. if part.Index < 0 {
  25. return errors.New("negative Index")
  26. }
  27. if len(part.Bytes) > BlockPartSizeBytes {
  28. return errors.Errorf("too big: %d bytes, max: %d", len(part.Bytes), BlockPartSizeBytes)
  29. }
  30. if err := part.Proof.ValidateBasic(); err != nil {
  31. return errors.Wrap(err, "wrong Proof")
  32. }
  33. return nil
  34. }
  35. func (part *Part) String() string {
  36. return part.StringIndented("")
  37. }
  38. func (part *Part) StringIndented(indent string) string {
  39. return fmt.Sprintf(`Part{#%v
  40. %s Bytes: %X...
  41. %s Proof: %v
  42. %s}`,
  43. part.Index,
  44. indent, tmbytes.Fingerprint(part.Bytes),
  45. indent, part.Proof.StringIndented(indent+" "),
  46. indent)
  47. }
  48. //-------------------------------------
  49. type PartSetHeader struct {
  50. Total int `json:"total"`
  51. Hash tmbytes.HexBytes `json:"hash"`
  52. }
  53. func (psh PartSetHeader) String() string {
  54. return fmt.Sprintf("%v:%X", psh.Total, tmbytes.Fingerprint(psh.Hash))
  55. }
  56. func (psh PartSetHeader) IsZero() bool {
  57. return psh.Total == 0 && len(psh.Hash) == 0
  58. }
  59. func (psh PartSetHeader) Equals(other PartSetHeader) bool {
  60. return psh.Total == other.Total && bytes.Equal(psh.Hash, other.Hash)
  61. }
  62. // ValidateBasic performs basic validation.
  63. func (psh PartSetHeader) ValidateBasic() error {
  64. if psh.Total < 0 {
  65. return errors.New("negative Total")
  66. }
  67. // Hash can be empty in case of POLBlockID.PartsHeader in Proposal.
  68. if err := ValidateHash(psh.Hash); err != nil {
  69. return errors.Wrap(err, "Wrong Hash")
  70. }
  71. return nil
  72. }
  73. //-------------------------------------
  74. type PartSet struct {
  75. total int
  76. hash []byte
  77. mtx sync.Mutex
  78. parts []*Part
  79. partsBitArray *bits.BitArray
  80. count int
  81. }
  82. // Returns an immutable, full PartSet from the data bytes.
  83. // The data bytes are split into "partSize" chunks, and merkle tree computed.
  84. func NewPartSetFromData(data []byte, partSize int) *PartSet {
  85. // divide data into 4kb parts.
  86. total := (len(data) + partSize - 1) / partSize
  87. parts := make([]*Part, total)
  88. partsBytes := make([][]byte, total)
  89. partsBitArray := bits.NewBitArray(total)
  90. for i := 0; i < total; i++ {
  91. part := &Part{
  92. Index: i,
  93. Bytes: data[i*partSize : tmmath.MinInt(len(data), (i+1)*partSize)],
  94. }
  95. parts[i] = part
  96. partsBytes[i] = part.Bytes
  97. partsBitArray.SetIndex(i, true)
  98. }
  99. // Compute merkle proofs
  100. root, proofs := merkle.SimpleProofsFromByteSlices(partsBytes)
  101. for i := 0; i < total; i++ {
  102. parts[i].Proof = *proofs[i]
  103. }
  104. return &PartSet{
  105. total: total,
  106. hash: root,
  107. parts: parts,
  108. partsBitArray: partsBitArray,
  109. count: total,
  110. }
  111. }
  112. // Returns an empty PartSet ready to be populated.
  113. func NewPartSetFromHeader(header PartSetHeader) *PartSet {
  114. return &PartSet{
  115. total: header.Total,
  116. hash: header.Hash,
  117. parts: make([]*Part, header.Total),
  118. partsBitArray: bits.NewBitArray(header.Total),
  119. count: 0,
  120. }
  121. }
  122. func (ps *PartSet) Header() PartSetHeader {
  123. if ps == nil {
  124. return PartSetHeader{}
  125. }
  126. return PartSetHeader{
  127. Total: ps.total,
  128. Hash: ps.hash,
  129. }
  130. }
  131. func (ps *PartSet) HasHeader(header PartSetHeader) bool {
  132. if ps == nil {
  133. return false
  134. }
  135. return ps.Header().Equals(header)
  136. }
  137. func (ps *PartSet) BitArray() *bits.BitArray {
  138. ps.mtx.Lock()
  139. defer ps.mtx.Unlock()
  140. return ps.partsBitArray.Copy()
  141. }
  142. func (ps *PartSet) Hash() []byte {
  143. if ps == nil {
  144. return nil
  145. }
  146. return ps.hash
  147. }
  148. func (ps *PartSet) HashesTo(hash []byte) bool {
  149. if ps == nil {
  150. return false
  151. }
  152. return bytes.Equal(ps.hash, hash)
  153. }
  154. func (ps *PartSet) Count() int {
  155. if ps == nil {
  156. return 0
  157. }
  158. return ps.count
  159. }
  160. func (ps *PartSet) Total() int {
  161. if ps == nil {
  162. return 0
  163. }
  164. return ps.total
  165. }
  166. func (ps *PartSet) AddPart(part *Part) (bool, error) {
  167. if ps == nil {
  168. return false, nil
  169. }
  170. ps.mtx.Lock()
  171. defer ps.mtx.Unlock()
  172. // Invalid part index
  173. if part.Index >= ps.total {
  174. return false, ErrPartSetUnexpectedIndex
  175. }
  176. // If part already exists, return false.
  177. if ps.parts[part.Index] != nil {
  178. return false, nil
  179. }
  180. // Check hash proof
  181. if part.Proof.Verify(ps.Hash(), part.Bytes) != nil {
  182. return false, ErrPartSetInvalidProof
  183. }
  184. // Add part
  185. ps.parts[part.Index] = part
  186. ps.partsBitArray.SetIndex(part.Index, true)
  187. ps.count++
  188. return true, nil
  189. }
  190. func (ps *PartSet) GetPart(index int) *Part {
  191. ps.mtx.Lock()
  192. defer ps.mtx.Unlock()
  193. return ps.parts[index]
  194. }
  195. func (ps *PartSet) IsComplete() bool {
  196. return ps.count == ps.total
  197. }
  198. func (ps *PartSet) GetReader() io.Reader {
  199. if !ps.IsComplete() {
  200. panic("Cannot GetReader() on incomplete PartSet")
  201. }
  202. return NewPartSetReader(ps.parts)
  203. }
  204. type PartSetReader struct {
  205. i int
  206. parts []*Part
  207. reader *bytes.Reader
  208. }
  209. func NewPartSetReader(parts []*Part) *PartSetReader {
  210. return &PartSetReader{
  211. i: 0,
  212. parts: parts,
  213. reader: bytes.NewReader(parts[0].Bytes),
  214. }
  215. }
  216. func (psr *PartSetReader) Read(p []byte) (n int, err error) {
  217. readerLen := psr.reader.Len()
  218. if readerLen >= len(p) {
  219. return psr.reader.Read(p)
  220. } else if readerLen > 0 {
  221. n1, err := psr.Read(p[:readerLen])
  222. if err != nil {
  223. return n1, err
  224. }
  225. n2, err := psr.Read(p[readerLen:])
  226. return n1 + n2, err
  227. }
  228. psr.i++
  229. if psr.i >= len(psr.parts) {
  230. return 0, io.EOF
  231. }
  232. psr.reader = bytes.NewReader(psr.parts[psr.i].Bytes)
  233. return psr.Read(p)
  234. }
  235. func (ps *PartSet) StringShort() string {
  236. if ps == nil {
  237. return "nil-PartSet"
  238. }
  239. ps.mtx.Lock()
  240. defer ps.mtx.Unlock()
  241. return fmt.Sprintf("(%v of %v)", ps.Count(), ps.Total())
  242. }
  243. func (ps *PartSet) MarshalJSON() ([]byte, error) {
  244. if ps == nil {
  245. return []byte("{}"), nil
  246. }
  247. ps.mtx.Lock()
  248. defer ps.mtx.Unlock()
  249. return cdc.MarshalJSON(struct {
  250. CountTotal string `json:"count/total"`
  251. PartsBitArray *bits.BitArray `json:"parts_bit_array"`
  252. }{
  253. fmt.Sprintf("%d/%d", ps.Count(), ps.Total()),
  254. ps.partsBitArray,
  255. })
  256. }