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}