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.

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