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.

143 lines
4.0 KiB

  1. package merkletree
  2. import (
  3. "fmt"
  4. "math/big"
  5. )
  6. // NodeType defines the type of node in the MT.
  7. type NodeType byte
  8. const (
  9. // NodeTypeMiddle indicates the type of middle Node that has children.
  10. NodeTypeMiddle NodeType = 0
  11. // NodeTypeLeaf indicates the type of a leaf Node that contains a key & value.
  12. NodeTypeLeaf NodeType = 1
  13. // NodeTypeEmpty indicates the type of an empty Node.
  14. NodeTypeEmpty NodeType = 2
  15. // DBEntryTypeRoot indicates the type of a DB entry that indicates the current Root of a MerkleTree
  16. DBEntryTypeRoot NodeType = 3
  17. )
  18. // Node is the struct that represents a node in the MT. The node should not be
  19. // modified after creation because the cached key won't be updated.
  20. type Node struct {
  21. // Type is the type of node in the tree.
  22. Type NodeType
  23. // ChildL is the left child of a middle node.
  24. ChildL *Hash
  25. // ChildR is the right child of a middle node.
  26. ChildR *Hash
  27. // Entry is the data stored in a leaf node.
  28. Entry [2]*Hash
  29. // key is a cache used to avoid recalculating key
  30. key *Hash
  31. }
  32. // NewNodeLeaf creates a new leaf node.
  33. func NewNodeLeaf(k, v *Hash) *Node {
  34. return &Node{Type: NodeTypeLeaf, Entry: [2]*Hash{k, v}}
  35. }
  36. // NewNodeMiddle creates a new middle node.
  37. func NewNodeMiddle(childL *Hash, childR *Hash) *Node {
  38. return &Node{Type: NodeTypeMiddle, ChildL: childL, ChildR: childR}
  39. }
  40. // NewNodeEmpty creates a new empty node.
  41. func NewNodeEmpty() *Node {
  42. return &Node{Type: NodeTypeEmpty}
  43. }
  44. // NewNodeFromBytes creates a new node by parsing the input []byte.
  45. func NewNodeFromBytes(b []byte) (*Node, error) {
  46. if len(b) < 1 {
  47. return nil, ErrNodeBytesBadSize
  48. }
  49. n := Node{Type: NodeType(b[0])}
  50. b = b[1:]
  51. switch n.Type {
  52. case NodeTypeMiddle:
  53. if len(b) != 2*ElemBytesLen {
  54. return nil, ErrNodeBytesBadSize
  55. }
  56. n.ChildL, n.ChildR = &Hash{}, &Hash{}
  57. copy(n.ChildL[:], b[:ElemBytesLen])
  58. copy(n.ChildR[:], b[ElemBytesLen:ElemBytesLen*2])
  59. case NodeTypeLeaf:
  60. if len(b) != 2*ElemBytesLen {
  61. return nil, ErrNodeBytesBadSize
  62. }
  63. n.Entry = [2]*Hash{{}, {}}
  64. copy(n.Entry[0][:], b[0:32])
  65. copy(n.Entry[1][:], b[32:64])
  66. case NodeTypeEmpty:
  67. break
  68. default:
  69. return nil, ErrInvalidNodeFound
  70. }
  71. return &n, nil
  72. }
  73. // LeafKey computes the key of a leaf node given the hIndex and hValue of the
  74. // entry of the leaf.
  75. func LeafKey(k, v *Hash) (*Hash, error) {
  76. return HashElemsKey(big.NewInt(1), k.BigInt(), v.BigInt())
  77. }
  78. // Key computes the key of the node by hashing the content in a specific way
  79. // for each type of node. This key is used as the hash of the merklee tree for
  80. // each node.
  81. func (n *Node) Key() (*Hash, error) {
  82. if n.key == nil { // Cache the key to avoid repeated hash computations.
  83. // NOTE: We are not using the type to calculate the hash!
  84. switch n.Type {
  85. case NodeTypeMiddle: // H(ChildL || ChildR)
  86. var err error
  87. n.key, err = HashElems(n.ChildL.BigInt(), n.ChildR.BigInt())
  88. if err != nil {
  89. return nil, err
  90. }
  91. case NodeTypeLeaf:
  92. var err error
  93. n.key, err = LeafKey(n.Entry[0], n.Entry[1])
  94. if err != nil {
  95. return nil, err
  96. }
  97. case NodeTypeEmpty: // Zero
  98. n.key = &HashZero
  99. default:
  100. n.key = &HashZero
  101. }
  102. }
  103. return n.key, nil
  104. }
  105. // Value returns the value of the node. This is the content that is stored in the backend database.
  106. func (n *Node) Value() []byte {
  107. switch n.Type {
  108. case NodeTypeMiddle: // {Type || ChildL || ChildR}
  109. return append([]byte{byte(n.Type)}, append(n.ChildL[:], n.ChildR[:]...)...)
  110. case NodeTypeLeaf: // {Type || Data...}
  111. return append([]byte{byte(n.Type)}, append(n.Entry[0][:], n.Entry[1][:]...)...)
  112. case NodeTypeEmpty: // {}
  113. return []byte{}
  114. default:
  115. return []byte{}
  116. }
  117. }
  118. // String outputs a string representation of a node (different for each type).
  119. func (n *Node) String() string {
  120. switch n.Type {
  121. case NodeTypeMiddle: // {Type || ChildL || ChildR}
  122. return fmt.Sprintf("Middle L:%s R:%s", n.ChildL, n.ChildR)
  123. case NodeTypeLeaf: // {Type || Data...}
  124. return fmt.Sprintf("Leaf I:%v D:%v", n.Entry[0], n.Entry[1])
  125. case NodeTypeEmpty: // {}
  126. return "Empty"
  127. default:
  128. return "Invalid Node"
  129. }
  130. }