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.

269 lines
5.5 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
  1. package blocks
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "strings"
  9. "sync"
  10. . "github.com/tendermint/tendermint/binary"
  11. . "github.com/tendermint/tendermint/common"
  12. "github.com/tendermint/tendermint/merkle"
  13. )
  14. const (
  15. partSize = 4096 // 4KB
  16. )
  17. var (
  18. ErrPartSetUnexpectedIndex = errors.New("Error part set unexpected index")
  19. ErrPartSetInvalidTrail = errors.New("Error part set invalid trail")
  20. )
  21. type Part struct {
  22. Index uint16
  23. Trail [][]byte
  24. Bytes []byte
  25. // Cache
  26. hash []byte
  27. }
  28. func ReadPart(r io.Reader, n *int64, err *error) *Part {
  29. return &Part{
  30. Index: ReadUInt16(r, n, err),
  31. Trail: ReadByteSlices(r, n, err),
  32. Bytes: ReadByteSlice(r, n, err),
  33. }
  34. }
  35. func (part *Part) WriteTo(w io.Writer) (n int64, err error) {
  36. WriteUInt16(w, part.Index, &n, &err)
  37. WriteByteSlices(w, part.Trail, &n, &err)
  38. WriteByteSlice(w, part.Bytes, &n, &err)
  39. return
  40. }
  41. func (part *Part) Hash() []byte {
  42. if part.hash != nil {
  43. return part.hash
  44. } else {
  45. hasher := sha256.New()
  46. _, err := hasher.Write(part.Bytes)
  47. if err != nil {
  48. panic(err)
  49. }
  50. part.hash = hasher.Sum(nil)
  51. return part.hash
  52. }
  53. }
  54. func (part *Part) String() string {
  55. return part.StringWithIndent("")
  56. }
  57. func (part *Part) StringWithIndent(indent string) string {
  58. trailStrings := make([]string, len(part.Trail))
  59. for i, hash := range part.Trail {
  60. trailStrings[i] = fmt.Sprintf("%X", hash)
  61. }
  62. return fmt.Sprintf(`Part{
  63. %s Index: %v
  64. %s Trail:
  65. %s %v
  66. %s}`,
  67. indent, part.Index,
  68. indent,
  69. indent, strings.Join(trailStrings, "\n"+indent+" "),
  70. indent)
  71. }
  72. //-------------------------------------
  73. type PartSetHeader struct {
  74. Total uint16
  75. Hash []byte
  76. }
  77. func ReadPartSetHeader(r io.Reader, n *int64, err *error) PartSetHeader {
  78. return PartSetHeader{
  79. Total: ReadUInt16(r, n, err),
  80. Hash: ReadByteSlice(r, n, err),
  81. }
  82. }
  83. func (psh PartSetHeader) WriteTo(w io.Writer) (n int64, err error) {
  84. WriteUInt16(w, psh.Total, &n, &err)
  85. WriteByteSlice(w, psh.Hash, &n, &err)
  86. return
  87. }
  88. func (psh PartSetHeader) IsZero() bool {
  89. return psh.Total == 0
  90. }
  91. func (psh PartSetHeader) String() string {
  92. return fmt.Sprintf("PartSet{%X/%v}", psh.Hash, psh.Total)
  93. }
  94. func (psh PartSetHeader) Equals(other PartSetHeader) bool {
  95. return psh.Total == other.Total && bytes.Equal(psh.Hash, other.Hash)
  96. }
  97. //-------------------------------------
  98. type PartSet struct {
  99. total uint16
  100. hash []byte
  101. mtx sync.Mutex
  102. parts []*Part
  103. partsBitArray BitArray
  104. count uint16
  105. }
  106. // Returns an immutable, full PartSet.
  107. // TODO Name is confusing, Data/Header clash with Block.Data/Header
  108. func NewPartSetFromData(data []byte) *PartSet {
  109. // divide data into 4kb parts.
  110. total := (len(data) + partSize - 1) / partSize
  111. parts := make([]*Part, total)
  112. parts_ := make([]merkle.Hashable, total)
  113. partsBitArray := NewBitArray(uint(total))
  114. for i := 0; i < total; i++ {
  115. part := &Part{
  116. Index: uint16(i),
  117. Bytes: data[i*partSize : MinInt(len(data), (i+1)*partSize)],
  118. }
  119. parts[i] = part
  120. parts_[i] = part
  121. partsBitArray.SetIndex(uint(i), true)
  122. }
  123. // Compute merkle trails
  124. hashTree := merkle.HashTreeFromHashables(parts_)
  125. for i := 0; i < total; i++ {
  126. parts[i].Trail = merkle.HashTrailForIndex(hashTree, i)
  127. }
  128. return &PartSet{
  129. total: uint16(total),
  130. hash: hashTree[len(hashTree)/2],
  131. parts: parts,
  132. partsBitArray: partsBitArray,
  133. count: uint16(total),
  134. }
  135. }
  136. // Returns an empty PartSet ready to be populated.
  137. // TODO Name is confusing, Data/Header clash with Block.Data/Header
  138. func NewPartSetFromHeader(header PartSetHeader) *PartSet {
  139. return &PartSet{
  140. total: header.Total,
  141. hash: header.Hash,
  142. parts: make([]*Part, header.Total),
  143. partsBitArray: NewBitArray(uint(header.Total)),
  144. count: 0,
  145. }
  146. }
  147. func (ps *PartSet) Header() PartSetHeader {
  148. if ps == nil {
  149. return PartSetHeader{}
  150. } else {
  151. return PartSetHeader{
  152. Total: ps.total,
  153. Hash: ps.hash,
  154. }
  155. }
  156. }
  157. func (ps *PartSet) BitArray() BitArray {
  158. ps.mtx.Lock()
  159. defer ps.mtx.Unlock()
  160. return ps.partsBitArray.Copy()
  161. }
  162. func (ps *PartSet) Hash() []byte {
  163. if ps == nil {
  164. return nil
  165. }
  166. return ps.hash
  167. }
  168. func (ps *PartSet) HashesTo(hash []byte) bool {
  169. if ps == nil {
  170. return false
  171. }
  172. return bytes.Equal(ps.hash, hash)
  173. }
  174. func (ps *PartSet) Count() uint16 {
  175. if ps == nil {
  176. return 0
  177. }
  178. return ps.count
  179. }
  180. func (ps *PartSet) Total() uint16 {
  181. if ps == nil {
  182. return 0
  183. }
  184. return ps.total
  185. }
  186. func (ps *PartSet) AddPart(part *Part) (bool, error) {
  187. ps.mtx.Lock()
  188. defer ps.mtx.Unlock()
  189. // Invalid part index
  190. if part.Index >= ps.total {
  191. return false, ErrPartSetUnexpectedIndex
  192. }
  193. // If part already exists, return false.
  194. if ps.parts[part.Index] != nil {
  195. return false, nil
  196. }
  197. // Check hash trail
  198. if !merkle.VerifyHashTrailForIndex(int(part.Index), part.Hash(), part.Trail, ps.hash) {
  199. return false, ErrPartSetInvalidTrail
  200. }
  201. // Add part
  202. ps.parts[part.Index] = part
  203. ps.partsBitArray.SetIndex(uint(part.Index), true)
  204. ps.count++
  205. return true, nil
  206. }
  207. func (ps *PartSet) GetPart(index uint16) *Part {
  208. ps.mtx.Lock()
  209. defer ps.mtx.Unlock()
  210. return ps.parts[index]
  211. }
  212. func (ps *PartSet) IsComplete() bool {
  213. return ps.count == ps.total
  214. }
  215. func (ps *PartSet) GetReader() io.Reader {
  216. if !ps.IsComplete() {
  217. panic("Cannot GetReader() on incomplete PartSet")
  218. }
  219. buf := []byte{}
  220. for _, part := range ps.parts {
  221. buf = append(buf, part.Bytes...)
  222. }
  223. return bytes.NewReader(buf)
  224. }
  225. func (ps *PartSet) Description() string {
  226. if ps == nil {
  227. return "nil-PartSet"
  228. } else {
  229. return fmt.Sprintf("(%v of %v)", ps.Count(), ps.Total())
  230. }
  231. }