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.

693 lines
21 KiB

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