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.

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