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.

150 lines
3.3 KiB

  1. package tree
  2. import (
  3. "bytes"
  4. "errors"
  5. "os/user"
  6. common3 "github.com/iden3/go-iden3/common"
  7. mkcore "github.com/iden3/go-iden3/core"
  8. db "github.com/iden3/go-iden3/db"
  9. merkletree "github.com/iden3/go-iden3/merkletree"
  10. )
  11. type Tree struct {
  12. Storage string
  13. Tree *merkletree.MerkleTree
  14. DbStorage *db.LevelDbStorage
  15. }
  16. func (t *Tree) Init(namespace string) error {
  17. if len(t.Storage) < 1 {
  18. if len(namespace) < 1 {
  19. return errors.New("namespace not valid")
  20. }
  21. usr, err := user.Current()
  22. if err == nil {
  23. t.Storage = usr.HomeDir + "/.dvote/census/" + namespace
  24. } else {
  25. t.Storage = "./dvoteTree/" + namespace
  26. }
  27. }
  28. mtdb, err := db.NewLevelDbStorage(t.Storage, false)
  29. if err != nil {
  30. return err
  31. }
  32. mt, err := merkletree.NewMerkleTree(mtdb, 140)
  33. if err != nil {
  34. return err
  35. }
  36. t.DbStorage = mtdb
  37. t.Tree = mt
  38. return nil
  39. }
  40. func (t *Tree) Close() {
  41. defer t.Tree.Storage().Close()
  42. }
  43. func (t *Tree) GetClaim(data []byte) (*mkcore.ClaimBasic, error) {
  44. if len(data) > 496/8 {
  45. return nil, errors.New("claim data too large")
  46. }
  47. for i := len(data); i <= 496/8; i++ {
  48. data = append(data, byte('.'))
  49. }
  50. var indexSlot [400 / 8]byte
  51. var dataSlot [496 / 8]byte
  52. copy(indexSlot[:], data[:400/8])
  53. copy(dataSlot[:], data[:496/8])
  54. e := mkcore.NewClaimBasic(indexSlot, dataSlot)
  55. return e, nil
  56. }
  57. func (t *Tree) AddClaim(data []byte) error {
  58. e, err := t.GetClaim(data)
  59. if err != nil {
  60. return err
  61. }
  62. return t.Tree.Add(e.Entry())
  63. }
  64. func (t *Tree) GenProof(data []byte) (string, error) {
  65. e, err := t.GetClaim(data)
  66. if err != nil {
  67. return "", err
  68. }
  69. mp, err := t.Tree.GenerateProof(e.Entry().HIndex())
  70. if err != nil {
  71. return "", err
  72. }
  73. mpHex := common3.HexEncode(mp.Bytes())
  74. return mpHex, nil
  75. }
  76. func (t *Tree) CheckProof(data []byte, mpHex string) (bool, error) {
  77. mpBytes, err := common3.HexDecode(mpHex)
  78. if err != nil {
  79. return false, err
  80. }
  81. mp, err := merkletree.NewProofFromBytes(mpBytes)
  82. if err != nil {
  83. return false, err
  84. }
  85. e, err := t.GetClaim(data)
  86. if err != nil {
  87. return false, err
  88. }
  89. return merkletree.VerifyProof(t.Tree.RootKey(), mp,
  90. e.Entry().HIndex(), e.Entry().HValue()), nil
  91. }
  92. func (t *Tree) GetRoot() string {
  93. return t.Tree.RootKey().String()
  94. }
  95. func (t *Tree) GetIndex(data []byte) (string, error) {
  96. e, err := t.GetClaim(data)
  97. if err != nil {
  98. return "", err
  99. }
  100. index, err := t.Tree.GetDataByIndex(e.Entry().HIndex())
  101. return index.String(), err
  102. }
  103. /*
  104. func (t *Tree) Dump() ([]string, error) {
  105. var response []string
  106. err := t.Tree.Walk(t.Tree.RootKey(), func(n *merkletree.Node) {
  107. if n.Type == merkletree.NodeTypeLeaf {
  108. rawValue := n.Value()
  109. var cleanValue []byte
  110. for i := 0; i < len(rawValue); i++ {
  111. if rawValue[i] == byte('.') {
  112. break
  113. }
  114. cleanValue = append(cleanValue, rawValue[i])
  115. }
  116. response = append(response, fmt.Sprintf("%s", cleanValue))
  117. }
  118. })
  119. return response, err
  120. }
  121. */
  122. func (t *Tree) Dump() (string, error) {
  123. w := bytes.NewBufferString("")
  124. err := t.Tree.DumpClaims(w, nil) // as rootKey we can pass a nil pointer, and it will use the current RootKey
  125. return w.String(), err
  126. }
  127. func (t *Tree) Snapshot(root string) (*Tree, error) {
  128. var rootHash merkletree.Hash
  129. copy(rootHash[:32], root)
  130. mt, err := t.Tree.Snapshot(&rootHash)
  131. snapshotTree := new(Tree)
  132. snapshotTree.Tree = mt
  133. return snapshotTree, err
  134. }