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.

118 lines
3.0 KiB

  1. package tree
  2. import (
  3. "errors"
  4. "fmt"
  5. "os/user"
  6. "strings"
  7. common3 "github.com/vocdoni/go-iden3/common"
  8. mkcore "github.com/vocdoni/go-iden3/core"
  9. "github.com/vocdoni/go-iden3/db"
  10. "github.com/vocdoni/go-iden3/merkletree"
  11. )
  12. type Tree struct {
  13. Namespace string
  14. Storage string
  15. Tree *merkletree.MerkleTree
  16. DbStorage *db.LevelDbStorage
  17. }
  18. func (t *Tree) Init() error {
  19. if len(t.Storage) < 1 {
  20. usr, err := user.Current()
  21. if err == nil {
  22. t.Storage = usr.HomeDir + "/.dvote/Tree"
  23. } else {
  24. t.Storage = "./dvoteTree"
  25. }
  26. }
  27. mtdb, err := db.NewLevelDbStorage(t.Storage, false)
  28. if err != nil {
  29. return err
  30. }
  31. mt, err := merkletree.New(mtdb, 140)
  32. if err != nil {
  33. return err
  34. }
  35. t.DbStorage = mtdb
  36. t.Tree = mt
  37. return nil
  38. }
  39. func (t *Tree) Close() {
  40. defer t.Tree.Storage().Close()
  41. }
  42. func (t *Tree) AddClaim(data []byte) error {
  43. isSnapshot := strings.HasPrefix(t.Namespace, "0x")
  44. if isSnapshot {
  45. return errors.New("No new claims can be added to a Snapshot")
  46. }
  47. claim := mkcore.NewGenericClaim(t.Namespace, "default", data, nil)
  48. return t.Tree.Add(claim)
  49. }
  50. func (t *Tree) GenProof(data []byte) (string, error) {
  51. claim := mkcore.NewGenericClaim(t.Namespace, "default", data, nil)
  52. mp, err := t.Tree.GenerateProof(claim.Hi())
  53. if err != nil {
  54. return "", err
  55. }
  56. mpHex := common3.BytesToHex(mp)
  57. return mpHex, nil
  58. }
  59. func (t *Tree) CheckProof(data []byte, mpHex string) (bool, error) {
  60. mp, err := common3.HexToBytes(mpHex)
  61. if err != nil {
  62. return false, err
  63. }
  64. claim := mkcore.NewGenericClaim(t.Namespace, "default", data, nil)
  65. return merkletree.CheckProof(t.Tree.Root(), mp, claim.Hi(), claim.Ht(), t.Tree.NumLevels()), nil
  66. }
  67. func (t *Tree) GetRoot() string {
  68. return t.Tree.Root().Hex()
  69. }
  70. /* Dump, Export and Snapshot functions are a bit tricky.
  71. Since go-iden3 does not provide the necessary tools. Low level operations must be performed.
  72. Once go-iden3 API is mature enough, these functions must be adapted.
  73. To explore: Values are stored twice in the BD?
  74. */
  75. func (t *Tree) Dump() ([]string, error) {
  76. var response []string
  77. substorage := t.DbStorage.WithPrefix([]byte(t.Namespace))
  78. nsHash := merkletree.HashBytes([]byte(t.Namespace))
  79. substorage.Iterate(func(key, value []byte) {
  80. nsValue := value[5:37]
  81. if fmt.Sprint(nsHash) == fmt.Sprint(nsValue) {
  82. response = append(response, string(value[69:]))
  83. }
  84. })
  85. return response, nil
  86. }
  87. func (t *Tree) Snapshot() (string, error) {
  88. substorage := t.DbStorage.WithPrefix([]byte(t.Namespace))
  89. nsHash := merkletree.HashBytes([]byte(t.Namespace))
  90. snapshotNamespace := t.GetRoot()
  91. fmt.Printf("Snapshoting %s\n", snapshotNamespace)
  92. t.Namespace = snapshotNamespace
  93. substorage.Iterate(func(key, value []byte) {
  94. nsValue := value[5:37]
  95. if fmt.Sprint(nsHash) == fmt.Sprint(nsValue) {
  96. fmt.Printf("%x\n", value)
  97. data := value[69:]
  98. //claim := mkcore.NewGenericClaim(snapshotNamespace, "default", data, nil)
  99. err := t.AddClaim(data)
  100. if err != nil {
  101. fmt.Println(err)
  102. }
  103. }
  104. })
  105. return snapshotNamespace, nil
  106. }