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.

97 lines
2.9 KiB

  1. package merkletree
  2. import (
  3. "errors"
  4. "math/big"
  5. "sync"
  6. "github.com/iden3/go-iden3-core/common"
  7. "github.com/iden3/go-iden3-core/db"
  8. )
  9. const (
  10. // proofFlagsLen is the byte length of the flags in the proof header (first 32
  11. // bytes).
  12. proofFlagsLen = 2
  13. // ElemBytesLen is the length of the Hash byte array
  14. ElemBytesLen = 32
  15. )
  16. var (
  17. // ErrNodeKeyAlreadyExists is used when a node key already exists.
  18. ErrNodeKeyAlreadyExists = errors.New("node already exists")
  19. // ErrEntryIndexNotFound is used when no entry is found for an index.
  20. ErrEntryIndexNotFound = errors.New("node index not found in the DB")
  21. // ErrNodeDataBadSize is used when the data of a node has an incorrect
  22. // size and can't be parsed.
  23. ErrNodeDataBadSize = errors.New("node data has incorrect size in the DB")
  24. // ErrReachedMaxLevel is used when a traversal of the MT reaches the
  25. // maximum level.
  26. ErrReachedMaxLevel = errors.New("reached maximum level of the merkle tree")
  27. // ErrInvalidNodeFound is used when an invalid node is found and can't
  28. // be parsed.
  29. ErrInvalidNodeFound = errors.New("found an invalid node in the DB")
  30. // ErrInvalidProofBytes is used when a serialized proof is invalid.
  31. ErrInvalidProofBytes = errors.New("the serialized proof is invalid")
  32. // ErrInvalidDBValue is used when a value in the key value DB is
  33. // invalid (for example, it doen't contain a byte header and a []byte
  34. // body of at least len=1.
  35. ErrInvalidDBValue = errors.New("the value in the DB is invalid")
  36. // ErrEntryIndexAlreadyExists is used when the entry index already
  37. // exists in the tree.
  38. ErrEntryIndexAlreadyExists = errors.New("the entry index already exists in the tree")
  39. // ErrNotWritable is used when the MerkleTree is not writable and a write function is called
  40. ErrNotWritable = errors.New("Merkle Tree not writable")
  41. rootNodeValue = []byte("currentroot")
  42. HashZero = Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  43. )
  44. type Hash [32]byte
  45. func (h Hash) String() string {
  46. return new(big.Int).SetBytes(h[:]).String()
  47. }
  48. func (h *Hash) BigInt() *big.Int {
  49. return new(big.Int).SetBytes(common.SwapEndianness(h[:]))
  50. }
  51. func NewHashFromBigInt(b *big.Int) *Hash {
  52. r := &Hash{}
  53. copy(r[:], common.SwapEndianness(b.Bytes()))
  54. return r
  55. }
  56. type MerkleTree struct {
  57. sync.RWMutex
  58. db db.Storage
  59. rootKey *Hash
  60. writable bool
  61. maxLevels int
  62. }
  63. func NewMerkleTree(storage db.Storage, maxLevels int) (*MerkleTree, error) {
  64. mt := MerkleTree{db: storage, maxLevels: maxLevels, writable: true}
  65. v, err := mt.db.Get(rootNodeValue)
  66. if err != nil {
  67. tx, err := mt.db.NewTx()
  68. if err != nil {
  69. return nil, err
  70. }
  71. mt.rootKey = &HashZero
  72. tx.Put(rootNodeValue, mt.rootKey[:])
  73. err = tx.Commit()
  74. if err != nil {
  75. return nil, err
  76. }
  77. return &mt, nil
  78. }
  79. mt.rootKey = &Hash{}
  80. copy(mt.rootKey[:], v)
  81. return &mt, nil
  82. }
  83. func (mt *MerkleTree) Root() *Hash {
  84. return mt.rootKey
  85. }