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.

149 lines
3.8 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
  1. package merkle
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "github.com/tendermint/tendermint/binary"
  6. . "github.com/tendermint/tendermint/common"
  7. )
  8. type IAVLProof struct {
  9. LeafNode IAVLProofLeafNode
  10. InnerNodes []IAVLProofInnerNode
  11. RootHash []byte
  12. }
  13. func (proof *IAVLProof) Verify(keyBytes, valueBytes, rootHash []byte) bool {
  14. if !bytes.Equal(keyBytes, proof.LeafNode.KeyBytes) {
  15. return false
  16. }
  17. if !bytes.Equal(valueBytes, proof.LeafNode.ValueBytes) {
  18. return false
  19. }
  20. if !bytes.Equal(rootHash, proof.RootHash) {
  21. return false
  22. }
  23. hash := proof.LeafNode.Hash()
  24. // fmt.Printf("leaf hash: %X\n", hash)
  25. for _, branch := range proof.InnerNodes {
  26. hash = branch.Hash(hash)
  27. // fmt.Printf("branch hash: %X\n", hash)
  28. }
  29. // fmt.Printf("root: %X, computed: %X\n", proof.RootHash, hash)
  30. return bytes.Equal(proof.RootHash, hash)
  31. }
  32. type IAVLProofInnerNode struct {
  33. Height int8
  34. Size int
  35. Left []byte
  36. Right []byte
  37. }
  38. func (branch IAVLProofInnerNode) Hash(childHash []byte) []byte {
  39. hasher := sha256.New()
  40. buf := new(bytes.Buffer)
  41. n, err := int64(0), error(nil)
  42. binary.WriteInt8(branch.Height, buf, &n, &err)
  43. binary.WriteVarint(branch.Size, buf, &n, &err)
  44. if len(branch.Left) == 0 {
  45. binary.WriteByteSlice(childHash, buf, &n, &err)
  46. binary.WriteByteSlice(branch.Right, buf, &n, &err)
  47. } else {
  48. binary.WriteByteSlice(branch.Left, buf, &n, &err)
  49. binary.WriteByteSlice(childHash, buf, &n, &err)
  50. }
  51. if err != nil {
  52. panic(Fmt("Failed to hash IAVLProofInnerNode: %v", err))
  53. }
  54. // fmt.Printf("InnerNode hash bytes: %X\n", buf.Bytes())
  55. hasher.Write(buf.Bytes())
  56. return hasher.Sum(nil)
  57. }
  58. type IAVLProofLeafNode struct {
  59. KeyBytes []byte
  60. ValueBytes []byte
  61. }
  62. func (leaf IAVLProofLeafNode) Hash() []byte {
  63. hasher := sha256.New()
  64. buf := new(bytes.Buffer)
  65. n, err := int64(0), error(nil)
  66. binary.WriteInt8(0, buf, &n, &err)
  67. binary.WriteVarint(1, buf, &n, &err)
  68. binary.WriteByteSlice(leaf.KeyBytes, buf, &n, &err)
  69. binary.WriteByteSlice(leaf.ValueBytes, buf, &n, &err)
  70. if err != nil {
  71. panic(Fmt("Failed to hash IAVLProofLeafNode: %v", err))
  72. }
  73. // fmt.Printf("LeafNode hash bytes: %X\n", buf.Bytes())
  74. hasher.Write(buf.Bytes())
  75. return hasher.Sum(nil)
  76. }
  77. func (node *IAVLNode) constructProof(t *IAVLTree, key interface{}, proof *IAVLProof) (exists bool) {
  78. if node.height == 0 {
  79. if t.keyCodec.Compare(node.key, key) == 0 {
  80. keyBuf, valueBuf := new(bytes.Buffer), new(bytes.Buffer)
  81. n, err := int64(0), error(nil)
  82. t.keyCodec.Encode(node.key, keyBuf, &n, &err)
  83. if err != nil {
  84. panic(Fmt("Failed to encode node.key: %v", err))
  85. }
  86. t.valueCodec.Encode(node.value, valueBuf, &n, &err)
  87. if err != nil {
  88. panic(Fmt("Failed to encode node.value: %v", err))
  89. }
  90. leaf := IAVLProofLeafNode{
  91. KeyBytes: keyBuf.Bytes(),
  92. ValueBytes: valueBuf.Bytes(),
  93. }
  94. proof.LeafNode = leaf
  95. return true
  96. } else {
  97. return false
  98. }
  99. } else {
  100. if t.keyCodec.Compare(key, node.key) < 0 {
  101. exists := node.getLeftNode(t).constructProof(t, key, proof)
  102. if !exists {
  103. return false
  104. }
  105. branch := IAVLProofInnerNode{
  106. Height: node.height,
  107. Size: node.size,
  108. Left: nil,
  109. Right: node.getRightNode(t).hash,
  110. }
  111. proof.InnerNodes = append(proof.InnerNodes, branch)
  112. return true
  113. } else {
  114. exists := node.getRightNode(t).constructProof(t, key, proof)
  115. if !exists {
  116. return false
  117. }
  118. branch := IAVLProofInnerNode{
  119. Height: node.height,
  120. Size: node.size,
  121. Left: node.getLeftNode(t).hash,
  122. Right: nil,
  123. }
  124. proof.InnerNodes = append(proof.InnerNodes, branch)
  125. return true
  126. }
  127. }
  128. }
  129. // Returns nil if key is not in tree.
  130. func (t *IAVLTree) ConstructProof(key interface{}) *IAVLProof {
  131. if t.root == nil {
  132. return nil
  133. }
  134. t.root.hashWithCount(t) // Ensure that all hashes are calculated.
  135. proof := &IAVLProof{
  136. RootHash: t.root.hash,
  137. }
  138. t.root.constructProof(t, key, proof)
  139. return proof
  140. }