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.

296 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 = 376
  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. // Store zkinputs json for debugging purposes
  54. zkInputsJSON, err := json.Marshal(zki)
  55. require.NoError(t, err)
  56. err = ioutil.WriteFile("/tmp/dbgZKInputs.json", zkInputsJSON, 0640) //nolint:gosec
  57. require.NoError(t, err)
  58. proofServerClient := prover.NewProofServerClient(proofServerURL, pollInterval)
  59. err = proofServerClient.WaitReady(context.Background())
  60. require.NoError(t, err)
  61. err = proofServerClient.CalculateProof(context.Background(), zki)
  62. require.NoError(t, err)
  63. proof, pubInputs, err := proofServerClient.GetProof(context.Background())
  64. require.NoError(t, err)
  65. fmt.Printf("proof: %#v\n", proof)
  66. fmt.Printf("pubInputs: %#v\n", pubInputs)
  67. }
  68. func TestZKInputsEmpty(t *testing.T) {
  69. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  70. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  71. coordIdxs := []common.Idx{}
  72. l1UserTxs := []common.L1Tx{}
  73. l1CoordTxs := []common.L1Tx{}
  74. l2Txs := []common.PoolL2Tx{}
  75. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  76. require.NoError(t, err)
  77. sendProofAndCheckResp(t, ptOut.ZKInputs) // test empty batch ZKInputs
  78. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs = txsets.GenerateTxsZKInputs0(t, ChainID)
  79. _, err = tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  80. require.NoError(t, err)
  81. coordIdxs = []common.Idx{}
  82. l1UserTxs = []common.L1Tx{}
  83. l1CoordTxs = []common.L1Tx{}
  84. l2Txs = []common.PoolL2Tx{}
  85. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  86. require.NoError(t, err)
  87. sendProofAndCheckResp(t, ptOut.ZKInputs) // test empty batch ZKInputs after a non-empty batch
  88. }
  89. func TestZKInputs0(t *testing.T) {
  90. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  91. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs0(t, ChainID)
  92. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  93. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  94. require.NoError(t, err)
  95. sendProofAndCheckResp(t, ptOut.ZKInputs)
  96. }
  97. func TestZKInputs1(t *testing.T) {
  98. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  99. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs1(t, ChainID)
  100. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  101. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  102. require.NoError(t, err)
  103. sendProofAndCheckResp(t, ptOut.ZKInputs)
  104. }
  105. func TestZKInputs2(t *testing.T) {
  106. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  107. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs2(t, ChainID)
  108. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  109. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  110. require.NoError(t, err)
  111. sendProofAndCheckResp(t, ptOut.ZKInputs)
  112. }
  113. func TestZKInputs3(t *testing.T) {
  114. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  115. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs3(t, ChainID)
  116. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  117. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  118. require.NoError(t, err)
  119. sendProofAndCheckResp(t, ptOut.ZKInputs)
  120. }
  121. func TestZKInputs4(t *testing.T) {
  122. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  123. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs4(t, ChainID)
  124. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  125. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  126. require.NoError(t, err)
  127. sendProofAndCheckResp(t, ptOut.ZKInputs)
  128. }
  129. func TestZKInputs5(t *testing.T) {
  130. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  131. _, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs5(t, ChainID)
  132. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  133. ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
  134. require.NoError(t, err)
  135. sendProofAndCheckResp(t, ptOut.ZKInputs)
  136. }
  137. func TestZKInputs6(t *testing.T) {
  138. sdb := initStateDB(t, statedb.TypeBatchBuilder)
  139. tc := til.NewContext(ChainID, common.RollupConstMaxL1UserTx)
  140. blocks, err := tc.GenerateBlocks(txsets.SetBlockchainMinimumFlow0)
  141. require.NoError(t, err)
  142. // restart nonces of TilContext, as will be set by generating directly
  143. // the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
  144. tc.RestartNonces()
  145. tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
  146. // batch1
  147. ptOut, err := tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  148. require.NoError(t, err)
  149. sendProofAndCheckResp(t, ptOut.ZKInputs)
  150. // batch2
  151. l1UserTxs := []common.L1Tx{}
  152. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  153. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  154. require.NoError(t, err)
  155. sendProofAndCheckResp(t, ptOut.ZKInputs)
  156. // batch3
  157. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
  158. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  159. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  160. require.NoError(t, err)
  161. sendProofAndCheckResp(t, ptOut.ZKInputs)
  162. // batch4
  163. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
  164. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
  165. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
  166. require.NoError(t, err)
  167. sendProofAndCheckResp(t, ptOut.ZKInputs)
  168. // batch5
  169. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
  170. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
  171. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
  172. require.NoError(t, err)
  173. sendProofAndCheckResp(t, ptOut.ZKInputs)
  174. // batch6
  175. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
  176. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
  177. ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
  178. require.NoError(t, err)
  179. sendProofAndCheckResp(t, ptOut.ZKInputs)
  180. // batch7
  181. // simulate the PoolL2Txs of the batch7
  182. batchPoolL2 := `
  183. Type: PoolL2
  184. PoolTransferToEthAddr(1) A-B: 200 (126)
  185. PoolTransferToEthAddr(0) B-C: 100 (126)`
  186. poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
  187. require.NoError(t, err)
  188. // Coordinator Idx where to send the fees
  189. coordIdxs := []common.Idx{261, 262}
  190. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
  191. l2Txs = poolL2Txs
  192. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
  193. require.NoError(t, err)
  194. sendProofAndCheckResp(t, ptOut.ZKInputs)
  195. // batch8
  196. // simulate the PoolL2Txs of the batch8
  197. batchPoolL2 = `
  198. Type: PoolL2
  199. PoolTransfer(0) A-B: 100 (126)
  200. PoolTransfer(0) C-A: 50 (126)
  201. PoolTransfer(1) B-C: 100 (126)
  202. PoolExit(0) A: 100 (126)`
  203. poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
  204. require.NoError(t, err)
  205. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
  206. l2Txs = poolL2Txs
  207. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
  208. require.NoError(t, err)
  209. sendProofAndCheckResp(t, ptOut.ZKInputs)
  210. // batch9
  211. // simulate the PoolL2Txs of the batch9
  212. batchPoolL2 = `
  213. Type: PoolL2
  214. PoolTransfer(0) D-A: 300 (126)
  215. PoolTransfer(0) B-D: 100 (126)`
  216. poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
  217. require.NoError(t, err)
  218. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
  219. l2Txs = poolL2Txs
  220. coordIdxs = []common.Idx{262}
  221. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  222. require.NoError(t, err)
  223. sendProofAndCheckResp(t, ptOut.ZKInputs)
  224. // batch10
  225. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
  226. l2Txs = []common.PoolL2Tx{}
  227. coordIdxs = []common.Idx{}
  228. ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  229. require.NoError(t, err)
  230. sendProofAndCheckResp(t, ptOut.ZKInputs)
  231. }