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.

178 lines
4.3 KiB

10 years ago
  1. /*
  2. Computes a deterministic minimal height merkle tree hash.
  3. If the number of items is not a power of two, some leaves
  4. will be at different levels. Tries to keep both sides of
  5. the tree the same size, but the left may be one greater.
  6. Use this for short deterministic trees, such as the validator list.
  7. For larger datasets, use IAVLTree.
  8. *
  9. / \
  10. / \
  11. / \
  12. / \
  13. * *
  14. / \ / \
  15. / \ / \
  16. / \ / \
  17. * * * h6
  18. / \ / \ / \
  19. h0 h1 h2 h3 h4 h5
  20. */
  21. package merkle
  22. import (
  23. "bytes"
  24. "crypto/sha256"
  25. "github.com/tendermint/tendermint2/binary"
  26. )
  27. func HashFromTwoHashes(left []byte, right []byte) []byte {
  28. var n int64
  29. var err error
  30. var hasher = sha256.New()
  31. binary.WriteByteSlice(left, hasher, &n, &err)
  32. binary.WriteByteSlice(right, hasher, &n, &err)
  33. if err != nil {
  34. panic(err)
  35. }
  36. return hasher.Sum(nil)
  37. }
  38. func HashFromHashes(hashes [][]byte) []byte {
  39. // Recursive impl.
  40. switch len(hashes) {
  41. case 0:
  42. return nil
  43. case 1:
  44. return hashes[0]
  45. default:
  46. left := HashFromHashes(hashes[:(len(hashes)+1)/2])
  47. right := HashFromHashes(hashes[(len(hashes)+1)/2:])
  48. return HashFromTwoHashes(left, right)
  49. }
  50. }
  51. // Convenience for HashFromHashes.
  52. func HashFromBinaries(items []interface{}) []byte {
  53. hashes := [][]byte{}
  54. for _, item := range items {
  55. hashes = append(hashes, HashFromBinary(item))
  56. }
  57. return HashFromHashes(hashes)
  58. }
  59. // General Convenience
  60. func HashFromBinary(item interface{}) []byte {
  61. hasher, n, err := sha256.New(), new(int64), new(error)
  62. binary.WriteBinary(item, hasher, n, err)
  63. if *err != nil {
  64. panic(err)
  65. }
  66. return hasher.Sum(nil)
  67. }
  68. // Convenience for HashFromHashes.
  69. func HashFromHashables(items []Hashable) []byte {
  70. hashes := [][]byte{}
  71. for _, item := range items {
  72. hash := item.Hash()
  73. hashes = append(hashes, hash)
  74. }
  75. return HashFromHashes(hashes)
  76. }
  77. type HashTrail struct {
  78. Hash []byte
  79. Parent *HashTrail
  80. Left *HashTrail
  81. Right *HashTrail
  82. }
  83. func (ht *HashTrail) Flatten() [][]byte {
  84. // Nonrecursive impl.
  85. trail := [][]byte{}
  86. for ht != nil {
  87. if ht.Left != nil {
  88. trail = append(trail, ht.Left.Hash)
  89. } else if ht.Right != nil {
  90. trail = append(trail, ht.Right.Hash)
  91. } else {
  92. break
  93. }
  94. ht = ht.Parent
  95. }
  96. return trail
  97. }
  98. // returned trails[0].Hash is the leaf hash.
  99. // trails[0].Parent.Hash is the hash above that, etc.
  100. func HashTrailsFromHashables(items []Hashable) (trails []*HashTrail, root *HashTrail) {
  101. // Recursive impl.
  102. switch len(items) {
  103. case 0:
  104. return nil, nil
  105. case 1:
  106. trail := &HashTrail{items[0].Hash(), nil, nil, nil}
  107. return []*HashTrail{trail}, trail
  108. default:
  109. lefts, leftRoot := HashTrailsFromHashables(items[:(len(items)+1)/2])
  110. rights, rightRoot := HashTrailsFromHashables(items[(len(items)+1)/2:])
  111. rootHash := HashFromTwoHashes(leftRoot.Hash, rightRoot.Hash)
  112. root := &HashTrail{rootHash, nil, nil, nil}
  113. leftRoot.Parent = root
  114. leftRoot.Right = rightRoot
  115. rightRoot.Parent = root
  116. rightRoot.Left = leftRoot
  117. return append(lefts, rights...), root
  118. }
  119. }
  120. // Ensures that leafHash is part of rootHash.
  121. func VerifyHashTrail(index uint, total uint, leafHash []byte, trail [][]byte, rootHash []byte) bool {
  122. computedRoot := ComputeRootFromTrail(index, total, leafHash, trail)
  123. if computedRoot == nil {
  124. return false
  125. }
  126. return bytes.Equal(computedRoot, rootHash)
  127. }
  128. // Use the leafHash and trail to get the root merkle hash.
  129. // If the length of the trail slice isn't exactly correct, the result is nil.
  130. func ComputeRootFromTrail(index uint, total uint, leafHash []byte, trail [][]byte) []byte {
  131. // Recursive impl.
  132. if index >= total {
  133. return nil
  134. }
  135. switch total {
  136. case 0:
  137. panic("Cannot call ComputeRootFromTrail() with 0 total")
  138. case 1:
  139. if len(trail) != 0 {
  140. return nil
  141. }
  142. return leafHash
  143. default:
  144. if len(trail) == 0 {
  145. return nil
  146. }
  147. numLeft := (total + 1) / 2
  148. if index < numLeft {
  149. leftRoot := ComputeRootFromTrail(index, numLeft, leafHash, trail[:len(trail)-1])
  150. if leftRoot == nil {
  151. return nil
  152. }
  153. return HashFromTwoHashes(leftRoot, trail[len(trail)-1])
  154. } else {
  155. rightRoot := ComputeRootFromTrail(index-numLeft, total-numLeft, leafHash, trail[:len(trail)-1])
  156. if rightRoot == nil {
  157. return nil
  158. }
  159. return HashFromTwoHashes(trail[len(trail)-1], rightRoot)
  160. }
  161. }
  162. }