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.

844 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("could not get account to determine TokenID of L2Tx: FromIdx %d not found: %s", l2txs[i].FromIdx, 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. return nil, nil, false, err
  368. }
  369. }
  370. // ZKInputs
  371. if s.zki != nil {
  372. // Txs
  373. // s.zki.TxCompressedData[s.i] = tx.TxCompressedData() // uncomment once L1Tx.TxCompressedData is ready
  374. // s.zki.TxCompressedDataV2[s.i] = tx.TxCompressedDataV2() // uncomment once L2Tx.TxCompressedDataV2 is ready
  375. s.zki.FromIdx[s.i] = tx.FromIdx.BigInt()
  376. s.zki.ToIdx[s.i] = tx.ToIdx.BigInt()
  377. // fill AuxToIdx if needed
  378. if tx.ToIdx == 0 {
  379. // use toIdx that can have been filled by tx.ToIdx or
  380. // if tx.Idx==0 (this case), toIdx is filled by the Idx
  381. // from db by ToEthAddr&ToBJJ
  382. s.zki.AuxToIdx[s.i] = tx.AuxToIdx.BigInt()
  383. }
  384. if tx.ToBJJ != nil {
  385. s.zki.ToBJJAy[s.i] = tx.ToBJJ.Y
  386. }
  387. s.zki.ToEthAddr[s.i] = common.EthAddrToBigInt(tx.ToEthAddr)
  388. s.zki.OnChain[s.i] = big.NewInt(0)
  389. s.zki.NewAccount[s.i] = big.NewInt(0)
  390. // L2Txs
  391. // s.zki.RqOffset[s.i] = // TODO Rq once TxSelector is ready
  392. // s.zki.RqTxCompressedDataV2[s.i] = // TODO
  393. // s.zki.RqToEthAddr[s.i] = common.EthAddrToBigInt(tx.RqToEthAddr) // TODO
  394. // s.zki.RqToBJJAy[s.i] = tx.ToBJJ.Y // TODO
  395. signature, err := tx.Signature.Decompress()
  396. if err != nil {
  397. log.Error(err)
  398. return nil, nil, false, err
  399. }
  400. s.zki.S[s.i] = signature.S
  401. s.zki.R8x[s.i] = signature.R8.X
  402. s.zki.R8y[s.i] = signature.R8.Y
  403. }
  404. // if StateDB type==TypeSynchronizer, will need to add Nonce
  405. if s.typ == TypeSynchronizer {
  406. // as type==TypeSynchronizer, always tx.ToIdx!=0
  407. acc, err := s.GetAccount(tx.FromIdx)
  408. if err != nil {
  409. log.Errorw("GetAccount", "fromIdx", tx.FromIdx, "err", err)
  410. return nil, nil, false, err
  411. }
  412. tx.Nonce = acc.Nonce + 1
  413. tx.TokenID = acc.TokenID
  414. }
  415. switch tx.Type {
  416. case common.TxTypeTransfer, common.TxTypeTransferToEthAddr, common.TxTypeTransferToBJJ:
  417. // go to the MT account of sender and receiver, and update
  418. // balance & nonce
  419. err = s.applyTransfer(coordIdxsMap, collectedFees, tx.Tx(), tx.AuxToIdx)
  420. if err != nil {
  421. log.Error(err)
  422. return nil, nil, false, err
  423. }
  424. case common.TxTypeExit:
  425. // execute exit flow
  426. exitAccount, newExit, err := s.applyExit(coordIdxsMap, collectedFees, exitTree, tx.Tx())
  427. if err != nil {
  428. log.Error(err)
  429. return nil, nil, false, err
  430. }
  431. return &tx.FromIdx, exitAccount, newExit, nil
  432. default:
  433. }
  434. return nil, nil, false, nil
  435. }
  436. // applyCreateAccount creates a new account in the account of the depositer, it
  437. // stores the deposit value
  438. func (s *StateDB) applyCreateAccount(tx *common.L1Tx) error {
  439. account := &common.Account{
  440. TokenID: tx.TokenID,
  441. Nonce: 0,
  442. Balance: tx.LoadAmount,
  443. PublicKey: tx.FromBJJ,
  444. EthAddr: tx.FromEthAddr,
  445. }
  446. p, err := s.CreateAccount(common.Idx(s.idx+1), account)
  447. if err != nil {
  448. return err
  449. }
  450. if s.zki != nil {
  451. s.zki.TokenID1[s.i] = tx.TokenID.BigInt()
  452. s.zki.Nonce1[s.i] = big.NewInt(0)
  453. if babyjub.PointCoordSign(tx.FromBJJ.X) {
  454. s.zki.Sign1[s.i] = big.NewInt(1)
  455. }
  456. s.zki.Ay1[s.i] = tx.FromBJJ.Y
  457. s.zki.Balance1[s.i] = tx.LoadAmount
  458. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(tx.FromEthAddr)
  459. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  460. if p.IsOld0 {
  461. s.zki.IsOld0_1[s.i] = big.NewInt(1)
  462. }
  463. s.zki.OldKey1[s.i] = p.OldKey.BigInt()
  464. s.zki.OldValue1[s.i] = p.OldValue.BigInt()
  465. }
  466. s.idx = s.idx + 1
  467. return s.setIdx(s.idx)
  468. }
  469. // applyDeposit updates the balance in the account of the depositer, if
  470. // andTransfer parameter is set to true, the method will also apply the
  471. // Transfer of the L1Tx/DepositTransfer
  472. func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
  473. // deposit the tx.LoadAmount into the sender account
  474. accSender, err := s.GetAccount(tx.FromIdx)
  475. if err != nil {
  476. return err
  477. }
  478. accSender.Balance = new(big.Int).Add(accSender.Balance, tx.LoadAmount)
  479. // in case that the tx is a L1Tx>DepositTransfer
  480. var accReceiver *common.Account
  481. if transfer {
  482. accReceiver, err = s.GetAccount(tx.ToIdx)
  483. if err != nil {
  484. return err
  485. }
  486. // subtract amount to the sender
  487. accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
  488. // add amount to the receiver
  489. accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
  490. }
  491. // update sender account in localStateDB
  492. p, err := s.UpdateAccount(tx.FromIdx, accSender)
  493. if err != nil {
  494. return err
  495. }
  496. if s.zki != nil {
  497. s.zki.TokenID1[s.i] = accSender.TokenID.BigInt()
  498. s.zki.Nonce1[s.i] = accSender.Nonce.BigInt()
  499. if babyjub.PointCoordSign(accSender.PublicKey.X) {
  500. s.zki.Sign1[s.i] = big.NewInt(1)
  501. }
  502. s.zki.Ay1[s.i] = accSender.PublicKey.Y
  503. s.zki.Balance1[s.i] = accSender.Balance
  504. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(accSender.EthAddr)
  505. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  506. // IsOld0_1, OldKey1, OldValue1 not needed as this is not an insert
  507. }
  508. // this is done after updating Sender Account (depositer)
  509. if transfer {
  510. // update receiver account in localStateDB
  511. p, err := s.UpdateAccount(tx.ToIdx, accReceiver)
  512. if err != nil {
  513. return err
  514. }
  515. if s.zki != nil {
  516. s.zki.TokenID2[s.i] = accReceiver.TokenID.BigInt()
  517. s.zki.Nonce2[s.i] = accReceiver.Nonce.BigInt()
  518. if babyjub.PointCoordSign(accReceiver.PublicKey.X) {
  519. s.zki.Sign2[s.i] = big.NewInt(1)
  520. }
  521. s.zki.Ay2[s.i] = accReceiver.PublicKey.Y
  522. s.zki.Balance2[s.i] = accReceiver.Balance
  523. s.zki.EthAddr2[s.i] = common.EthAddrToBigInt(accReceiver.EthAddr)
  524. s.zki.Siblings2[s.i] = siblingsToZKInputFormat(p.Siblings)
  525. // IsOld0_2, OldKey2, OldValue2 not needed as this is not an insert
  526. }
  527. }
  528. return nil
  529. }
  530. // applyTransfer updates the balance & nonce in the account of the sender, and
  531. // the balance in the account of the receiver.
  532. // Parameter 'toIdx' should be at 0 if the tx already has tx.ToIdx!=0, if
  533. // tx.ToIdx==0, then toIdx!=0, and will be used the toIdx parameter as Idx of
  534. // the receiver. This parameter is used when the tx.ToIdx is not specified and
  535. // the real ToIdx is found trhrough the ToEthAddr or ToBJJ.
  536. func (s *StateDB) applyTransfer(coordIdxsMap map[common.TokenID]common.Idx, collectedFees map[common.TokenID]*big.Int,
  537. tx common.Tx, auxToIdx common.Idx) error {
  538. if auxToIdx == common.Idx(0) {
  539. auxToIdx = tx.ToIdx
  540. }
  541. // get sender and receiver accounts from localStateDB
  542. accSender, err := s.GetAccount(tx.FromIdx)
  543. if err != nil {
  544. log.Error(err)
  545. return err
  546. }
  547. accReceiver, err := s.GetAccount(auxToIdx)
  548. if err != nil {
  549. log.Error(err)
  550. return err
  551. }
  552. // increment nonce
  553. accSender.Nonce++
  554. if !tx.IsL1 {
  555. // compute fee and subtract it from the accSender
  556. fee := common.CalcFeeAmount(tx.Amount, *tx.Fee)
  557. feeAndAmount := new(big.Int).Add(tx.Amount, fee)
  558. accSender.Balance = new(big.Int).Sub(accSender.Balance, feeAndAmount)
  559. // send the fee to the Idx of the Coordinator for the TokenID
  560. accCoord, err := s.GetAccount(coordIdxsMap[accSender.TokenID])
  561. if err != nil {
  562. log.Debugw("No coord Idx to receive fee", "tx", tx)
  563. } else {
  564. accCoord.Balance = new(big.Int).Add(accCoord.Balance, fee)
  565. _, err = s.UpdateAccount(coordIdxsMap[accSender.TokenID], accCoord)
  566. if err != nil {
  567. log.Error(err)
  568. return err
  569. }
  570. if s.typ == TypeSynchronizer {
  571. collected := collectedFees[accSender.TokenID]
  572. collected.Add(collected, fee)
  573. }
  574. }
  575. } else {
  576. accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
  577. }
  578. // add amount-feeAmount to the receiver
  579. accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
  580. // update sender account in localStateDB
  581. pSender, err := s.UpdateAccount(tx.FromIdx, accSender)
  582. if err != nil {
  583. log.Error(err)
  584. return err
  585. }
  586. if s.zki != nil {
  587. s.zki.TokenID1[s.i] = accSender.TokenID.BigInt()
  588. s.zki.Nonce1[s.i] = accSender.Nonce.BigInt()
  589. if babyjub.PointCoordSign(accSender.PublicKey.X) {
  590. s.zki.Sign1[s.i] = big.NewInt(1)
  591. }
  592. s.zki.Ay1[s.i] = accSender.PublicKey.Y
  593. s.zki.Balance1[s.i] = accSender.Balance
  594. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(accSender.EthAddr)
  595. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(pSender.Siblings)
  596. }
  597. // update receiver account in localStateDB
  598. pReceiver, err := s.UpdateAccount(auxToIdx, accReceiver)
  599. if err != nil {
  600. return err
  601. }
  602. if s.zki != nil {
  603. s.zki.TokenID2[s.i] = accReceiver.TokenID.BigInt()
  604. s.zki.Nonce2[s.i] = accReceiver.Nonce.BigInt()
  605. if babyjub.PointCoordSign(accReceiver.PublicKey.X) {
  606. s.zki.Sign2[s.i] = big.NewInt(1)
  607. }
  608. s.zki.Ay2[s.i] = accReceiver.PublicKey.Y
  609. s.zki.Balance2[s.i] = accReceiver.Balance
  610. s.zki.EthAddr2[s.i] = common.EthAddrToBigInt(accReceiver.EthAddr)
  611. s.zki.Siblings2[s.i] = siblingsToZKInputFormat(pReceiver.Siblings)
  612. }
  613. return nil
  614. }
  615. // applyCreateAccountDepositTransfer, in a single tx, creates a new account,
  616. // makes a deposit, and performs a transfer to another account
  617. func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
  618. accSender := &common.Account{
  619. TokenID: tx.TokenID,
  620. Nonce: 0,
  621. Balance: tx.LoadAmount,
  622. PublicKey: tx.FromBJJ,
  623. EthAddr: tx.FromEthAddr,
  624. }
  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. } else {
  705. acc.Balance = new(big.Int).Sub(acc.Balance, tx.Amount)
  706. }
  707. p, err := s.UpdateAccount(tx.FromIdx, acc)
  708. if err != nil {
  709. return nil, false, err
  710. }
  711. if s.zki != nil {
  712. s.zki.TokenID1[s.i] = acc.TokenID.BigInt()
  713. s.zki.Nonce1[s.i] = acc.Nonce.BigInt()
  714. if babyjub.PointCoordSign(acc.PublicKey.X) {
  715. s.zki.Sign1[s.i] = big.NewInt(1)
  716. }
  717. s.zki.Ay1[s.i] = acc.PublicKey.Y
  718. s.zki.Balance1[s.i] = acc.Balance
  719. s.zki.EthAddr1[s.i] = common.EthAddrToBigInt(acc.EthAddr)
  720. s.zki.Siblings1[s.i] = siblingsToZKInputFormat(p.Siblings)
  721. }
  722. if exitTree == nil {
  723. return nil, false, nil
  724. }
  725. exitAccount, err := getAccountInTreeDB(exitTree.DB(), tx.FromIdx)
  726. if err == db.ErrNotFound {
  727. // 1a. if idx does not exist in exitTree:
  728. // add new leaf 'ExitTreeLeaf', where ExitTreeLeaf.Balance = exitAmount (exitAmount=tx.Amount)
  729. exitAccount := &common.Account{
  730. TokenID: acc.TokenID,
  731. Nonce: common.Nonce(1),
  732. Balance: tx.Amount,
  733. PublicKey: acc.PublicKey,
  734. EthAddr: acc.EthAddr,
  735. }
  736. _, err = createAccountInTreeDB(exitTree.DB(), exitTree, tx.FromIdx, exitAccount)
  737. return exitAccount, true, err
  738. } else if err != nil {
  739. return exitAccount, false, err
  740. }
  741. // 1b. if idx already exist in exitTree:
  742. // update account, where account.Balance += exitAmount
  743. exitAccount.Balance = new(big.Int).Add(exitAccount.Balance, tx.Amount)
  744. _, err = updateAccountInTreeDB(exitTree.DB(), exitTree, tx.FromIdx, exitAccount)
  745. return exitAccount, false, err
  746. }
  747. // getIdx returns the stored Idx from the localStateDB, which is the last Idx
  748. // used for an Account in the localStateDB.
  749. func (s *StateDB) getIdx() (common.Idx, error) {
  750. idxBytes, err := s.DB().Get(keyidx)
  751. if err == db.ErrNotFound {
  752. return 0, nil
  753. }
  754. if err != nil {
  755. return 0, err
  756. }
  757. return common.IdxFromBytes(idxBytes[:4])
  758. }
  759. // setIdx stores Idx in the localStateDB
  760. func (s *StateDB) setIdx(idx common.Idx) error {
  761. tx, err := s.DB().NewTx()
  762. if err != nil {
  763. return err
  764. }
  765. idxBytes, err := idx.Bytes()
  766. if err != nil {
  767. return err
  768. }
  769. err = tx.Put(keyidx, idxBytes[:])
  770. if err != nil {
  771. return err
  772. }
  773. if err := tx.Commit(); err != nil {
  774. return err
  775. }
  776. return nil
  777. }