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