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.

841 lines
26 KiB

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