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}