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.

301 lines
9.4 KiB

  1. package zkproof
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. "testing"
  9. "time"
  10. "github.com/hermeznetwork/hermez-node/common"
  11. "github.com/hermeznetwork/hermez-node/db/statedb"
  12. "github.com/hermeznetwork/hermez-node/log"
  13. "github.com/hermeznetwork/hermez-node/prover"
  14. "github.com/hermeznetwork/hermez-node/test/til"
  15. "github.com/hermeznetwork/hermez-node/test/txsets"
  16. "github.com/hermeznetwork/hermez-node/txprocessor"
  17. "github.com/stretchr/testify/assert"
  18. "github.com/stretchr/testify/require"
  19. )
  20. var proofServerURL string
  21. const pollInterval = 200 * time.Millisecond
  22. func TestMain(m *testing.M) {
  23. exitVal := 0
  24. proofServerURL = os.Getenv("PROOF_SERVER_URL")
  25. exitVal = m.Run()
  26. os.Exit(exitVal)
  27. }
  28. const MaxTx = 352
  29. const NLevels = 32
  30. const MaxL1Tx = 256
  31. const MaxFeeTx = 64
  32. const ChainID uint16 = 1
  33. var txprocConfig = txprocessor.Config{
  34. NLevels: uint32(NLevels),
  35. MaxTx: MaxTx,
  36. MaxL1Tx: MaxL1Tx,
  37. MaxFeeTx: MaxFeeTx,
  38. ChainID: ChainID,
  39. }
  40. func initStateDB(t *testing.T, typ statedb.TypeStateDB) *statedb.StateDB {
  41. dir, err := ioutil.TempDir("", "tmpdb")
  42. require.NoError(t, err)
  43. defer assert.Nil(t, os.RemoveAll(dir))
  44. sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: typ, NLevels: NLevels})
  45. require.NoError(t, err)
  46. return sdb
  47. }
  48. func sendProofAndCheckResp(t *testing.T, zki *common.ZKInputs) {
  49. if proofServerURL == "" {
  50. log.Debug("No PROOF_SERVER_URL defined, not using ProofServer")
  51. return
  52. }
  53. log.Infof("sending proof to %s", proofServerURL)
  54. // Store zkinputs json for debugging purposes
  55. zkInputsJSON, err := json.Marshal(zki)
  56. require.NoError(t, err)
  57. err = ioutil.WriteFile("/tmp/dbgZKInputs.json", zkInputsJSON, 0640) //nolint:gosec
  58. require.NoError(t, err)
  59. proofServerClient := prover.NewProofServerClient(proofServerURL, pollInterval)
  60. err = proofServerClient.WaitReady(context.Background())
  61. require.NoError(t, err)
  62. err = proofServerClient.CalculateProof(context.Background(), zki)
  63. require.NoError(t, err)
  64. proof, pubInputs, err := proofServerClient.GetProof(context.Background())
  65. require.NoError(t, err)
  66. fmt.Printf("proof: %#v\n", proof)
  67. fmt.Printf("pubInputs: %#v\n", pubInputs)
  68. }
  69. func TestZKInputsEmpty(t *testing.T) {
  70. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  71. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  72. coordIdxs := []common.Idx{}
  73. l1UserTxs := []common.L1Tx{}
  74. l1CoordTxs := []common.L1Tx{}
  75. l2Txs := []common.PoolL2Tx{}
  76. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  77. require.NoError(t, err)
  78. sendProofAndCheckResp(t, ptOut.ZKInputs) // test empty batch ZKInputs
  79. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs = txsets.GenerateTxsZKInputs0(t, ChainID)
  80. _, err = tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  81. require.NoError(t, err)
  82. coordIdxs = []common.Idx{}
  83. l1UserTxs = []common.L1Tx{}
  84. l1CoordTxs = []common.L1Tx{}
  85. l2Txs = []common.PoolL2Tx{}
  86. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  87. require.NoError(t, err)
  88. sendProofAndCheckResp(t, ptOut.ZKInputs) // test empty batch ZKInputs after a non-empty batch
  89. }
  90. func TestZKInputs0(t *testing.T) {
  91. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  92. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs0(t, ChainID)
  93. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  94. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  95. require.NoError(t, err)
  96. sendProofAndCheckResp(t, ptOut.ZKInputs)
  97. }
  98. func TestZKInputs1(t *testing.T) {
  99. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  100. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs1(t, ChainID)
  101. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  102. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  103. require.NoError(t, err)
  104. sendProofAndCheckResp(t, ptOut.ZKInputs)
  105. }
  106. func TestZKInputs2(t *testing.T) {
  107. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  108. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs2(t, ChainID)
  109. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  110. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  111. require.NoError(t, err)
  112. sendProofAndCheckResp(t, ptOut.ZKInputs)
  113. }
  114. func TestZKInputs3(t *testing.T) {
  115. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  116. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs3(t, ChainID)
  117. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  118. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  119. require.NoError(t, err)
  120. sendProofAndCheckResp(t, ptOut.ZKInputs)
  121. }
  122. func TestZKInputs4(t *testing.T) {
  123. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  124. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs4(t, ChainID)
  125. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  126. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  127. require.NoError(t, err)
  128. sendProofAndCheckResp(t, ptOut.ZKInputs)
  129. }
  130. func TestZKInputs5(t *testing.T) {
  131. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  132. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs5(t, ChainID)
  133. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  134. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  135. require.NoError(t, err)
  136. sendProofAndCheckResp(t, ptOut.ZKInputs)
  137. }
  138. func TestZKInputs6(t *testing.T) {
  139. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  140. tc := til.NewContext(ChainID, common.RollupConstMaxL1UserTx)
  141. blocks, err := tc.GenerateBlocks(txsets.SetBlockchainMinimumFlow0)
  142. require.NoError(t, err)
  143. // restart nonces of TilContext, as will be set by generating directly
  144. // the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
  145. tc.RestartNonces()
  146. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  147. // batch1
  148. ptOut, err := tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  149. require.NoError(t, err)
  150. sendProofAndCheckResp(t, ptOut.ZKInputs)
  151. // batch2
  152. l1UserTxs := []common.L1Tx{}
  153. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  154. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  155. require.NoError(t, err)
  156. sendProofAndCheckResp(t, ptOut.ZKInputs)
  157. // batch3
  158. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
  159. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  160. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  161. require.NoError(t, err)
  162. sendProofAndCheckResp(t, ptOut.ZKInputs)
  163. // batch4
  164. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
  165. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
  166. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
  167. require.NoError(t, err)
  168. sendProofAndCheckResp(t, ptOut.ZKInputs)
  169. // batch5
  170. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
  171. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
  172. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
  173. require.NoError(t, err)
  174. sendProofAndCheckResp(t, ptOut.ZKInputs)
  175. // batch6
  176. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
  177. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
  178. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
  179. require.NoError(t, err)
  180. sendProofAndCheckResp(t, ptOut.ZKInputs)
  181. // batch7
  182. // simulate the PoolL2Txs of the batch7
  183. batchPoolL2 := `
  184. Type: PoolL2
  185. PoolTransferToEthAddr(1) A-B: 200 (126)
  186. PoolTransferToEthAddr(0) B-C: 100 (126)`
  187. poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
  188. require.NoError(t, err)
  189. // Coordinator Idx where to send the fees
  190. coordIdxs := []common.Idx{261, 262}
  191. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
  192. l2Txs = poolL2Txs
  193. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
  194. blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
  195. require.NoError(t, err)
  196. sendProofAndCheckResp(t, ptOut.ZKInputs)
  197. // batch8
  198. // simulate the PoolL2Txs of the batch8
  199. batchPoolL2 = `
  200. Type: PoolL2
  201. PoolTransfer(0) A-B: 100 (126)
  202. PoolTransfer(0) C-A: 50 (126)
  203. PoolTransfer(1) B-C: 100 (126)
  204. PoolExit(0) A: 100 (126)`
  205. poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
  206. require.NoError(t, err)
  207. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
  208. l2Txs = poolL2Txs
  209. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
  210. blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
  211. require.NoError(t, err)
  212. sendProofAndCheckResp(t, ptOut.ZKInputs)
  213. // batch9
  214. // simulate the PoolL2Txs of the batch9
  215. batchPoolL2 = `
  216. Type: PoolL2
  217. PoolTransfer(0) D-A: 300 (126)
  218. PoolTransfer(0) B-D: 100 (126)`
  219. poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
  220. require.NoError(t, err)
  221. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
  222. l2Txs = poolL2Txs
  223. coordIdxs = []common.Idx{262}
  224. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
  225. blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  226. require.NoError(t, err)
  227. sendProofAndCheckResp(t, ptOut.ZKInputs)
  228. // batch10
  229. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
  230. l2Txs = []common.PoolL2Tx{}
  231. coordIdxs = []common.Idx{}
  232. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
  233. blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  234. require.NoError(t, err)
  235. sendProofAndCheckResp(t, ptOut.ZKInputs)
  236. }