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.

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