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