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.

227 lines
6.3 KiB

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