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.

91 lines
2.2 KiB

7 years ago
7 years ago
7 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. "github.com/tendermint/tmlibs/merkle/tmhash"
  24. )
  25. func SimpleHashFromTwoHashes(left []byte, right []byte) []byte {
  26. var hasher = tmhash.New()
  27. err := encodeByteSlice(hasher, left)
  28. if err != nil {
  29. panic(err)
  30. }
  31. err = encodeByteSlice(hasher, right)
  32. if err != nil {
  33. panic(err)
  34. }
  35. return hasher.Sum(nil)
  36. }
  37. func SimpleHashFromHashes(hashes [][]byte) []byte {
  38. // Recursive impl.
  39. switch len(hashes) {
  40. case 0:
  41. return nil
  42. case 1:
  43. return hashes[0]
  44. default:
  45. left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2])
  46. right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:])
  47. return SimpleHashFromTwoHashes(left, right)
  48. }
  49. }
  50. // NOTE: Do not implement this, use SimpleHashFromByteslices instead.
  51. // type Byteser interface { Bytes() []byte }
  52. // func SimpleHashFromBytesers(items []Byteser) []byte { ... }
  53. func SimpleHashFromByteslices(bzs [][]byte) []byte {
  54. hashes := make([][]byte, len(bzs))
  55. for i, bz := range bzs {
  56. hashes[i] = SimpleHashFromBytes(bz)
  57. }
  58. return SimpleHashFromHashes(hashes)
  59. }
  60. func SimpleHashFromBytes(bz []byte) []byte {
  61. hasher := tmhash.New()
  62. hasher.Write(bz)
  63. return hasher.Sum(nil)
  64. }
  65. func SimpleHashFromHashers(items []Hasher) []byte {
  66. hashes := make([][]byte, len(items))
  67. for i, item := range items {
  68. hash := item.Hash()
  69. hashes[i] = hash
  70. }
  71. return SimpleHashFromHashes(hashes)
  72. }
  73. func SimpleHashFromMap(m map[string]Hasher) []byte {
  74. sm := NewSimpleMap()
  75. for k, v := range m {
  76. sm.Set(k, v)
  77. }
  78. return sm.Hash()
  79. }