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.

714 lines
21 KiB

  1. package statedb
  2. import (
  3. "errors"
  4. "math/big"
  5. "github.com/hermeznetwork/hermez-node/common"
  6. "github.com/hermeznetwork/hermez-node/log"
  7. "github.com/iden3/go-iden3-crypto/babyjub"
  8. "github.com/iden3/go-merkletree"
  9. "github.com/iden3/go-merkletree/db"
  10. "github.com/iden3/go-merkletree/db/memory"
  11. )
  12. var (
  13. // keyidx is used as key in the db to store the current Idx
  14. keyidx = []byte("idx")
  15. )
  16. func (s *StateDB) resetZKInputs() {
  17. s.zki = nil
  18. s.i = 0
  19. }
  20. type processedExit struct {
  21. exit bool
  22. newExit bool
  23. idx common.Idx
  24. acc common.Account
  25. }
  26. // ProcessTxs process the given L1Txs & L2Txs applying the needed updates to
  27. // the StateDB depending on the transaction Type. If StateDB
  28. // type==TypeBatchBuilder, returns the common.ZKInputs to generate the
  29. // SnarkProof later used by the BatchBuilder. If StateDB
  30. // type==TypeSynchronizer, assumes that the call is done from the Synchronizer,
  31. // returns common.ExitTreeLeaf that is later used by the Synchronizer to update
  32. // the HistoryDB, and adds Nonce & TokenID to the L2Txs.
  33. func (s *StateDB) ProcessTxs(l1usertxs, l1coordinatortxs []*common.L1Tx, l2txs []*common.PoolL2Tx) (*common.ZKInputs, []common.ExitInfo, error) {
  34. var err error
  35. var exitTree *merkletree.MerkleTree
  36. if s.zki != nil {
  37. return nil, nil, errors.New("Expected StateDB.zki==nil, something went wrong and it's not empty")
  38. }
  39. defer s.resetZKInputs()
  40. nTx := len(l1usertxs) + len(l1coordinatortxs) + len(l2txs)
  41. if nTx == 0 {
  42. // TODO return ZKInputs of batch without txs
  43. return nil, nil, nil
  44. }
  45. exits := make([]processedExit, nTx)
  46. if s.typ == TypeBatchBuilder {
  47. s.zki = common.NewZKInputs(nTx, 24, 32) // TODO this values will be parameters of the function, taken from config file/coordinator call
  48. s.zki.OldLastIdx = (s.idx - 1).BigInt()
  49. s.zki.OldStateRoot = s.mt.Root().BigInt()
  50. }
  51. // TBD if ExitTree is only in memory or stored in disk, for the moment
  52. // only needed in memory
  53. if s.typ == TypeSynchronizer || s.typ == TypeBatchBuilder {
  54. exitTree, err = merkletree.NewMerkleTree(memory.NewMemoryStorage(), s.mt.MaxLevels())
  55. if err != nil {
  56. return nil, nil, err
  57. }
  58. }
  59. // assumption: l1usertx are sorted by L1Tx.Position
  60. for _, tx := range l1usertxs {
  61. exitIdx, exitAccount, newExit, err := s.processL1Tx(exitTree, tx)
  62. if err != nil {
  63. return nil, nil, err
  64. }
  65. if s.typ == TypeSynchronizer || s.typ == TypeBatchBuilder {
  66. if exitIdx != nil && exitTree != nil {
  67. exits[s.i] = processedExit{
  68. exit: true,
  69. newExit: newExit,
  70. idx: *exitIdx,
  71. acc: *exitAccount,
  72. }
  73. }
  74. s.i++
  75. }
  76. }
  77. for _, tx := range l1coordinatortxs {
  78. exitIdx, exitAccount, newExit, err := s.processL1Tx(exitTree, tx)
  79. if err != nil {
  80. return nil, nil, err
  81. }
  82. if exitIdx != nil {
  83. log.Error("Unexpected Exit in L1CoordinatorTx")
  84. }
  85. if s.typ == TypeSynchronizer || s.typ == TypeBatchBuilder {
  86. if exitIdx != nil && exitTree != nil {
  87. exits[s.i] = processedExit{
  88. exit: true,
  89. newExit: newExit,
  90. idx: *exitIdx,
  91. acc: *exitAccount,
  92. }
  93. }
  94. s.i++
  95. }
  96. }
  97. for _, tx := range l2txs {
  98. exitIdx, exitAccount, newExit, err := s.processL2Tx(exitTree, tx)
  99. if err != nil {
  100. return nil, nil, err
  101. }
  102. if s.typ == TypeSynchronizer || s.typ == TypeBatchBuilder {
  103. if exitIdx != nil && exitTree != nil {
  104. exits[s.i] = processedExit{
  105. exit: true,
  106. newExit: newExit,
  107. idx: *exitIdx,
  108. acc: *exitAccount,
  109. }
  110. }
  111. s.i++
  112. }
  113. }
  114. if s.typ == TypeTxSelector {
  115. return nil, nil, nil
  116. }
  117. // once all txs processed (exitTree root frozen), for each Exit,
  118. // generate common.ExitInfo data
  119. var exitInfos []common.ExitInfo
  120. for i := 0; i < nTx; i++ {
  121. if !exits[i].exit {
  122. continue
  123. }
  124. exitIdx := exits[i].idx
  125. exitAccount := exits[i].acc
  126. // 0. generate MerkleProof
  127. p, err := exitTree.GenerateCircomVerifierProof(exitIdx.BigInt(), nil)
  128. if err != nil {
  129. return nil, nil, err
  130. }
  131. // 1. generate common.ExitInfo
  132. ei := common.ExitInfo{
  133. AccountIdx: exitIdx,
  134. MerkleProof: p,
  135. Balance: exitAccount.Balance,
  136. }
  137. exitInfos = append(exitInfos, ei)
  138. if s.zki != nil {
  139. s.zki.TokenID2[i] = exitAccount.TokenID.BigInt()
  140. s.zki.Nonce2[i] = exitAccount.Nonce.BigInt()
  141. if babyjub.PointCoordSign(exitAccount.PublicKey.X) {
  142. s.zki.Sign2[i] = big.NewInt(1)
  143. }
  144. s.zki.Ay2[i] = exitAccount.PublicKey.Y
  145. s.zki.Balance2[i] = exitAccount.Balance
  146. s.zki.EthAddr2[i] = common.EthAddrToBigInt(exitAccount.EthAddr)
  147. s.zki.Siblings2[i] = p.Siblings
  148. if exits[i].newExit {
  149. s.zki.NewExit[i] = big.NewInt(1)
  150. }
  151. if p.IsOld0 {
  152. s.zki.IsOld0_2[i] = big.NewInt(1)
  153. }
  154. s.zki.OldKey2[i] = p.OldKey.BigInt()
  155. s.zki.OldValue2[i] = p.OldValue.BigInt()
  156. }
  157. }
  158. if s.typ == TypeSynchronizer {
  159. return nil, exitInfos, nil
  160. }
  161. // compute last ZKInputs parameters
  162. s.zki.GlobalChainID = big.NewInt(0) // TODO, 0: ethereum, this will be get from config file
  163. // zki.FeeIdxs = ? // TODO, this will be get from the config file
  164. tokenIDs, err := s.getTokenIDsBigInt(l1usertxs, l1coordinatortxs, l2txs)
  165. if err != nil {
  166. return nil, nil, err
  167. }
  168. s.zki.FeePlanTokens = tokenIDs
  169. // s.zki.ISInitStateRootFee = s.mt.Root().BigInt()
  170. // TODO once the Node Config sets the Accounts where to send the Fees
  171. // compute fees & update ZKInputs
  172. // return exitInfos, so Synchronizer will be able to store it into
  173. // HistoryDB for the concrete BatchNum
  174. return s.zki, exitInfos, nil
  175. }
  176. // getTokenIDsBigInt returns the list of TokenIDs in *big.Int format
  177. func (s *StateDB) getTokenIDsBigInt(l1usertxs, l1coordinatortxs []*common.L1Tx, l2txs []*common.PoolL2Tx) ([]*big.Int, error) {
  178. tokenIDs := make(map[common.TokenID]bool)
  179. for i := 0; i < len(l1usertxs); i++ {
  180. tokenIDs[l1usertxs[i].TokenID] = true
  181. }
  182. for i := 0; i < len(l1coordinatortxs); i++ {
  183. tokenIDs[l1coordinatortxs[i].TokenID] = true
  184. }
  185. for i := 0; i < len(l2txs); i++ {
  186. // as L2Tx does not have parameter TokenID, get it from the
  187. // AccountsDB (in the StateDB)
  188. acc, err := s.GetAccount(l2txs[i].ToIdx)
  189. if err != nil {
  190. return nil, err
  191. }
  192. tokenIDs[acc.TokenID] = true
  193. }
  194. var tBI []*big.Int
  195. for t := range tokenIDs {
  196. tBI = append(tBI, t.BigInt())
  197. }
  198. return tBI, nil
  199. }
  200. // processL1Tx process the given L1Tx applying the needed updates to the
  201. // StateDB depending on the transaction Type. It returns the 3 parameters
  202. // related to the Exit (in case of): Idx, ExitAccount, boolean determining if
  203. // the Exit created a new Leaf in the ExitTree.
  204. func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx) (*common.Idx, *common.Account, bool, error) {
  205. // ZKInputs
  206. if s.zki != nil {
  207. // Txs
  208. // s.zki.TxCompressedData[s.i] = tx.TxCompressedData() // uncomment once L1Tx.TxCompressedData is ready
  209. if tx.FromIdx != nil {
  210. s.zki.FromIdx[s.i] = tx.FromIdx.BigInt()
  211. } else {
  212. s.zki.FromIdx[s.i] = big.NewInt(0)
  213. }
  214. s.zki.ToIdx[s.i] = tx.ToIdx.BigInt()
  215. s.zki.OnChain[s.i] = big.NewInt(1)
  216. // L1Txs
  217. s.zki.LoadAmountF[s.i] = tx.LoadAmount
  218. s.zki.FromEthAddr[s.i] = common.EthAddrToBigInt(tx.FromEthAddr)
  219. if tx.FromBJJ != nil {
  220. s.zki.FromBJJCompressed[s.i] = BJJCompressedTo256BigInts(tx.FromBJJ.Compress())
  221. }
  222. // Intermediate States
  223. s.zki.ISOnChain[s.i] = big.NewInt(1)
  224. }
  225. switch tx.Type {
  226. case common.TxTypeForceTransfer, common.TxTypeTransfer:
  227. // go to the MT account of sender and receiver, and update balance
  228. // & nonce
  229. err := s.applyTransfer(tx.Tx(), 0) // 0 for the parameter toIdx, as at L1Tx ToIdx can only be 0 in the Deposit type case.
  230. if err != nil {
  231. return nil, nil, false, err
  232. }
  233. case common.TxTypeCreateAccountDeposit:
  234. // add new account to the MT, update balance of the MT account
  235. err := s.applyCreateAccount(tx)
  236. if err != nil {
  237. return nil, nil, false, err
  238. }
  239. if s.zki != nil {
  240. s.zki.AuxFromIdx[s.i] = s.idx.BigInt() // last s.idx is the one used for creating the new account
  241. s.zki.NewAccount[s.i] = big.NewInt(1)
  242. }
  243. case common.TxTypeDeposit:
  244. // update balance of the MT account
  245. err := s.applyDeposit(tx, false)
  246. if err != nil {
  247. return nil, nil, false, err
  248. }
  249. case common.TxTypeDepositTransfer:
  250. // update balance in MT account, update balance & nonce of sender
  251. // & receiver
  252. err := s.applyDeposit(tx, true)
  253. if err != nil {
  254. return nil, nil, false, err
  255. }
  256. case common.TxTypeCreateAccountDepositTransfer:
  257. // add new account to the merkletree, update balance in MT account,
  258. // update balance & nonce of sender & receiver
  259. err := s.applyCreateAccountDepositTransfer(tx)
  260. if err != nil {
  261. return nil, nil, false, err
  262. }
  263. if s.zki != nil {
  264. s.zki.AuxFromIdx[s.i] = s.idx.BigInt() // last s.idx is the one used for creating the new account
  265. s.zki.NewAccount[s.i] = big.NewInt(1)
  266. }
  267. case common.TxTypeExit:
  268. // execute exit flow
  269. exitAccount, newExit, err := s.applyExit(exitTree, tx.Tx())
  270. if err != nil {
  271. return nil, nil, false, err
  272. }
  273. return tx.FromIdx, exitAccount, newExit, nil
  274. default:
  275. }
  276. return nil, nil, false, nil
  277. }
  278. // processL2Tx process the given L2Tx applying the needed updates to the
  279. // StateDB depending on the transaction Type. It returns the 3 parameters
  280. // related to the Exit (in case of): Idx, ExitAccount, boolean determining if
  281. // the Exit created a new Leaf in the ExitTree.
  282. func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2Tx) (*common.Idx, *common.Account, bool, error) {
  283. var err error
  284. var auxToIdx common.Idx
  285. // if tx.ToIdx==0, get toIdx by ToEthAddr or ToBJJ
  286. if tx.ToIdx == nil || *tx.ToIdx == common.Idx(0) {
  287. auxToIdx, err = s.GetIdxByEthAddrBJJ(tx.ToEthAddr, tx.ToBJJ)
  288. if err != nil {
  289. log.Error(err)
  290. return nil, nil, false, err
  291. }
  292. }
  293. // ZKInputs
  294. if s.zki != nil {
  295. // Txs
  296. // s.zki.TxCompressedData[s.i] = tx.TxCompressedData() // uncomment once L1Tx.TxCompressedData is ready
  297. // s.zki.TxCompressedDataV2[s.i] = tx.TxCompressedDataV2() // uncomment once L2Tx.TxCompressedDataV2 is ready
  298. s.zki.FromIdx[s.i] = tx.FromIdx.BigInt()
  299. s.zki.ToIdx[s.i] = tx.ToIdx.BigInt()
  300. // fill AuxToIdx if needed
  301. if tx.ToIdx == nil {
  302. // use toIdx that can have been filled by tx.ToIdx or
  303. // if tx.Idx==0 (this case), toIdx is filled by the Idx
  304. // from db by ToEthAddr&ToBJJ
  305. s.zki.AuxToIdx[s.i] = auxToIdx.BigInt()
  306. }
  307. s.zki.ToBJJAy[s.i] = tx.ToBJJ.Y
  308. if tx.ToEthAddr != nil {
  309. s.zki.ToEthAddr[s.i] = common.EthAddrToBigInt(*tx.ToEthAddr)
  310. } else {
  311. // Not sure if this should throw an error
  312. s.zki.ToEthAddr[s.i] = big.NewInt(0)
  313. }
  314. s.zki.OnChain[s.i] = big.NewInt(0)
  315. s.zki.NewAccount[s.i] = big.NewInt(0)
  316. // L2Txs
  317. // s.zki.RqOffset[s.i] = // TODO Rq once TxSelector is ready
  318. // s.zki.RqTxCompressedDataV2[s.i] = // TODO
  319. // s.zki.RqToEthAddr[s.i] = common.EthAddrToBigInt(tx.RqToEthAddr) // TODO
  320. // s.zki.RqToBJJAy[s.i] = tx.ToBJJ.Y // TODO
  321. s.zki.S[s.i] = tx.Signature.S
  322. s.zki.R8x[s.i] = tx.Signature.R8.X
  323. s.zki.R8y[s.i] = tx.Signature.R8.Y
  324. }
  325. // if StateDB type==TypeSynchronizer, will need to add Nonce and
  326. // TokenID to the transaction
  327. if s.typ == TypeSynchronizer {
  328. acc, err := s.GetAccount(tx.ToIdx)
  329. if err != nil {
  330. return nil, nil, false, err
  331. }
  332. tx.Nonce = acc.Nonce
  333. tx.TokenID = acc.TokenID
  334. }
  335. switch tx.Type {
  336. case common.TxTypeTransfer:
  337. // go to the MT account of sender and receiver, and update
  338. // balance & nonce
  339. tmpTx, err := tx.Tx()
  340. if err != nil {
  341. return nil, nil, false, err
  342. }
  343. err = s.applyTransfer(tmpTx, auxToIdx)
  344. if err != nil {
  345. return nil, nil, false, err
  346. }
  347. case common.TxTypeExit:
  348. // execute exit flow
  349. tmpTx, err := tx.Tx()
  350. if err != nil {
  351. return nil, nil, false, err
  352. }
  353. exitAccount, newExit, err := s.applyExit(exitTree, tmpTx)
  354. if err != nil {
  355. return nil, nil, false, err
  356. }
  357. return &tx.FromIdx, exitAccount, newExit, nil
  358. default:
  359. }
  360. return nil, nil, false, nil
  361. }
  362. // applyCreateAccount creates a new account in the account of the depositer, it
  363. // stores the deposit value
  364. func (s *StateDB) applyCreateAccount(tx *common.L1Tx) error {
  365. account := &common.Account{
  366. TokenID: tx.TokenID,
  367. Nonce: 0,
  368. Balance: tx.LoadAmount,
  369. PublicKey: tx.FromBJJ,
  370. EthAddr: tx.FromEthAddr,
  371. }
  372. p, err := s.CreateAccount(common.Idx(s.idx+1), account)
  373. if err != nil {
  374. return err
  375. }
  376. if s.zki != nil {
  377. s.zki.TokenID1[s.i] = tx.TokenID.BigInt()
  378. s.zki.Nonce1[s.i] = big.NewInt(0)
  379. if babyjub.PointCoordSign(tx.FromBJJ.X) {
  380. s.zki.Sign1[s.i] = big.NewInt(1)
  381. }
  382. s.zki.Ay1[s.i] = tx.FromBJJ.Y
  383. s.zki.Balance1[s.i] = tx.LoadAmount
  384. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(tx.FromEthAddr)
  385. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  386. if p.IsOld0 {
  387. s.zki.IsOld0_1[s.i] = big.NewInt(1)
  388. }
  389. s.zki.OldKey1[s.i] = p.OldKey.BigInt()
  390. s.zki.OldValue1[s.i] = p.OldValue.BigInt()
  391. }
  392. s.idx = s.idx + 1
  393. return s.setIdx(s.idx)
  394. }
  395. // applyDeposit updates the balance in the account of the depositer, if
  396. // andTransfer parameter is set to true, the method will also apply the
  397. // Transfer of the L1Tx/DepositTransfer
  398. func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
  399. // deposit the tx.LoadAmount into the sender account
  400. accSender, err := s.GetAccount(tx.FromIdx)
  401. if err != nil {
  402. return err
  403. }
  404. accSender.Balance = new(big.Int).Add(accSender.Balance, tx.LoadAmount)
  405. // in case that the tx is a L1Tx>DepositTransfer
  406. var accReceiver *common.Account
  407. if transfer {
  408. accReceiver, err = s.GetAccount(&tx.ToIdx)
  409. if err != nil {
  410. return err
  411. }
  412. // subtract amount to the sender
  413. accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
  414. // add amount to the receiver
  415. accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
  416. }
  417. // update sender account in localStateDB
  418. p, err := s.UpdateAccount(tx.FromIdx, accSender)
  419. if err != nil {
  420. return err
  421. }
  422. if s.zki != nil {
  423. s.zki.TokenID1[s.i] = accSender.TokenID.BigInt()
  424. s.zki.Nonce1[s.i] = accSender.Nonce.BigInt()
  425. if babyjub.PointCoordSign(accSender.PublicKey.X) {
  426. s.zki.Sign1[s.i] = big.NewInt(1)
  427. }
  428. s.zki.Ay1[s.i] = accSender.PublicKey.Y
  429. s.zki.Balance1[s.i] = accSender.Balance
  430. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(accSender.EthAddr)
  431. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  432. // IsOld0_1, OldKey1, OldValue1 not needed as this is not an insert
  433. }
  434. // this is done after updating Sender Account (depositer)
  435. if transfer {
  436. // update receiver account in localStateDB
  437. p, err := s.UpdateAccount(&tx.ToIdx, accReceiver)
  438. if err != nil {
  439. return err
  440. }
  441. if s.zki != nil {
  442. s.zki.TokenID2[s.i] = accReceiver.TokenID.BigInt()
  443. s.zki.Nonce2[s.i] = accReceiver.Nonce.BigInt()
  444. if babyjub.PointCoordSign(accReceiver.PublicKey.X) {
  445. s.zki.Sign2[s.i] = big.NewInt(1)
  446. }
  447. s.zki.Ay2[s.i] = accReceiver.PublicKey.Y
  448. s.zki.Balance2[s.i] = accReceiver.Balance
  449. s.zki.EthAddr2[s.i] = common.EthAddrToBigInt(accReceiver.EthAddr)
  450. s.zki.Siblings2[s.i] = siblingsToZKInputFormat(p.Siblings)
  451. // IsOld0_2, OldKey2, OldValue2 not needed as this is not an insert
  452. }
  453. }
  454. return nil
  455. }
  456. // applyTransfer updates the balance & nonce in the account of the sender, and
  457. // the balance in the account of the receiver.
  458. // Parameter 'toIdx' should be at 0 if the tx already has tx.ToIdx!=0, if
  459. // tx.ToIdx==0, then toIdx!=0, and will be used the toIdx parameter as Idx of
  460. // the receiver. This parameter is used when the tx.ToIdx is not specified and
  461. // the real ToIdx is found trhrough the ToEthAddr or ToBJJ.
  462. func (s *StateDB) applyTransfer(tx *common.Tx, auxToIdx common.Idx) error {
  463. if auxToIdx == 0 {
  464. if tx.ToIdx == nil {
  465. return errors.New("tx.ToIdx cannot be nil if auxToIdx is 0")
  466. }
  467. auxToIdx = *tx.ToIdx
  468. }
  469. // get sender and receiver accounts from localStateDB
  470. accSender, err := s.GetAccount(tx.FromIdx)
  471. if err != nil {
  472. return err
  473. }
  474. accReceiver, err := s.GetAccount(&auxToIdx)
  475. if err != nil {
  476. return err
  477. }
  478. // increment nonce
  479. accSender.Nonce++
  480. // subtract amount to the sender
  481. accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
  482. // add amount to the receiver
  483. accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
  484. // update sender account in localStateDB
  485. pSender, err := s.UpdateAccount(tx.FromIdx, accSender)
  486. if err != nil {
  487. return err
  488. }
  489. if s.zki != nil {
  490. s.zki.TokenID1[s.i] = accSender.TokenID.BigInt()
  491. s.zki.Nonce1[s.i] = accSender.Nonce.BigInt()
  492. if babyjub.PointCoordSign(accSender.PublicKey.X) {
  493. s.zki.Sign1[s.i] = big.NewInt(1)
  494. }
  495. s.zki.Ay1[s.i] = accSender.PublicKey.Y
  496. s.zki.Balance1[s.i] = accSender.Balance
  497. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(accSender.EthAddr)
  498. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(pSender.Siblings)
  499. }
  500. // update receiver account in localStateDB
  501. pReceiver, err := s.UpdateAccount(&auxToIdx, accReceiver)
  502. if err != nil {
  503. return err
  504. }
  505. if s.zki != nil {
  506. s.zki.TokenID2[s.i] = accReceiver.TokenID.BigInt()
  507. s.zki.Nonce2[s.i] = accReceiver.Nonce.BigInt()
  508. if babyjub.PointCoordSign(accReceiver.PublicKey.X) {
  509. s.zki.Sign2[s.i] = big.NewInt(1)
  510. }
  511. s.zki.Ay2[s.i] = accReceiver.PublicKey.Y
  512. s.zki.Balance2[s.i] = accReceiver.Balance
  513. s.zki.EthAddr2[s.i] = common.EthAddrToBigInt(accReceiver.EthAddr)
  514. s.zki.Siblings2[s.i] = siblingsToZKInputFormat(pReceiver.Siblings)
  515. }
  516. return nil
  517. }
  518. // applyCreateAccountDepositTransfer, in a single tx, creates a new account,
  519. // makes a deposit, and performs a transfer to another account
  520. func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
  521. accSender := &common.Account{
  522. TokenID: tx.TokenID,
  523. Nonce: 0,
  524. Balance: tx.LoadAmount,
  525. PublicKey: tx.FromBJJ,
  526. EthAddr: tx.FromEthAddr,
  527. }
  528. accSender.Balance = new(big.Int).Add(accSender.Balance, tx.LoadAmount)
  529. accReceiver, err := s.GetAccount(&tx.ToIdx)
  530. if err != nil {
  531. return err
  532. }
  533. // subtract amount to the sender
  534. accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
  535. // add amount to the receiver
  536. accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
  537. // create Account of the Sender
  538. p, err := s.CreateAccount(common.Idx(s.idx+1), accSender)
  539. if err != nil {
  540. return err
  541. }
  542. if s.zki != nil {
  543. s.zki.TokenID1[s.i] = tx.TokenID.BigInt()
  544. s.zki.Nonce1[s.i] = big.NewInt(0)
  545. if babyjub.PointCoordSign(tx.FromBJJ.X) {
  546. s.zki.Sign1[s.i] = big.NewInt(1)
  547. }
  548. s.zki.Ay1[s.i] = tx.FromBJJ.Y
  549. s.zki.Balance1[s.i] = tx.LoadAmount
  550. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(tx.FromEthAddr)
  551. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  552. if p.IsOld0 {
  553. s.zki.IsOld0_1[s.i] = big.NewInt(1)
  554. }
  555. s.zki.OldKey1[s.i] = p.OldKey.BigInt()
  556. s.zki.OldValue1[s.i] = p.OldValue.BigInt()
  557. }
  558. // update receiver account in localStateDB
  559. p, err = s.UpdateAccount(&tx.ToIdx, accReceiver)
  560. if err != nil {
  561. return err
  562. }
  563. if s.zki != nil {
  564. s.zki.TokenID2[s.i] = accReceiver.TokenID.BigInt()
  565. s.zki.Nonce2[s.i] = accReceiver.Nonce.BigInt()
  566. if babyjub.PointCoordSign(accReceiver.PublicKey.X) {
  567. s.zki.Sign2[s.i] = big.NewInt(1)
  568. }
  569. s.zki.Ay2[s.i] = accReceiver.PublicKey.Y
  570. s.zki.Balance2[s.i] = accReceiver.Balance
  571. s.zki.EthAddr2[s.i] = common.EthAddrToBigInt(accReceiver.EthAddr)
  572. s.zki.Siblings2[s.i] = siblingsToZKInputFormat(p.Siblings)
  573. }
  574. s.idx = s.idx + 1
  575. return s.setIdx(s.idx)
  576. }
  577. // It returns the ExitAccount and a boolean determining if the Exit created a
  578. // new Leaf in the ExitTree.
  579. func (s *StateDB) applyExit(exitTree *merkletree.MerkleTree, tx *common.Tx) (*common.Account, bool, error) {
  580. // 0. subtract tx.Amount from current Account in StateMT
  581. // add the tx.Amount into the Account (tx.FromIdx) in the ExitMT
  582. acc, err := s.GetAccount(tx.FromIdx)
  583. if err != nil {
  584. return nil, false, err
  585. }
  586. acc.Balance = new(big.Int).Sub(acc.Balance, tx.Amount)
  587. p, err := s.UpdateAccount(tx.FromIdx, acc)
  588. if err != nil {
  589. return nil, false, err
  590. }
  591. if s.zki != nil {
  592. s.zki.TokenID1[s.i] = acc.TokenID.BigInt()
  593. s.zki.Nonce1[s.i] = acc.Nonce.BigInt()
  594. if babyjub.PointCoordSign(acc.PublicKey.X) {
  595. s.zki.Sign1[s.i] = big.NewInt(1)
  596. }
  597. s.zki.Ay1[s.i] = acc.PublicKey.Y
  598. s.zki.Balance1[s.i] = acc.Balance
  599. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(acc.EthAddr)
  600. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  601. }
  602. if exitTree == nil {
  603. return nil, false, nil
  604. }
  605. exitAccount, err := getAccountInTreeDB(exitTree.DB(), tx.FromIdx)
  606. if err == db.ErrNotFound {
  607. // 1a. if idx does not exist in exitTree:
  608. // add new leaf 'ExitTreeLeaf', where ExitTreeLeaf.Balance = exitAmount (exitAmount=tx.Amount)
  609. exitAccount := &common.Account{
  610. TokenID: acc.TokenID,
  611. Nonce: common.Nonce(1),
  612. Balance: tx.Amount,
  613. PublicKey: acc.PublicKey,
  614. EthAddr: acc.EthAddr,
  615. }
  616. _, err = createAccountInTreeDB(exitTree.DB(), exitTree, tx.FromIdx, exitAccount)
  617. return exitAccount, true, err
  618. } else if err != nil {
  619. return exitAccount, false, err
  620. }
  621. // 1b. if idx already exist in exitTree:
  622. // update account, where account.Balance += exitAmount
  623. exitAccount.Balance = new(big.Int).Add(exitAccount.Balance, tx.Amount)
  624. _, err = updateAccountInTreeDB(exitTree.DB(), exitTree, tx.FromIdx, exitAccount)
  625. return exitAccount, false, err
  626. }
  627. // getIdx returns the stored Idx from the localStateDB, which is the last Idx
  628. // used for an Account in the localStateDB.
  629. func (s *StateDB) getIdx() (common.Idx, error) {
  630. idxBytes, err := s.DB().Get(keyidx)
  631. if err == db.ErrNotFound {
  632. return 0, nil
  633. }
  634. if err != nil {
  635. return 0, err
  636. }
  637. return common.IdxFromBytes(idxBytes[:4])
  638. }
  639. // setIdx stores Idx in the localStateDB
  640. func (s *StateDB) setIdx(idx common.Idx) error {
  641. tx, err := s.DB().NewTx()
  642. if err != nil {
  643. return err
  644. }
  645. idxBytes, err := idx.Bytes()
  646. if err != nil {
  647. return err
  648. }
  649. err = tx.Put(keyidx, idxBytes[:])
  650. if err != nil {
  651. return err
  652. }
  653. if err := tx.Commit(); err != nil {
  654. return err
  655. }
  656. return nil
  657. }