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