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.

151 lines
3.9 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package merkle
  2. import (
  3. "bytes"
  4. "github.com/tendermint/tendermint/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160"
  5. "github.com/tendermint/tendermint/wire"
  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 := ripemd160.New()
  40. buf := new(bytes.Buffer)
  41. n, err := int64(0), error(nil)
  42. wire.WriteInt8(branch.Height, buf, &n, &err)
  43. wire.WriteVarint(branch.Size, buf, &n, &err)
  44. if len(branch.Left) == 0 {
  45. wire.WriteByteSlice(childHash, buf, &n, &err)
  46. wire.WriteByteSlice(branch.Right, buf, &n, &err)
  47. } else {
  48. wire.WriteByteSlice(branch.Left, buf, &n, &err)
  49. wire.WriteByteSlice(childHash, buf, &n, &err)
  50. }
  51. if err != nil {
  52. PanicCrisis(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 := ripemd160.New()
  64. buf := new(bytes.Buffer)
  65. n, err := int64(0), error(nil)
  66. wire.WriteInt8(0, buf, &n, &err)
  67. wire.WriteVarint(1, buf, &n, &err)
  68. wire.WriteByteSlice(leaf.KeyBytes, buf, &n, &err)
  69. wire.WriteByteSlice(leaf.ValueBytes, buf, &n, &err)
  70. if err != nil {
  71. PanicCrisis(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. PanicCrisis(Fmt("Failed to encode node.key: %v", err))
  85. }
  86. t.valueCodec.Encode(node.value, valueBuf, &n, &err)
  87. if err != nil {
  88. PanicCrisis(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. }