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.

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