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.

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