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.

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