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.

497 lines
15 KiB

  1. package statedb
  2. import (
  3. "errors"
  4. "fmt"
  5. "math/big"
  6. "github.com/hermeznetwork/hermez-node/common"
  7. "github.com/hermeznetwork/hermez-node/db/kvdb"
  8. "github.com/hermeznetwork/hermez-node/log"
  9. "github.com/hermeznetwork/tracerr"
  10. "github.com/iden3/go-merkletree"
  11. "github.com/iden3/go-merkletree/db"
  12. "github.com/iden3/go-merkletree/db/pebble"
  13. )
  14. var (
  15. // ErrStateDBWithoutMT is used when a method that requires a MerkleTree
  16. // is called in a StateDB that does not have a MerkleTree defined
  17. ErrStateDBWithoutMT = errors.New("Can not call method to use MerkleTree in a StateDB without MerkleTree")
  18. // ErrAccountAlreadyExists is used when CreateAccount is called and the
  19. // Account already exists
  20. ErrAccountAlreadyExists = errors.New("Can not CreateAccount because Account already exists")
  21. // ErrIdxNotFound is used when trying to get the Idx from EthAddr or
  22. // EthAddr&ToBJJ
  23. ErrIdxNotFound = errors.New("Idx can not be found")
  24. // ErrGetIdxNoCase is used when trying to get the Idx from EthAddr &
  25. // BJJ with not compatible combination
  26. ErrGetIdxNoCase = errors.New("Can not get Idx due unexpected combination of ethereum Address & BabyJubJub PublicKey")
  27. // PrefixKeyIdx is the key prefix for idx in the db
  28. PrefixKeyIdx = []byte("i:")
  29. // PrefixKeyAccHash is the key prefix for account hash in the db
  30. PrefixKeyAccHash = []byte("h:")
  31. // PrefixKeyMT is the key prefix for merkle tree in the db
  32. PrefixKeyMT = []byte("m:")
  33. // PrefixKeyAddr is the key prefix for address in the db
  34. PrefixKeyAddr = []byte("a:")
  35. // PrefixKeyAddrBJJ is the key prefix for address-babyjubjub in the db
  36. PrefixKeyAddrBJJ = []byte("ab:")
  37. )
  38. const (
  39. // TypeSynchronizer defines a StateDB used by the Synchronizer, that
  40. // generates the ExitTree when processing the txs
  41. TypeSynchronizer = "synchronizer"
  42. // TypeTxSelector defines a StateDB used by the TxSelector, without
  43. // computing ExitTree neither the ZKInputs
  44. TypeTxSelector = "txselector"
  45. // TypeBatchBuilder defines a StateDB used by the BatchBuilder, that
  46. // generates the ExitTree and the ZKInput when processing the txs
  47. TypeBatchBuilder = "batchbuilder"
  48. )
  49. // TypeStateDB determines the type of StateDB
  50. type TypeStateDB string
  51. // StateDB represents the StateDB object
  52. type StateDB struct {
  53. path string
  54. Typ TypeStateDB
  55. db *kvdb.KVDB
  56. nLevels int
  57. MT *merkletree.MerkleTree
  58. keep int
  59. }
  60. // Last offers a subset of view methods of the StateDB that can be
  61. // called via the LastRead method of StateDB in a thread-safe manner to obtain
  62. // a consistent view to the last batch of the StateDB.
  63. type Last struct {
  64. db db.Storage
  65. }
  66. // GetAccount returns the account for the given Idx
  67. func (s *Last) GetAccount(idx common.Idx) (*common.Account, error) {
  68. return GetAccountInTreeDB(s.db, idx)
  69. }
  70. // GetCurrentBatch returns the current BatchNum stored in Last.db
  71. func (s *Last) GetCurrentBatch() (common.BatchNum, error) {
  72. cbBytes, err := s.db.Get(kvdb.KeyCurrentBatch)
  73. if tracerr.Unwrap(err) == db.ErrNotFound {
  74. return 0, nil
  75. } else if err != nil {
  76. return 0, tracerr.Wrap(err)
  77. }
  78. return common.BatchNumFromBytes(cbBytes)
  79. }
  80. // DB returns the underlying storage of Last
  81. func (s *Last) DB() db.Storage {
  82. return s.db
  83. }
  84. // GetAccounts returns all the accounts in the db. Use for debugging pruposes
  85. // only.
  86. func (s *Last) GetAccounts() ([]common.Account, error) {
  87. return getAccounts(s.db)
  88. }
  89. // NewStateDB creates a new StateDB, allowing to use an in-memory or in-disk
  90. // storage. Checkpoints older than the value defined by `keep` will be
  91. // deleted.
  92. func NewStateDB(pathDB string, keep int, typ TypeStateDB, nLevels int) (*StateDB, error) {
  93. var kv *kvdb.KVDB
  94. var err error
  95. kv, err = kvdb.NewKVDB(pathDB, keep)
  96. if err != nil {
  97. return nil, tracerr.Wrap(err)
  98. }
  99. var mt *merkletree.MerkleTree = nil
  100. if typ == TypeSynchronizer || typ == TypeBatchBuilder {
  101. mt, err = merkletree.NewMerkleTree(kv.StorageWithPrefix(PrefixKeyMT), nLevels)
  102. if err != nil {
  103. return nil, tracerr.Wrap(err)
  104. }
  105. }
  106. if typ == TypeTxSelector && nLevels != 0 {
  107. return nil, tracerr.Wrap(fmt.Errorf("invalid StateDB parameters: StateDB type==TypeStateDB can not have nLevels!=0"))
  108. }
  109. return &StateDB{
  110. path: pathDB,
  111. db: kv,
  112. nLevels: nLevels,
  113. MT: mt,
  114. Typ: typ,
  115. keep: keep,
  116. }, nil
  117. }
  118. // LastRead is a thread-safe method to query the last checkpoint of the StateDB
  119. // via the Last type methods
  120. func (s *StateDB) LastRead(fn func(sdbLast *Last) error) error {
  121. return s.db.LastRead(
  122. func(db *pebble.Storage) error {
  123. return fn(&Last{
  124. db: db,
  125. })
  126. },
  127. )
  128. }
  129. // LastGetAccount is a thread-safe method to query an account in the last
  130. // checkpoint of the StateDB.
  131. func (s *StateDB) LastGetAccount(idx common.Idx) (*common.Account, error) {
  132. var account *common.Account
  133. if err := s.LastRead(func(sdb *Last) error {
  134. var err error
  135. account, err = sdb.GetAccount(idx)
  136. return err
  137. }); err != nil {
  138. return nil, tracerr.Wrap(err)
  139. }
  140. return account, nil
  141. }
  142. // LastGetCurrentBatch is a thread-safe method to get the current BatchNum in
  143. // the last checkpoint of the StateDB.
  144. func (s *StateDB) LastGetCurrentBatch() (common.BatchNum, error) {
  145. var batchNum common.BatchNum
  146. if err := s.LastRead(func(sdb *Last) error {
  147. var err error
  148. batchNum, err = sdb.GetCurrentBatch()
  149. return err
  150. }); err != nil {
  151. return 0, tracerr.Wrap(err)
  152. }
  153. return batchNum, nil
  154. }
  155. // LastMTGetRoot returns the root of the underlying Merkle Tree in the last
  156. // checkpoint of the StateDB.
  157. func (s *StateDB) LastMTGetRoot() (*big.Int, error) {
  158. var root *big.Int
  159. if err := s.LastRead(func(sdb *Last) error {
  160. mt, err := merkletree.NewMerkleTree(sdb.DB().WithPrefix(PrefixKeyMT), s.nLevels)
  161. if err != nil {
  162. return tracerr.Wrap(err)
  163. }
  164. root = mt.Root().BigInt()
  165. return nil
  166. }); err != nil {
  167. return nil, tracerr.Wrap(err)
  168. }
  169. return root, nil
  170. }
  171. // MakeCheckpoint does a checkpoint at the given batchNum in the defined path.
  172. // Internally this advances & stores the current BatchNum, and then stores a
  173. // Checkpoint of the current state of the StateDB.
  174. func (s *StateDB) MakeCheckpoint() error {
  175. log.Debugw("Making StateDB checkpoint", "batch", s.CurrentBatch()+1, "type", s.Typ)
  176. return s.db.MakeCheckpoint()
  177. }
  178. // CurrentBatch returns the current in-memory CurrentBatch of the StateDB.db
  179. func (s *StateDB) CurrentBatch() common.BatchNum {
  180. return s.db.CurrentBatch
  181. }
  182. // CurrentIdx returns the current in-memory CurrentIdx of the StateDB.db
  183. func (s *StateDB) CurrentIdx() common.Idx {
  184. return s.db.CurrentIdx
  185. }
  186. // getCurrentBatch returns the current BatchNum stored in the StateDB.db
  187. func (s *StateDB) getCurrentBatch() (common.BatchNum, error) {
  188. return s.db.GetCurrentBatch()
  189. }
  190. // GetCurrentIdx returns the stored Idx from the localStateDB, which is the
  191. // last Idx used for an Account in the localStateDB.
  192. func (s *StateDB) GetCurrentIdx() (common.Idx, error) {
  193. return s.db.GetCurrentIdx()
  194. }
  195. // SetCurrentIdx stores Idx in the StateDB
  196. func (s *StateDB) SetCurrentIdx(idx common.Idx) error {
  197. return s.db.SetCurrentIdx(idx)
  198. }
  199. // Reset resets the StateDB to the checkpoint at the given batchNum. Reset
  200. // does not delete the checkpoints between old current and the new current,
  201. // those checkpoints will remain in the storage, and eventually will be
  202. // deleted when MakeCheckpoint overwrites them.
  203. func (s *StateDB) Reset(batchNum common.BatchNum) error {
  204. err := s.db.Reset(batchNum)
  205. if err != nil {
  206. return tracerr.Wrap(err)
  207. }
  208. if s.MT != nil {
  209. // open the MT for the current s.db
  210. mt, err := merkletree.NewMerkleTree(s.db.StorageWithPrefix(PrefixKeyMT), s.MT.MaxLevels())
  211. if err != nil {
  212. return tracerr.Wrap(err)
  213. }
  214. s.MT = mt
  215. }
  216. log.Debugw("Making StateDB Reset", "batch", batchNum)
  217. return nil
  218. }
  219. // GetAccount returns the account for the given Idx
  220. func (s *StateDB) GetAccount(idx common.Idx) (*common.Account, error) {
  221. return GetAccountInTreeDB(s.db.DB(), idx)
  222. }
  223. func accountsIter(db db.Storage, fn func(a *common.Account) (bool, error)) error {
  224. idxDB := db.WithPrefix(PrefixKeyIdx)
  225. if err := idxDB.Iterate(func(k []byte, v []byte) (bool, error) {
  226. idx, err := common.IdxFromBytes(k)
  227. if err != nil {
  228. return false, tracerr.Wrap(err)
  229. }
  230. acc, err := GetAccountInTreeDB(db, idx)
  231. if err != nil {
  232. return false, tracerr.Wrap(err)
  233. }
  234. ok, err := fn(acc)
  235. if err != nil {
  236. return false, tracerr.Wrap(err)
  237. }
  238. return ok, nil
  239. }); err != nil {
  240. return tracerr.Wrap(err)
  241. }
  242. return nil
  243. }
  244. func getAccounts(db db.Storage) ([]common.Account, error) {
  245. accs := []common.Account{}
  246. if err := accountsIter(
  247. db,
  248. func(a *common.Account) (bool, error) {
  249. accs = append(accs, *a)
  250. return true, nil
  251. },
  252. ); err != nil {
  253. return nil, tracerr.Wrap(err)
  254. }
  255. return accs, nil
  256. }
  257. // TestGetAccounts returns all the accounts in the db. Use only in tests.
  258. // Outside tests getting all the accounts is discouraged because it's an
  259. // expensive operation, but if you must do it, use `LastRead()` method to get a
  260. // thread-safe and consistent view of the stateDB.
  261. func (s *StateDB) TestGetAccounts() ([]common.Account, error) {
  262. return getAccounts(s.db.DB())
  263. }
  264. // GetAccountInTreeDB is abstracted from StateDB to be used from StateDB and
  265. // from ExitTree. GetAccount returns the account for the given Idx
  266. func GetAccountInTreeDB(sto db.Storage, idx common.Idx) (*common.Account, error) {
  267. idxBytes, err := idx.Bytes()
  268. if err != nil {
  269. return nil, tracerr.Wrap(err)
  270. }
  271. vBytes, err := sto.Get(append(PrefixKeyIdx, idxBytes[:]...))
  272. if err != nil {
  273. return nil, tracerr.Wrap(err)
  274. }
  275. accBytes, err := sto.Get(append(PrefixKeyAccHash, vBytes...))
  276. if err != nil {
  277. return nil, tracerr.Wrap(err)
  278. }
  279. var b [32 * common.NLeafElems]byte
  280. copy(b[:], accBytes)
  281. account, err := common.AccountFromBytes(b)
  282. if err != nil {
  283. return nil, tracerr.Wrap(err)
  284. }
  285. account.Idx = idx
  286. return account, nil
  287. }
  288. // CreateAccount creates a new Account in the StateDB for the given Idx. If
  289. // StateDB.MT==nil, MerkleTree is not affected, otherwise updates the
  290. // MerkleTree, returning a CircomProcessorProof.
  291. func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
  292. cpp, err := CreateAccountInTreeDB(s.db.DB(), s.MT, idx, account)
  293. if err != nil {
  294. return cpp, tracerr.Wrap(err)
  295. }
  296. // store idx by EthAddr & BJJ
  297. err = s.setIdxByEthAddrBJJ(idx, account.EthAddr, account.BJJ, account.TokenID)
  298. return cpp, tracerr.Wrap(err)
  299. }
  300. // CreateAccountInTreeDB is abstracted from StateDB to be used from StateDB and
  301. // from ExitTree. Creates a new Account in the StateDB for the given Idx. If
  302. // StateDB.MT==nil, MerkleTree is not affected, otherwise updates the
  303. // MerkleTree, returning a CircomProcessorProof.
  304. func CreateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
  305. // store at the DB the key: v, and value: leaf.Bytes()
  306. v, err := account.HashValue()
  307. if err != nil {
  308. return nil, tracerr.Wrap(err)
  309. }
  310. accountBytes, err := account.Bytes()
  311. if err != nil {
  312. return nil, tracerr.Wrap(err)
  313. }
  314. // store the Leaf value
  315. tx, err := sto.NewTx()
  316. if err != nil {
  317. return nil, tracerr.Wrap(err)
  318. }
  319. idxBytes, err := idx.Bytes()
  320. if err != nil {
  321. return nil, tracerr.Wrap(err)
  322. }
  323. _, err = tx.Get(append(PrefixKeyIdx, idxBytes[:]...))
  324. if tracerr.Unwrap(err) != db.ErrNotFound {
  325. return nil, tracerr.Wrap(ErrAccountAlreadyExists)
  326. }
  327. err = tx.Put(append(PrefixKeyAccHash, v.Bytes()...), accountBytes[:])
  328. if err != nil {
  329. return nil, tracerr.Wrap(err)
  330. }
  331. err = tx.Put(append(PrefixKeyIdx, idxBytes[:]...), v.Bytes())
  332. if err != nil {
  333. return nil, tracerr.Wrap(err)
  334. }
  335. if err := tx.Commit(); err != nil {
  336. return nil, tracerr.Wrap(err)
  337. }
  338. if mt != nil {
  339. return mt.AddAndGetCircomProof(idx.BigInt(), v)
  340. }
  341. return nil, nil
  342. }
  343. // UpdateAccount updates the Account in the StateDB for the given Idx. If
  344. // StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
  345. // MerkleTree, returning a CircomProcessorProof.
  346. func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
  347. return UpdateAccountInTreeDB(s.db.DB(), s.MT, idx, account)
  348. }
  349. // UpdateAccountInTreeDB is abstracted from StateDB to be used from StateDB and
  350. // from ExitTree. Updates the Account in the StateDB for the given Idx. If
  351. // StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
  352. // MerkleTree, returning a CircomProcessorProof.
  353. func UpdateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
  354. // store at the DB the key: v, and value: account.Bytes()
  355. v, err := account.HashValue()
  356. if err != nil {
  357. return nil, tracerr.Wrap(err)
  358. }
  359. accountBytes, err := account.Bytes()
  360. if err != nil {
  361. return nil, tracerr.Wrap(err)
  362. }
  363. tx, err := sto.NewTx()
  364. if err != nil {
  365. return nil, tracerr.Wrap(err)
  366. }
  367. err = tx.Put(append(PrefixKeyAccHash, v.Bytes()...), accountBytes[:])
  368. if err != nil {
  369. return nil, tracerr.Wrap(err)
  370. }
  371. idxBytes, err := idx.Bytes()
  372. if err != nil {
  373. return nil, tracerr.Wrap(err)
  374. }
  375. err = tx.Put(append(PrefixKeyIdx, idxBytes[:]...), v.Bytes())
  376. if err != nil {
  377. return nil, tracerr.Wrap(err)
  378. }
  379. if err := tx.Commit(); err != nil {
  380. return nil, tracerr.Wrap(err)
  381. }
  382. if mt != nil {
  383. proof, err := mt.Update(idx.BigInt(), v)
  384. return proof, tracerr.Wrap(err)
  385. }
  386. return nil, nil
  387. }
  388. // MTGetProof returns the CircomVerifierProof for a given Idx
  389. func (s *StateDB) MTGetProof(idx common.Idx) (*merkletree.CircomVerifierProof, error) {
  390. if s.MT == nil {
  391. return nil, tracerr.Wrap(ErrStateDBWithoutMT)
  392. }
  393. p, err := s.MT.GenerateSCVerifierProof(idx.BigInt(), s.MT.Root())
  394. if err != nil {
  395. return nil, tracerr.Wrap(err)
  396. }
  397. return p, nil
  398. }
  399. // Close the StateDB
  400. func (s *StateDB) Close() {
  401. s.db.Close()
  402. }
  403. // LocalStateDB represents the local StateDB which allows to make copies from
  404. // the synchronizer StateDB, and is used by the tx-selector and the
  405. // batch-builder. LocalStateDB is an in-memory storage.
  406. type LocalStateDB struct {
  407. *StateDB
  408. synchronizerStateDB *StateDB
  409. }
  410. // NewLocalStateDB returns a new LocalStateDB connected to the given
  411. // synchronizerDB. Checkpoints older than the value defined by `keep` will be
  412. // deleted.
  413. func NewLocalStateDB(path string, keep int, synchronizerDB *StateDB, typ TypeStateDB,
  414. nLevels int) (*LocalStateDB, error) {
  415. s, err := NewStateDB(path, keep, typ, nLevels)
  416. if err != nil {
  417. return nil, tracerr.Wrap(err)
  418. }
  419. return &LocalStateDB{
  420. s,
  421. synchronizerDB,
  422. }, nil
  423. }
  424. // Reset performs a reset in the LocaStateDB. If fromSynchronizer is true, it
  425. // gets the state from LocalStateDB.synchronizerStateDB for the given batchNum.
  426. // If fromSynchronizer is false, get the state from LocalStateDB checkpoints.
  427. func (l *LocalStateDB) Reset(batchNum common.BatchNum, fromSynchronizer bool) error {
  428. if fromSynchronizer {
  429. err := l.db.ResetFromSynchronizer(batchNum, l.synchronizerStateDB.db)
  430. if err != nil {
  431. return tracerr.Wrap(err)
  432. }
  433. // open the MT for the current s.db
  434. if l.MT != nil {
  435. mt, err := merkletree.NewMerkleTree(l.db.StorageWithPrefix(PrefixKeyMT), l.MT.MaxLevels())
  436. if err != nil {
  437. return tracerr.Wrap(err)
  438. }
  439. l.MT = mt
  440. }
  441. return nil
  442. }
  443. // use checkpoint from LocalStateDB
  444. return l.StateDB.Reset(batchNum)
  445. }