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.

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