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.

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