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.

229 lines
5.8 KiB

  1. package batchbuilder
  2. import (
  3. ethCommon "github.com/ethereum/go-ethereum/common"
  4. "github.com/hermeznetwork/hermez-node/common"
  5. "github.com/iden3/go-merkletree"
  6. "github.com/iden3/go-merkletree/db"
  7. "github.com/iden3/go-merkletree/db/memory"
  8. )
  9. // ConfigCircuit contains the circuit configuration
  10. type ConfigCircuit struct {
  11. TxsMax uint64
  12. L1TxsMax uint64
  13. SMTLevelsMax uint64
  14. }
  15. // BatchBuilder implements the batch builder type, which contains the functionallities
  16. type BatchBuilder struct {
  17. StateDB db.Storage // where the MTs will be stored by the Synchronizer
  18. idx uint64
  19. mt *merkletree.MerkleTree
  20. configCircuits []ConfigCircuit
  21. }
  22. // ConfigBatch contains the batch configuration
  23. type ConfigBatch struct {
  24. CoordinatorAddress ethCommon.Address
  25. }
  26. // NewBatchBuilder constructs a new BatchBuilder, and executes the bb.Reset
  27. // method
  28. func NewBatchBuilder(stateDB db.Storage, configCircuits []ConfigCircuit, batchNum int, idx, nLevels uint64) (*BatchBuilder, error) {
  29. localMt, err := merkletree.NewMerkleTree(memory.NewMemoryStorage(), int(nLevels))
  30. if err != nil {
  31. return nil, err
  32. }
  33. bb := BatchBuilder{
  34. StateDB: stateDB,
  35. idx: idx,
  36. mt: localMt,
  37. configCircuits: configCircuits,
  38. }
  39. err = bb.Reset(batchNum, idx, true)
  40. return &bb, err
  41. }
  42. // Reset tells the BatchBuilder to reset it's internal state to the required
  43. // `batchNum`. If `fromSynchronizer` is true, the BatchBuilder must take a
  44. // copy of the rollup state from the Synchronizer at that `batchNum`, otherwise
  45. // it can just roll back the internal copy.
  46. func (bb *BatchBuilder) Reset(batchNum int, idx uint64, fromSynchronizer bool) error {
  47. // TODO
  48. return nil
  49. }
  50. // BuildBatch takes the transactions and returns the common.ZKInputs of the next batch
  51. func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) {
  52. for _, tx := range l1usertxs {
  53. err := bb.processL1Tx(tx)
  54. if err != nil {
  55. return nil, err
  56. }
  57. }
  58. for _, tx := range l1coordinatortxs {
  59. err := bb.processL1Tx(tx)
  60. if err != nil {
  61. return nil, err
  62. }
  63. }
  64. for _, tx := range l2txs {
  65. switch tx.Type {
  66. case common.TxTypeTransfer:
  67. // go to the MT account of sender and receiver, and update
  68. // balance & nonce
  69. err := bb.applyTransfer(tx.Tx)
  70. if err != nil {
  71. return nil, err
  72. }
  73. case common.TxTypeExit:
  74. // execute exit flow
  75. default:
  76. }
  77. }
  78. return nil, nil
  79. }
  80. func (bb *BatchBuilder) processL1Tx(tx common.L1Tx) error {
  81. switch tx.Type {
  82. case common.TxTypeForceTransfer, common.TxTypeTransfer:
  83. // go to the MT account of sender and receiver, and update balance
  84. // & nonce
  85. err := bb.applyTransfer(tx.Tx)
  86. if err != nil {
  87. return err
  88. }
  89. case common.TxTypeCreateAccountDeposit:
  90. // add new account to the MT, update balance of the MT account
  91. err := bb.applyCreateLeaf(tx)
  92. if err != nil {
  93. return err
  94. }
  95. case common.TxTypeDeposit: // TODO check if this type will ever exist, or will be TxTypeDepositAndTransfer with transfer 0 value
  96. // update balance of the MT account
  97. err := bb.applyDeposit(tx, false)
  98. if err != nil {
  99. return err
  100. }
  101. case common.TxTypeDepositAndTransfer:
  102. // update balance in MT account, update balance & nonce of sender
  103. // & receiver
  104. err := bb.applyDeposit(tx, true)
  105. if err != nil {
  106. return err
  107. }
  108. case common.TxTypeCreateAccountDepositAndTransfer:
  109. // add new account to the merkletree, update balance in MT account,
  110. // update balance & nonce of sender & receiver
  111. err := bb.applyCreateLeaf(tx)
  112. if err != nil {
  113. return err
  114. }
  115. err = bb.applyTransfer(tx.Tx)
  116. if err != nil {
  117. return err
  118. }
  119. case common.TxTypeExit:
  120. // execute exit flow
  121. default:
  122. }
  123. return nil
  124. }
  125. // applyCreateLeaf creates a new account in the account of the depositer, it stores
  126. // the deposit value
  127. func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error {
  128. account := common.Account{
  129. TokenID: tx.TokenID,
  130. Nonce: 0,
  131. Balance: tx.LoadAmount,
  132. PublicKey: &tx.FromBJJ,
  133. EthAddr: tx.FromEthAddr,
  134. }
  135. v, err := account.HashValue()
  136. if err != nil {
  137. return err
  138. }
  139. dbTx, err := bb.mt.DB().NewTx()
  140. if err != nil {
  141. return err
  142. }
  143. err = bb.CreateBalance(dbTx, common.Idx(bb.idx+1), account)
  144. if err != nil {
  145. return err
  146. }
  147. accountBytes, err := account.Bytes()
  148. if err != nil {
  149. return err
  150. }
  151. dbTx.Put(v.Bytes(), accountBytes[:])
  152. // if everything is fine, do dbTx & increment idx
  153. if err := dbTx.Commit(); err != nil {
  154. return err
  155. }
  156. bb.idx = bb.idx + 1
  157. return nil
  158. }
  159. // applyDeposit updates the balance in the account of the depositer, if andTransfer parameter is set to true, the method will also apply the Transfer of the L1Tx/DepositAndTransfer
  160. func (bb *BatchBuilder) applyDeposit(tx common.L1Tx, andTransfer bool) error {
  161. dbTx, err := bb.mt.DB().NewTx()
  162. if err != nil {
  163. return err
  164. }
  165. // deposit
  166. err = bb.UpdateBalance(dbTx, tx.FromIdx, tx.LoadAmount, false)
  167. if err != nil {
  168. return err
  169. }
  170. // in case that the tx is a L1Tx>DepositAndTransfer
  171. if andTransfer {
  172. // transact
  173. err = bb.UpdateBalance(dbTx, tx.FromIdx, tx.Tx.Amount, true)
  174. if err != nil {
  175. return err
  176. }
  177. err = bb.UpdateBalance(dbTx, tx.ToIdx, tx.Tx.Amount, false)
  178. if err != nil {
  179. return err
  180. }
  181. }
  182. if err := dbTx.Commit(); err != nil {
  183. return err
  184. }
  185. return nil
  186. }
  187. // applyTransfer updates the balance & nonce in the account of the sender, and the
  188. // balance in the account of the receiver
  189. func (bb *BatchBuilder) applyTransfer(tx common.Tx) error {
  190. dbTx, err := bb.mt.DB().NewTx()
  191. if err != nil {
  192. return err
  193. }
  194. // transact
  195. err = bb.UpdateBalance(dbTx, tx.FromIdx, tx.Amount, true)
  196. if err != nil {
  197. return err
  198. }
  199. err = bb.UpdateBalance(dbTx, tx.ToIdx, tx.Amount, false)
  200. if err != nil {
  201. return err
  202. }
  203. if err := dbTx.Commit(); err != nil {
  204. return err
  205. }
  206. return nil
  207. }