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.

778 lines
24 KiB

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