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.

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