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.

717 lines
21 KiB

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