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.

1005 lines
30 KiB

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