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