arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/db/l2db/l2db_test.go
db/l2db/l2db_test.goRaw
  1package l2db
  2
  3import (
  4	"math"
  5	"math/big"
  6	"os"
  7	"testing"
  8	"time"
  9
 10	ethCommon "github.com/ethereum/go-ethereum/common"
 11	"github.com/hermeznetwork/hermez-node/common"
 12	dbUtils "github.com/hermeznetwork/hermez-node/db"
 13	"github.com/hermeznetwork/hermez-node/db/historydb"
 14	"github.com/hermeznetwork/hermez-node/log"
 15	"github.com/hermeznetwork/hermez-node/test"
 16	"github.com/hermeznetwork/hermez-node/test/til"
 17	"github.com/hermeznetwork/tracerr"
 18	"github.com/iden3/go-iden3-crypto/babyjub"
 19	"github.com/stretchr/testify/assert"
 20	"github.com/stretchr/testify/require"
 21)
 22
 23var l2DB *L2DB
 24var historyDB *historydb.HistoryDB
 25var tc *til.Context
 26var tokens map[common.TokenID]historydb.TokenWithUSD
 27var tokensValue map[common.TokenID]float64
 28var accs map[common.Idx]common.Account
 29
 30func TestMain(m *testing.M) {
 31	// init DB
 32	pass := os.Getenv("POSTGRES_PASS")
 33	db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
 34	if err != nil {
 35		panic(err)
 36	}
 37	l2DB = NewL2DB(db, 10, 1000, 24*time.Hour)
 38	test.WipeDB(l2DB.DB())
 39	historyDB = historydb.NewHistoryDB(db)
 40	// Run tests
 41	result := m.Run()
 42	// Close DB
 43	if err := db.Close(); err != nil {
 44		log.Error("Error closing the history DB:", err)
 45	}
 46	os.Exit(result)
 47}
 48
 49func prepareHistoryDB(historyDB *historydb.HistoryDB) error {
 50	// Reset DB
 51	test.WipeDB(l2DB.DB())
 52	// Generate pool txs using til
 53	setBlockchain := `
 54			Type: Blockchain
 55
 56			AddToken(1)
 57			AddToken(2)
 58			CreateAccountDeposit(1) A: 2000
 59			CreateAccountDeposit(2) A: 2000
 60			CreateAccountDeposit(1) B: 1000
 61			CreateAccountDeposit(2) B: 1000
 62			> batchL1 
 63			> batchL1
 64			> block
 65			> block
 66			`
 67
 68	tc = til.NewContext(uint16(0), common.RollupConstMaxL1UserTx)
 69	tilCfgExtra := til.ConfigExtra{
 70		BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
 71		CoordUser:     "A",
 72	}
 73	blocks, err := tc.GenerateBlocks(setBlockchain)
 74	if err != nil {
 75		return tracerr.Wrap(err)
 76	}
 77
 78	err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
 79	if err != nil {
 80		return tracerr.Wrap(err)
 81	}
 82	tokens = make(map[common.TokenID]historydb.TokenWithUSD)
 83	tokensValue = make(map[common.TokenID]float64)
 84	accs = make(map[common.Idx]common.Account)
 85	value := 5 * 5.389329
 86	now := time.Now().UTC()
 87	// Add all blocks except for the last one
 88	for i := range blocks[:len(blocks)-1] {
 89		err = historyDB.AddBlockSCData(&blocks[i])
 90		if err != nil {
 91			return tracerr.Wrap(err)
 92		}
 93		for _, batch := range blocks[i].Rollup.Batches {
 94			for _, account := range batch.CreatedAccounts {
 95				accs[account.Idx] = account
 96			}
 97		}
 98		for _, token := range blocks[i].Rollup.AddedTokens {
 99			readToken := historydb.TokenWithUSD{
100				TokenID:     token.TokenID,
101				EthBlockNum: token.EthBlockNum,
102				EthAddr:     token.EthAddr,
103				Name:        token.Name,
104				Symbol:      token.Symbol,
105				Decimals:    token.Decimals,
106			}
107			tokensValue[token.TokenID] = value / math.Pow(10, float64(token.Decimals))
108			readToken.USDUpdate = &now
109			readToken.USD = &value
110			tokens[token.TokenID] = readToken
111		}
112		// Set value to the tokens (tokens have no symbol)
113		tokenSymbol := ""
114		err := historyDB.UpdateTokenValue(tokenSymbol, value)
115		if err != nil {
116			return tracerr.Wrap(err)
117		}
118	}
119	return nil
120}
121
122func generatePoolL2Txs() ([]common.PoolL2Tx, error) {
123	setPool := `
124			Type: PoolL2
125			PoolTransfer(1) A-B: 6 (4)
126			PoolTransfer(2) A-B: 3 (1)
127			PoolTransfer(1) B-A: 5 (2)
128			PoolTransfer(2) B-A: 10 (3)
129			PoolTransfer(1) A-B: 7 (2)
130			PoolTransfer(2) A-B: 2 (1)
131			PoolTransfer(1) B-A: 8 (2)
132			PoolTransfer(2) B-A: 1 (1)
133			PoolTransfer(1) A-B: 3 (1)
134			PoolTransferToEthAddr(2) B-A: 5 (2)
135			PoolTransferToBJJ(2) B-A: 5 (2)
136
137			PoolExit(1) A: 5 (2)
138			PoolExit(2) B: 3 (1)
139		`
140	poolL2Txs, err := tc.GeneratePoolL2Txs(setPool)
141	if err != nil {
142		return nil, tracerr.Wrap(err)
143	}
144	return poolL2Txs, nil
145}
146
147func TestAddTxTest(t *testing.T) {
148	err := prepareHistoryDB(historyDB)
149	if err != nil {
150		log.Error("Error prepare historyDB", err)
151	}
152	poolL2Txs, err := generatePoolL2Txs()
153	assert.NoError(t, err)
154	for i := range poolL2Txs {
155		err := l2DB.AddTxTest(&poolL2Txs[i])
156		assert.NoError(t, err)
157		fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID)
158		assert.NoError(t, err)
159		assertTx(t, &poolL2Txs[i], fetchedTx)
160		nameZone, offset := fetchedTx.Timestamp.Zone()
161		assert.Equal(t, "UTC", nameZone)
162		assert.Equal(t, 0, offset)
163	}
164}
165func TestUpdateTxsInfo(t *testing.T) {
166	err := prepareHistoryDB(historyDB)
167	if err != nil {
168		log.Error("Error prepare historyDB", err)
169	}
170	poolL2Txs, err := generatePoolL2Txs()
171	assert.NoError(t, err)
172	for i := range poolL2Txs {
173		err := l2DB.AddTxTest(&poolL2Txs[i])
174		require.NoError(t, err)
175
176		// once added, change the Info parameter
177		poolL2Txs[i].Info = "test"
178	}
179	// update the txs
180	err = l2DB.UpdateTxsInfo(poolL2Txs)
181	require.NoError(t, err)
182
183	for i := range poolL2Txs {
184		fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID)
185		assert.NoError(t, err)
186		assert.Equal(t, "test", fetchedTx.Info)
187	}
188}
189
190func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
191	// Check that timestamp has been set within the last 3 seconds
192	assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix())
193	assert.GreaterOrEqual(t, time.Now().UTC().Unix(), actual.Timestamp.Unix())
194	expected.Timestamp = actual.Timestamp
195	// Check absolute fee
196	// find token
197	token := tokens[expected.TokenID]
198	// If the token has value in USD setted
199	if token.USDUpdate != nil {
200		assert.Less(t, token.USDUpdate.Unix()-3, actual.AbsoluteFeeUpdate.Unix())
201		expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate
202		// Set expected fee
203		f := new(big.Float).SetInt(expected.Amount)
204		amountF, _ := f.Float64()
205		expected.AbsoluteFee = *token.USD * amountF * expected.Fee.Percentage()
206		test.AssertUSD(t, &expected.AbsoluteFee, &actual.AbsoluteFee)
207	}
208	assert.Equal(t, expected, actual)
209}
210
211// NO UPDATE: benchmarks will be done after impl is finished
212// func BenchmarkAddTxTest(b *testing.B) {
213// 	const nInserts = 20
214// 	test.WipeDB(l2DB.DB())
215// 	txs := test.GenPoolTxs(nInserts, tokens)
216// 	now := time.Now()
217// 	for _, tx := range txs {
218// 		_ = l2DB.AddTxTest(tx)
219// 	}
220// 	elapsedTime := time.Since(now)
221// 	log.Info("Time to insert 2048 txs:", elapsedTime)
222// }
223
224func TestGetPending(t *testing.T) {
225	err := prepareHistoryDB(historyDB)
226	if err != nil {
227		log.Error("Error prepare historyDB", err)
228	}
229	poolL2Txs, err := generatePoolL2Txs()
230	assert.NoError(t, err)
231	var pendingTxs []*common.PoolL2Tx
232	for i := range poolL2Txs {
233		err := l2DB.AddTxTest(&poolL2Txs[i])
234		assert.NoError(t, err)
235		pendingTxs = append(pendingTxs, &poolL2Txs[i])
236	}
237	fetchedTxs, err := l2DB.GetPendingTxs()
238	assert.NoError(t, err)
239	assert.Equal(t, len(pendingTxs), len(fetchedTxs))
240	for i := range fetchedTxs {
241		assertTx(t, pendingTxs[i], &fetchedTxs[i])
242	}
243}
244
245func TestStartForging(t *testing.T) {
246	// Generate txs
247	var fakeBatchNum common.BatchNum = 33
248	err := prepareHistoryDB(historyDB)
249	if err != nil {
250		log.Error("Error prepare historyDB", err)
251	}
252	poolL2Txs, err := generatePoolL2Txs()
253	assert.NoError(t, err)
254	var startForgingTxIDs []common.TxID
255	randomizer := 0
256	// Add txs to DB
257	for i := range poolL2Txs {
258		err := l2DB.AddTxTest(&poolL2Txs[i])
259		assert.NoError(t, err)
260		if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
261			startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
262		}
263		randomizer++
264	}
265	// Start forging txs
266	err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
267	assert.NoError(t, err)
268	// Fetch txs and check that they've been updated correctly
269	for _, id := range startForgingTxIDs {
270		fetchedTx, err := l2DB.GetTxAPI(id)
271		assert.NoError(t, err)
272		assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
273		assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
274	}
275}
276
277func TestDoneForging(t *testing.T) {
278	// Generate txs
279	var fakeBatchNum common.BatchNum = 33
280	err := prepareHistoryDB(historyDB)
281	if err != nil {
282		log.Error("Error prepare historyDB", err)
283	}
284	poolL2Txs, err := generatePoolL2Txs()
285	assert.NoError(t, err)
286	var startForgingTxIDs []common.TxID
287	randomizer := 0
288	// Add txs to DB
289	for i := range poolL2Txs {
290		err := l2DB.AddTxTest(&poolL2Txs[i])
291		assert.NoError(t, err)
292		if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
293			startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
294		}
295		randomizer++
296	}
297	// Start forging txs
298	err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
299	assert.NoError(t, err)
300
301	var doneForgingTxIDs []common.TxID
302	randomizer = 0
303	for _, txID := range startForgingTxIDs {
304		if randomizer%2 == 0 {
305			doneForgingTxIDs = append(doneForgingTxIDs, txID)
306		}
307		randomizer++
308	}
309	// Done forging txs
310	err = l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum)
311	assert.NoError(t, err)
312
313	// Fetch txs and check that they've been updated correctly
314	for _, id := range doneForgingTxIDs {
315		fetchedTx, err := l2DB.GetTxAPI(id)
316		assert.NoError(t, err)
317		assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
318		assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
319	}
320}
321
322func TestInvalidate(t *testing.T) {
323	// Generate txs
324	var fakeBatchNum common.BatchNum = 33
325	err := prepareHistoryDB(historyDB)
326	if err != nil {
327		log.Error("Error prepare historyDB", err)
328	}
329	poolL2Txs, err := generatePoolL2Txs()
330	assert.NoError(t, err)
331	var invalidTxIDs []common.TxID
332	randomizer := 0
333	// Add txs to DB
334	for i := range poolL2Txs {
335		err := l2DB.AddTxTest(&poolL2Txs[i])
336		assert.NoError(t, err)
337		if poolL2Txs[i].State != common.PoolL2TxStateInvalid && randomizer%2 == 0 {
338			randomizer++
339			invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
340		}
341	}
342	// Invalidate txs
343	err = l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
344	assert.NoError(t, err)
345	// Fetch txs and check that they've been updated correctly
346	for _, id := range invalidTxIDs {
347		fetchedTx, err := l2DB.GetTxAPI(id)
348		assert.NoError(t, err)
349		assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
350		assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
351	}
352}
353
354func TestInvalidateOldNonces(t *testing.T) {
355	// Generate txs
356	var fakeBatchNum common.BatchNum = 33
357	err := prepareHistoryDB(historyDB)
358	if err != nil {
359		log.Error("Error prepare historyDB", err)
360	}
361	poolL2Txs, err := generatePoolL2Txs()
362	assert.NoError(t, err)
363	// Update Accounts currentNonce
364	var updateAccounts []common.IdxNonce
365	var currentNonce = common.Nonce(1)
366	for i := range accs {
367		updateAccounts = append(updateAccounts, common.IdxNonce{
368			Idx:   accs[i].Idx,
369			Nonce: common.Nonce(currentNonce),
370		})
371	}
372	// Add txs to DB
373	var invalidTxIDs []common.TxID
374	for i := range poolL2Txs {
375		if poolL2Txs[i].Nonce < currentNonce {
376			invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
377		}
378		err := l2DB.AddTxTest(&poolL2Txs[i])
379		assert.NoError(t, err)
380	}
381	// sanity check
382	require.Greater(t, len(invalidTxIDs), 0)
383
384	err = l2DB.InvalidateOldNonces(updateAccounts, fakeBatchNum)
385	assert.NoError(t, err)
386	// Fetch txs and check that they've been updated correctly
387	for _, id := range invalidTxIDs {
388		fetchedTx, err := l2DB.GetTxAPI(id)
389		require.NoError(t, err)
390		assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
391		assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
392	}
393}
394
395// TestReorg: first part of the test with reorg
396// With invalidated transactions BEFORE reorgBatch
397// And forged transactions in reorgBatch
398func TestReorg(t *testing.T) {
399	// Generate txs
400	const lastValidBatch common.BatchNum = 20
401	const reorgBatch common.BatchNum = lastValidBatch + 1
402	err := prepareHistoryDB(historyDB)
403	if err != nil {
404		log.Error("Error prepare historyDB", err)
405	}
406	poolL2Txs, err := generatePoolL2Txs()
407	assert.NoError(t, err)
408
409	reorgedTxIDs := []common.TxID{}
410	nonReorgedTxIDs := []common.TxID{}
411	var startForgingTxIDs []common.TxID
412	var invalidTxIDs []common.TxID
413	var allTxRandomize []common.TxID
414	randomizer := 0
415	// Add txs to DB
416	for i := range poolL2Txs {
417		err := l2DB.AddTxTest(&poolL2Txs[i])
418		assert.NoError(t, err)
419		if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
420			startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
421			allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
422		} else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 {
423			invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
424			allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
425		}
426		randomizer++
427	}
428	// Start forging txs
429	err = l2DB.StartForging(startForgingTxIDs, lastValidBatch)
430	assert.NoError(t, err)
431
432	var doneForgingTxIDs []common.TxID
433	randomizer = 0
434	for _, txID := range allTxRandomize {
435		invalidTx := false
436		for i := range invalidTxIDs {
437			if invalidTxIDs[i] == txID {
438				invalidTx = true
439				nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
440			}
441		}
442		if !invalidTx {
443			if randomizer%2 == 0 {
444				doneForgingTxIDs = append(doneForgingTxIDs, txID)
445				reorgedTxIDs = append(reorgedTxIDs, txID)
446			} else {
447				nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
448			}
449			randomizer++
450		}
451	}
452
453	// Invalidate txs BEFORE reorgBatch --> nonReorg
454	err = l2DB.InvalidateTxs(invalidTxIDs, lastValidBatch)
455	assert.NoError(t, err)
456	// Done forging txs in reorgBatch --> Reorg
457	err = l2DB.DoneForging(doneForgingTxIDs, reorgBatch)
458	assert.NoError(t, err)
459
460	err = l2DB.Reorg(lastValidBatch)
461	assert.NoError(t, err)
462	for _, id := range reorgedTxIDs {
463		tx, err := l2DB.GetTxAPI(id)
464		assert.NoError(t, err)
465		assert.Nil(t, tx.BatchNum)
466		assert.Equal(t, common.PoolL2TxStatePending, tx.State)
467	}
468	for _, id := range nonReorgedTxIDs {
469		fetchedTx, err := l2DB.GetTxAPI(id)
470		assert.NoError(t, err)
471		assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
472	}
473}
474
475// TestReorg: second part of test with reorg
476// With invalidated transactions in reorgBatch
477// And forged transactions BEFORE reorgBatch
478func TestReorg2(t *testing.T) {
479	// Generate txs
480	const lastValidBatch common.BatchNum = 20
481	const reorgBatch common.BatchNum = lastValidBatch + 1
482	err := prepareHistoryDB(historyDB)
483	if err != nil {
484		log.Error("Error prepare historyDB", err)
485	}
486	poolL2Txs, err := generatePoolL2Txs()
487	assert.NoError(t, err)
488
489	reorgedTxIDs := []common.TxID{}
490	nonReorgedTxIDs := []common.TxID{}
491	var startForgingTxIDs []common.TxID
492	var invalidTxIDs []common.TxID
493	var allTxRandomize []common.TxID
494	randomizer := 0
495	// Add txs to DB
496	for i := range poolL2Txs {
497		err := l2DB.AddTxTest(&poolL2Txs[i])
498		assert.NoError(t, err)
499		if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
500			startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
501			allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
502		} else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 {
503			invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
504			allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
505		}
506		randomizer++
507	}
508	// Start forging txs
509	err = l2DB.StartForging(startForgingTxIDs, lastValidBatch)
510	assert.NoError(t, err)
511
512	var doneForgingTxIDs []common.TxID
513	randomizer = 0
514	for _, txID := range allTxRandomize {
515		invalidTx := false
516		for i := range invalidTxIDs {
517			if invalidTxIDs[i] == txID {
518				invalidTx = true
519				reorgedTxIDs = append(reorgedTxIDs, txID)
520			}
521		}
522		if !invalidTx {
523			if randomizer%2 == 0 {
524				doneForgingTxIDs = append(doneForgingTxIDs, txID)
525			}
526			nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
527			randomizer++
528		}
529	}
530	// Done forging txs BEFORE reorgBatch --> nonReorg
531	err = l2DB.DoneForging(doneForgingTxIDs, lastValidBatch)
532	assert.NoError(t, err)
533	// Invalidate txs in reorgBatch --> Reorg
534	err = l2DB.InvalidateTxs(invalidTxIDs, reorgBatch)
535	assert.NoError(t, err)
536
537	err = l2DB.Reorg(lastValidBatch)
538	assert.NoError(t, err)
539	for _, id := range reorgedTxIDs {
540		tx, err := l2DB.GetTxAPI(id)
541		assert.NoError(t, err)
542		assert.Nil(t, tx.BatchNum)
543		assert.Equal(t, common.PoolL2TxStatePending, tx.State)
544	}
545	for _, id := range nonReorgedTxIDs {
546		fetchedTx, err := l2DB.GetTxAPI(id)
547		assert.NoError(t, err)
548		assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
549	}
550}
551
552func TestPurge(t *testing.T) {
553	// Generate txs
554	err := prepareHistoryDB(historyDB)
555	if err != nil {
556		log.Error("Error prepare historyDB", err)
557	}
558	// generatePoolL2Txs
559	generateTx := int(l2DB.maxTxs/8 + 1)
560	var poolL2Tx []common.PoolL2Tx
561	for i := 0; i < generateTx; i++ {
562		poolL2TxAux, err := generatePoolL2Txs()
563		assert.NoError(t, err)
564		poolL2Tx = append(poolL2Tx, poolL2TxAux...)
565	}
566
567	afterTTLIDs := []common.TxID{}
568	keepedIDs := []common.TxID{}
569	var deletedIDs []common.TxID
570	var invalidTxIDs []common.TxID
571	var doneForgingTxIDs []common.TxID
572	const toDeleteBatchNum common.BatchNum = 30
573	safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
574	// Add txs to the DB
575	for i := 0; i < len(poolL2Tx); i++ {
576		tx := poolL2Tx[i]
577		if i%2 == 0 { // keep tx
578			keepedIDs = append(keepedIDs, tx.TxID)
579		} else { // delete after safety period
580			if i%3 == 0 {
581				doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID)
582			} else if i%5 == 0 {
583				invalidTxIDs = append(invalidTxIDs, tx.TxID)
584			} else {
585				afterTTLIDs = append(afterTTLIDs, tx.TxID)
586			}
587			deletedIDs = append(deletedIDs, poolL2Tx[i].TxID)
588		}
589		err := l2DB.AddTxTest(&tx)
590		assert.NoError(t, err)
591	}
592	// Set batchNum keeped txs
593	for i := range keepedIDs {
594		_, err = l2DB.db.Exec(
595			"UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
596			safeBatchNum, keepedIDs[i],
597		)
598		assert.NoError(t, err)
599	}
600	// Start forging txs and set batchNum
601	err = l2DB.StartForging(doneForgingTxIDs, toDeleteBatchNum)
602	assert.NoError(t, err)
603	// Done forging txs and set batchNum
604	err = l2DB.DoneForging(doneForgingTxIDs, toDeleteBatchNum)
605	assert.NoError(t, err)
606	// Invalidate txs and set batchNum
607	err = l2DB.InvalidateTxs(invalidTxIDs, toDeleteBatchNum)
608	assert.NoError(t, err)
609	// Update timestamp of afterTTL txs
610	deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0)
611	for _, id := range afterTTLIDs {
612		// Set timestamp
613		_, err = l2DB.db.Exec(
614			"UPDATE tx_pool SET timestamp = $1, state = $2 WHERE tx_id = $3;",
615			deleteTimestamp, common.PoolL2TxStatePending, id,
616		)
617		assert.NoError(t, err)
618	}
619
620	// Purge txs
621	err = l2DB.Purge(safeBatchNum)
622	assert.NoError(t, err)
623	// Check results
624	for _, id := range deletedIDs {
625		_, err := l2DB.GetTx(id)
626		assert.Error(t, err)
627	}
628	for _, id := range keepedIDs {
629		_, err := l2DB.GetTx(id)
630		assert.NoError(t, err)
631	}
632}
633
634func TestAuth(t *testing.T) {
635	test.WipeDB(l2DB.DB())
636	const nAuths = 5
637	chainID := uint16(0)
638	hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
639	// Generate authorizations
640	auths := test.GenAuths(nAuths, chainID, hermezContractAddr)
641	for i := 0; i < len(auths); i++ {
642		// Add to the DB
643		err := l2DB.AddAccountCreationAuth(auths[i])
644		assert.NoError(t, err)
645		// Fetch from DB
646		auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
647		assert.NoError(t, err)
648		// Check fetched vs generated
649		assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
650		assert.Equal(t, auths[i].BJJ, auth.BJJ)
651		assert.Equal(t, auths[i].Signature, auth.Signature)
652		assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
653		nameZone, offset := auths[i].Timestamp.Zone()
654		assert.Equal(t, "UTC", nameZone)
655		assert.Equal(t, 0, offset)
656	}
657}
658
659func TestAddGet(t *testing.T) {
660	err := prepareHistoryDB(historyDB)
661	if err != nil {
662		log.Error("Error prepare historyDB", err)
663	}
664	poolL2Txs, err := generatePoolL2Txs()
665	assert.NoError(t, err)
666
667	// We will work with only 3 txs
668	require.GreaterOrEqual(t, len(poolL2Txs), 3)
669	txs := poolL2Txs[:3]
670	// NOTE: By changing the tx fields, the signature will no longer be
671	// valid, but we are not checking the signautre here so it's OK.
672	// 0. Has ToIdx >= 256 && ToEthAddr == 0 && ToBJJ == 0
673	require.GreaterOrEqual(t, int(txs[0].ToIdx), 256)
674	txs[0].ToEthAddr = ethCommon.Address{}
675	txs[0].ToBJJ = babyjub.PublicKeyComp{}
676	// 1. Has ToIdx >= 256 && ToEthAddr != 0 && ToBJJ != 0
677	require.GreaterOrEqual(t, int(txs[1].ToIdx), 256)
678	require.NotEqual(t, txs[1].ToEthAddr, ethCommon.Address{})
679	require.NotEqual(t, txs[1].ToBJJ, babyjub.PublicKeyComp{})
680	// 2. Has ToIdx == 0 && ToEthAddr != 0 && ToBJJ != 0
681	txs[2].ToIdx = 0
682	require.NotEqual(t, txs[2].ToEthAddr, ethCommon.Address{})
683	require.NotEqual(t, txs[2].ToBJJ, babyjub.PublicKeyComp{})
684
685	for i := 0; i < len(txs); i++ {
686		require.NoError(t, txs[i].SetID())
687		require.NoError(t, l2DB.AddTxTest(&txs[i]))
688	}
689	// Verify that the inserts haven't altered any field (specially
690	// ToEthAddr and ToBJJ)
691	for i := 0; i < len(txs); i++ {
692		dbTx, err := l2DB.GetTx(txs[i].TxID)
693		require.NoError(t, err)
694		// Ignore Timestamp, AbsoluteFee, AbsoluteFeeUpdate
695		txs[i].Timestamp = dbTx.Timestamp
696		txs[i].AbsoluteFee = dbTx.AbsoluteFee
697		txs[i].AbsoluteFeeUpdate = dbTx.AbsoluteFeeUpdate
698		assert.Equal(t, txs[i], *dbTx)
699	}
700}