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.

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