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.

221 lines
5.9 KiB

  1. package statedb
  2. import (
  3. "errors"
  4. "github.com/hermeznetwork/hermez-node/common"
  5. "github.com/iden3/go-merkletree"
  6. "github.com/iden3/go-merkletree/db"
  7. "github.com/iden3/go-merkletree/db/leveldb"
  8. "github.com/iden3/go-merkletree/db/memory"
  9. )
  10. // ErrStateDBWithoutMT is used when a method that requires a MerkleTree is called in a StateDB that does not have a MerkleTree defined
  11. var ErrStateDBWithoutMT = errors.New("Can not call method to use MerkleTree in a StateDB without MerkleTree")
  12. // ErrAccountAlreadyExists is used when CreateAccount is called and the Account already exists
  13. var ErrAccountAlreadyExists = errors.New("Can not CreateAccount because Account already exists")
  14. // StateDB represents the StateDB object
  15. type StateDB struct {
  16. db db.Storage
  17. mt *merkletree.MerkleTree
  18. }
  19. // NewStateDB creates a new StateDB, allowing to use an in-memory or in-disk
  20. // storage
  21. func NewStateDB(path string, inDisk bool, withMT bool, nLevels int) (*StateDB, error) {
  22. var sto db.Storage
  23. var err error
  24. if inDisk {
  25. sto, err = leveldb.NewLevelDbStorage(path, false)
  26. if err != nil {
  27. return nil, err
  28. }
  29. } else {
  30. sto = memory.NewMemoryStorage()
  31. }
  32. var mt *merkletree.MerkleTree = nil
  33. if withMT {
  34. mt, err = merkletree.NewMerkleTree(sto, nLevels)
  35. if err != nil {
  36. return nil, err
  37. }
  38. }
  39. return &StateDB{
  40. db: sto,
  41. mt: mt,
  42. }, nil
  43. }
  44. // CheckPointAt does a checkpoint at the given batchNum in the defined path
  45. func (s *StateDB) CheckPointAt(batchNum int, path string) error {
  46. // TODO
  47. return nil
  48. }
  49. // Reset resets the StateDB to the checkpoint at the given batchNum
  50. func (s *StateDB) Reset(batchNum int) error {
  51. // TODO
  52. return nil
  53. }
  54. // Checkpoints returns a list of the checkpoints (batchNums)
  55. func (s *StateDB) Checkpoints() ([]int, error) {
  56. // TODO
  57. //batchnums, err
  58. return nil, nil
  59. }
  60. // GetAccount returns the account for the given Idx
  61. func (s *StateDB) GetAccount(idx common.Idx) (*common.Account, error) {
  62. vBytes, err := s.db.Get(idx.Bytes())
  63. if err != nil {
  64. return nil, err
  65. }
  66. accBytes, err := s.db.Get(vBytes)
  67. if err != nil {
  68. return nil, err
  69. }
  70. var b [32 * common.NLEAFELEMS]byte
  71. copy(b[:], accBytes)
  72. return common.AccountFromBytes(b)
  73. }
  74. // CreateAccount creates a new Account in the StateDB for the given Idx.
  75. // MerkleTree is not affected.
  76. func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) error {
  77. // store at the DB the key: v, and value: leaf.Bytes()
  78. v, err := account.HashValue()
  79. if err != nil {
  80. return err
  81. }
  82. accountBytes, err := account.Bytes()
  83. if err != nil {
  84. return err
  85. }
  86. // store the Leaf value
  87. tx, err := s.db.NewTx()
  88. if err != nil {
  89. return err
  90. }
  91. _, err = tx.Get(idx.Bytes())
  92. if err != db.ErrNotFound {
  93. return ErrAccountAlreadyExists
  94. }
  95. tx.Put(v.Bytes(), accountBytes[:])
  96. tx.Put(idx.Bytes(), v.Bytes())
  97. return tx.Commit()
  98. }
  99. // UpdateAccount updates the Account in the StateDB for the given Idx.
  100. // MerkleTree is not affected.
  101. func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) error {
  102. // store at the DB the key: v, and value: leaf.Bytes()
  103. v, err := account.HashValue()
  104. if err != nil {
  105. return err
  106. }
  107. accountBytes, err := account.Bytes()
  108. if err != nil {
  109. return err
  110. }
  111. tx, err := s.db.NewTx()
  112. if err != nil {
  113. return err
  114. }
  115. tx.Put(v.Bytes(), accountBytes[:])
  116. tx.Put(idx.Bytes(), v.Bytes())
  117. return tx.Commit()
  118. }
  119. // MTCreateAccount creates a new Account in the StateDB for the given Idx,
  120. // and updates the MerkleTree, returning a CircomProcessorProof
  121. func (s *StateDB) MTCreateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
  122. if s.mt == nil {
  123. return nil, ErrStateDBWithoutMT
  124. }
  125. err := s.CreateAccount(idx, account)
  126. if err != nil {
  127. return nil, err
  128. }
  129. v, err := account.HashValue() // already computed in s.CreateAccount, next iteration reuse first computation
  130. if err != nil {
  131. return nil, err
  132. }
  133. // Add k & v into the MT
  134. return s.mt.AddAndGetCircomProof(idx.BigInt(), v)
  135. }
  136. // MTUpdateAccount updates the Account in the StateDB for the given Idx, and
  137. // updates the MerkleTree, returning a CircomProcessorProof
  138. func (s *StateDB) MTUpdateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
  139. if s.mt == nil {
  140. return nil, ErrStateDBWithoutMT
  141. }
  142. err := s.UpdateAccount(idx, account)
  143. if err != nil {
  144. return nil, err
  145. }
  146. v, err := account.HashValue() // already computed in s.CreateAccount, next iteration reuse first computation
  147. if err != nil {
  148. return nil, err
  149. }
  150. // Add k & v into the MT
  151. return s.mt.Update(idx.BigInt(), v)
  152. }
  153. // MTGetProof returns the CircomVerifierProof for a given Idx
  154. func (s *StateDB) MTGetProof(idx common.Idx) (*merkletree.CircomVerifierProof, error) {
  155. if s.mt == nil {
  156. return nil, ErrStateDBWithoutMT
  157. }
  158. return s.mt.GenerateCircomVerifierProof(idx.BigInt(), s.mt.Root())
  159. }
  160. // LocalStateDB represents the local StateDB which allows to make copies from
  161. // the synchronizer StateDB, and is used by the tx-selector and the
  162. // batch-builder. LocalStateDB is an in-memory storage.
  163. type LocalStateDB struct {
  164. *StateDB
  165. synchronizerStateDB *StateDB
  166. }
  167. // NewLocalStateDB returns a new LocalStateDB connected to the given
  168. // synchronizerDB
  169. func NewLocalStateDB(synchronizerDB *StateDB, withMT bool, nLevels int) (*LocalStateDB, error) {
  170. s, err := NewStateDB("", false, withMT, nLevels)
  171. if err != nil {
  172. return nil, err
  173. }
  174. return &LocalStateDB{
  175. s,
  176. synchronizerDB,
  177. }, nil
  178. }
  179. // Reset performs a reset, getting the state from
  180. // LocalStateDB.synchronizerStateDB for the given batchNum
  181. func (l *LocalStateDB) Reset(batchNum int, fromSynchronizer bool) error {
  182. // TODO
  183. // if fromSynchronizer==true:
  184. // make copy from l.synchronizerStateDB at the batchNum to the localStateDB
  185. // if synchronizerStateDB does not have batchNum, return err
  186. // the localStateDB checkpoint is set to batchNum
  187. // else fromSynchronizer==false:
  188. // the localStateDB checkpoint is set to batchNum
  189. // if localStateDB does not have batchNum, return err
  190. return nil
  191. }