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}
165
166func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
167 // Check that timestamp has been set within the last 3 seconds
168 assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix())
169 assert.GreaterOrEqual(t, time.Now().UTC().Unix(), actual.Timestamp.Unix())
170 expected.Timestamp = actual.Timestamp
171 // Check absolute fee
172 // find token
173 token := tokens[expected.TokenID]
174 // If the token has value in USD setted
175 if token.USDUpdate != nil {
176 assert.Less(t, token.USDUpdate.Unix()-3, actual.AbsoluteFeeUpdate.Unix())
177 expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate
178 // Set expected fee
179 f := new(big.Float).SetInt(expected.Amount)
180 amountF, _ := f.Float64()
181 expected.AbsoluteFee = *token.USD * amountF * expected.Fee.Percentage()
182 test.AssertUSD(t, &expected.AbsoluteFee, &actual.AbsoluteFee)
183 }
184 assert.Equal(t, expected, actual)
185}
186
187// NO UPDATE: benchmarks will be done after impl is finished
188// func BenchmarkAddTxTest(b *testing.B) {
189// const nInserts = 20
190// test.WipeDB(l2DB.DB())
191// txs := test.GenPoolTxs(nInserts, tokens)
192// now := time.Now()
193// for _, tx := range txs {
194// _ = l2DB.AddTxTest(tx)
195// }
196// elapsedTime := time.Since(now)
197// log.Info("Time to insert 2048 txs:", elapsedTime)
198// }
199
200func TestGetPending(t *testing.T) {
201 err := prepareHistoryDB(historyDB)
202 if err != nil {
203 log.Error("Error prepare historyDB", err)
204 }
205 poolL2Txs, err := generatePoolL2Txs()
206 assert.NoError(t, err)
207 var pendingTxs []*common.PoolL2Tx
208 for i := range poolL2Txs {
209 err := l2DB.AddTxTest(&poolL2Txs[i])
210 assert.NoError(t, err)
211 pendingTxs = append(pendingTxs, &poolL2Txs[i])
212 }
213 fetchedTxs, err := l2DB.GetPendingTxs()
214 assert.NoError(t, err)
215 assert.Equal(t, len(pendingTxs), len(fetchedTxs))
216 for i := range fetchedTxs {
217 assertTx(t, pendingTxs[i], &fetchedTxs[i])
218 }
219}
220
221func TestStartForging(t *testing.T) {
222 // Generate txs
223 var fakeBatchNum common.BatchNum = 33
224 err := prepareHistoryDB(historyDB)
225 if err != nil {
226 log.Error("Error prepare historyDB", err)
227 }
228 poolL2Txs, err := generatePoolL2Txs()
229 assert.NoError(t, err)
230 var startForgingTxIDs []common.TxID
231 randomizer := 0
232 // Add txs to DB
233 for i := range poolL2Txs {
234 err := l2DB.AddTxTest(&poolL2Txs[i])
235 assert.NoError(t, err)
236 if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
237 startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
238 }
239 randomizer++
240 }
241 // Start forging txs
242 err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
243 assert.NoError(t, err)
244 // Fetch txs and check that they've been updated correctly
245 for _, id := range startForgingTxIDs {
246 fetchedTx, err := l2DB.GetTxAPI(id)
247 assert.NoError(t, err)
248 assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
249 assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
250 }
251}
252
253func TestDoneForging(t *testing.T) {
254 // Generate txs
255 var fakeBatchNum common.BatchNum = 33
256 err := prepareHistoryDB(historyDB)
257 if err != nil {
258 log.Error("Error prepare historyDB", err)
259 }
260 poolL2Txs, err := generatePoolL2Txs()
261 assert.NoError(t, err)
262 var startForgingTxIDs []common.TxID
263 randomizer := 0
264 // Add txs to DB
265 for i := range poolL2Txs {
266 err := l2DB.AddTxTest(&poolL2Txs[i])
267 assert.NoError(t, err)
268 if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
269 startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
270 }
271 randomizer++
272 }
273 // Start forging txs
274 err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
275 assert.NoError(t, err)
276
277 var doneForgingTxIDs []common.TxID
278 randomizer = 0
279 for _, txID := range startForgingTxIDs {
280 if randomizer%2 == 0 {
281 doneForgingTxIDs = append(doneForgingTxIDs, txID)
282 }
283 randomizer++
284 }
285 // Done forging txs
286 err = l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum)
287 assert.NoError(t, err)
288
289 // Fetch txs and check that they've been updated correctly
290 for _, id := range doneForgingTxIDs {
291 fetchedTx, err := l2DB.GetTxAPI(id)
292 assert.NoError(t, err)
293 assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
294 assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
295 }
296}
297
298func TestInvalidate(t *testing.T) {
299 // Generate txs
300 var fakeBatchNum common.BatchNum = 33
301 err := prepareHistoryDB(historyDB)
302 if err != nil {
303 log.Error("Error prepare historyDB", err)
304 }
305 poolL2Txs, err := generatePoolL2Txs()
306 assert.NoError(t, err)
307 var invalidTxIDs []common.TxID
308 randomizer := 0
309 // Add txs to DB
310 for i := range poolL2Txs {
311 err := l2DB.AddTxTest(&poolL2Txs[i])
312 assert.NoError(t, err)
313 if poolL2Txs[i].State != common.PoolL2TxStateInvalid && randomizer%2 == 0 {
314 randomizer++
315 invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
316 }
317 }
318 // Invalidate txs
319 err = l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
320 assert.NoError(t, err)
321 // Fetch txs and check that they've been updated correctly
322 for _, id := range invalidTxIDs {
323 fetchedTx, err := l2DB.GetTxAPI(id)
324 assert.NoError(t, err)
325 assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
326 assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
327 }
328}
329
330func TestInvalidateOldNonces(t *testing.T) {
331 // Generate txs
332 var fakeBatchNum common.BatchNum = 33
333 err := prepareHistoryDB(historyDB)
334 if err != nil {
335 log.Error("Error prepare historyDB", err)
336 }
337 poolL2Txs, err := generatePoolL2Txs()
338 assert.NoError(t, err)
339 // Update Accounts currentNonce
340 var updateAccounts []common.IdxNonce
341 var currentNonce = common.Nonce(1)
342 for i := range accs {
343 updateAccounts = append(updateAccounts, common.IdxNonce{
344 Idx: accs[i].Idx,
345 Nonce: common.Nonce(currentNonce),
346 })
347 }
348 // Add txs to DB
349 var invalidTxIDs []common.TxID
350 for i := range poolL2Txs {
351 if poolL2Txs[i].Nonce < currentNonce {
352 invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
353 }
354 err := l2DB.AddTxTest(&poolL2Txs[i])
355 assert.NoError(t, err)
356 }
357 // sanity check
358 require.Greater(t, len(invalidTxIDs), 0)
359
360 err = l2DB.InvalidateOldNonces(updateAccounts, fakeBatchNum)
361 assert.NoError(t, err)
362 // Fetch txs and check that they've been updated correctly
363 for _, id := range invalidTxIDs {
364 fetchedTx, err := l2DB.GetTxAPI(id)
365 require.NoError(t, err)
366 assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
367 assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
368 }
369}
370
371// TestReorg: first part of the test with reorg
372// With invalidated transactions BEFORE reorgBatch
373// And forged transactions in reorgBatch
374func TestReorg(t *testing.T) {
375 // Generate txs
376 const lastValidBatch common.BatchNum = 20
377 const reorgBatch common.BatchNum = lastValidBatch + 1
378 err := prepareHistoryDB(historyDB)
379 if err != nil {
380 log.Error("Error prepare historyDB", err)
381 }
382 poolL2Txs, err := generatePoolL2Txs()
383 assert.NoError(t, err)
384
385 reorgedTxIDs := []common.TxID{}
386 nonReorgedTxIDs := []common.TxID{}
387 var startForgingTxIDs []common.TxID
388 var invalidTxIDs []common.TxID
389 var allTxRandomize []common.TxID
390 randomizer := 0
391 // Add txs to DB
392 for i := range poolL2Txs {
393 err := l2DB.AddTxTest(&poolL2Txs[i])
394 assert.NoError(t, err)
395 if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
396 startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
397 allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
398 } else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 {
399 invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
400 allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
401 }
402 randomizer++
403 }
404 // Start forging txs
405 err = l2DB.StartForging(startForgingTxIDs, lastValidBatch)
406 assert.NoError(t, err)
407
408 var doneForgingTxIDs []common.TxID
409 randomizer = 0
410 for _, txID := range allTxRandomize {
411 invalidTx := false
412 for i := range invalidTxIDs {
413 if invalidTxIDs[i] == txID {
414 invalidTx = true
415 nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
416 }
417 }
418 if !invalidTx {
419 if randomizer%2 == 0 {
420 doneForgingTxIDs = append(doneForgingTxIDs, txID)
421 reorgedTxIDs = append(reorgedTxIDs, txID)
422 } else {
423 nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
424 }
425 randomizer++
426 }
427 }
428
429 // Invalidate txs BEFORE reorgBatch --> nonReorg
430 err = l2DB.InvalidateTxs(invalidTxIDs, lastValidBatch)
431 assert.NoError(t, err)
432 // Done forging txs in reorgBatch --> Reorg
433 err = l2DB.DoneForging(doneForgingTxIDs, reorgBatch)
434 assert.NoError(t, err)
435
436 err = l2DB.Reorg(lastValidBatch)
437 assert.NoError(t, err)
438 for _, id := range reorgedTxIDs {
439 tx, err := l2DB.GetTxAPI(id)
440 assert.NoError(t, err)
441 assert.Nil(t, tx.BatchNum)
442 assert.Equal(t, common.PoolL2TxStatePending, tx.State)
443 }
444 for _, id := range nonReorgedTxIDs {
445 fetchedTx, err := l2DB.GetTxAPI(id)
446 assert.NoError(t, err)
447 assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
448 }
449}
450
451// TestReorg: second part of test with reorg
452// With invalidated transactions in reorgBatch
453// And forged transactions BEFORE reorgBatch
454func TestReorg2(t *testing.T) {
455 // Generate txs
456 const lastValidBatch common.BatchNum = 20
457 const reorgBatch common.BatchNum = lastValidBatch + 1
458 err := prepareHistoryDB(historyDB)
459 if err != nil {
460 log.Error("Error prepare historyDB", err)
461 }
462 poolL2Txs, err := generatePoolL2Txs()
463 assert.NoError(t, err)
464
465 reorgedTxIDs := []common.TxID{}
466 nonReorgedTxIDs := []common.TxID{}
467 var startForgingTxIDs []common.TxID
468 var invalidTxIDs []common.TxID
469 var allTxRandomize []common.TxID
470 randomizer := 0
471 // Add txs to DB
472 for i := range poolL2Txs {
473 err := l2DB.AddTxTest(&poolL2Txs[i])
474 assert.NoError(t, err)
475 if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
476 startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
477 allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
478 } else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 {
479 invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
480 allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
481 }
482 randomizer++
483 }
484 // Start forging txs
485 err = l2DB.StartForging(startForgingTxIDs, lastValidBatch)
486 assert.NoError(t, err)
487
488 var doneForgingTxIDs []common.TxID
489 randomizer = 0
490 for _, txID := range allTxRandomize {
491 invalidTx := false
492 for i := range invalidTxIDs {
493 if invalidTxIDs[i] == txID {
494 invalidTx = true
495 reorgedTxIDs = append(reorgedTxIDs, txID)
496 }
497 }
498 if !invalidTx {
499 if randomizer%2 == 0 {
500 doneForgingTxIDs = append(doneForgingTxIDs, txID)
501 }
502 nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
503 randomizer++
504 }
505 }
506 // Done forging txs BEFORE reorgBatch --> nonReorg
507 err = l2DB.DoneForging(doneForgingTxIDs, lastValidBatch)
508 assert.NoError(t, err)
509 // Invalidate txs in reorgBatch --> Reorg
510 err = l2DB.InvalidateTxs(invalidTxIDs, reorgBatch)
511 assert.NoError(t, err)
512
513 err = l2DB.Reorg(lastValidBatch)
514 assert.NoError(t, err)
515 for _, id := range reorgedTxIDs {
516 tx, err := l2DB.GetTxAPI(id)
517 assert.NoError(t, err)
518 assert.Nil(t, tx.BatchNum)
519 assert.Equal(t, common.PoolL2TxStatePending, tx.State)
520 }
521 for _, id := range nonReorgedTxIDs {
522 fetchedTx, err := l2DB.GetTxAPI(id)
523 assert.NoError(t, err)
524 assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
525 }
526}
527
528func TestPurge(t *testing.T) {
529 // Generate txs
530 err := prepareHistoryDB(historyDB)
531 if err != nil {
532 log.Error("Error prepare historyDB", err)
533 }
534 // generatePoolL2Txs
535 generateTx := int(l2DB.maxTxs/8 + 1)
536 var poolL2Tx []common.PoolL2Tx
537 for i := 0; i < generateTx; i++ {
538 poolL2TxAux, err := generatePoolL2Txs()
539 assert.NoError(t, err)
540 poolL2Tx = append(poolL2Tx, poolL2TxAux...)
541 }
542
543 afterTTLIDs := []common.TxID{}
544 keepedIDs := []common.TxID{}
545 var deletedIDs []common.TxID
546 var invalidTxIDs []common.TxID
547 var doneForgingTxIDs []common.TxID
548 const toDeleteBatchNum common.BatchNum = 30
549 safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
550 // Add txs to the DB
551 for i := 0; i < len(poolL2Tx); i++ {
552 tx := poolL2Tx[i]
553 if i%2 == 0 { // keep tx
554 keepedIDs = append(keepedIDs, tx.TxID)
555 } else { // delete after safety period
556 if i%3 == 0 {
557 doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID)
558 } else if i%5 == 0 {
559 invalidTxIDs = append(invalidTxIDs, tx.TxID)
560 } else {
561 afterTTLIDs = append(afterTTLIDs, tx.TxID)
562 }
563 deletedIDs = append(deletedIDs, poolL2Tx[i].TxID)
564 }
565 err := l2DB.AddTxTest(&tx)
566 assert.NoError(t, err)
567 }
568 // Set batchNum keeped txs
569 for i := range keepedIDs {
570 _, err = l2DB.db.Exec(
571 "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
572 safeBatchNum, keepedIDs[i],
573 )
574 assert.NoError(t, err)
575 }
576 // Start forging txs and set batchNum
577 err = l2DB.StartForging(doneForgingTxIDs, toDeleteBatchNum)
578 assert.NoError(t, err)
579 // Done forging txs and set batchNum
580 err = l2DB.DoneForging(doneForgingTxIDs, toDeleteBatchNum)
581 assert.NoError(t, err)
582 // Invalidate txs and set batchNum
583 err = l2DB.InvalidateTxs(invalidTxIDs, toDeleteBatchNum)
584 assert.NoError(t, err)
585 // Update timestamp of afterTTL txs
586 deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0)
587 for _, id := range afterTTLIDs {
588 // Set timestamp
589 _, err = l2DB.db.Exec(
590 "UPDATE tx_pool SET timestamp = $1, state = $2 WHERE tx_id = $3;",
591 deleteTimestamp, common.PoolL2TxStatePending, id,
592 )
593 assert.NoError(t, err)
594 }
595
596 // Purge txs
597 err = l2DB.Purge(safeBatchNum)
598 assert.NoError(t, err)
599 // Check results
600 for _, id := range deletedIDs {
601 _, err := l2DB.GetTx(id)
602 assert.Error(t, err)
603 }
604 for _, id := range keepedIDs {
605 _, err := l2DB.GetTx(id)
606 assert.NoError(t, err)
607 }
608}
609
610func TestAuth(t *testing.T) {
611 test.WipeDB(l2DB.DB())
612 const nAuths = 5
613 chainID := uint16(0)
614 hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
615 // Generate authorizations
616 auths := test.GenAuths(nAuths, chainID, hermezContractAddr)
617 for i := 0; i < len(auths); i++ {
618 // Add to the DB
619 err := l2DB.AddAccountCreationAuth(auths[i])
620 assert.NoError(t, err)
621 // Fetch from DB
622 auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
623 assert.NoError(t, err)
624 // Check fetched vs generated
625 assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
626 assert.Equal(t, auths[i].BJJ, auth.BJJ)
627 assert.Equal(t, auths[i].Signature, auth.Signature)
628 assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
629 nameZone, offset := auths[i].Timestamp.Zone()
630 assert.Equal(t, "UTC", nameZone)
631 assert.Equal(t, 0, offset)
632 }
633}
634
635func TestAddGet(t *testing.T) {
636 err := prepareHistoryDB(historyDB)
637 if err != nil {
638 log.Error("Error prepare historyDB", err)
639 }
640 poolL2Txs, err := generatePoolL2Txs()
641 assert.NoError(t, err)
642
643 // We will work with only 3 txs
644 require.GreaterOrEqual(t, len(poolL2Txs), 3)
645 txs := poolL2Txs[:3]
646 // NOTE: By changing the tx fields, the signature will no longer be
647 // valid, but we are not checking the signautre here so it's OK.
648 // 0. Has ToIdx >= 256 && ToEthAddr == 0 && ToBJJ == 0
649 require.GreaterOrEqual(t, int(txs[0].ToIdx), 256)
650 txs[0].ToEthAddr = ethCommon.Address{}
651 txs[0].ToBJJ = babyjub.PublicKeyComp{}
652 // 1. Has ToIdx >= 256 && ToEthAddr != 0 && ToBJJ != 0
653 require.GreaterOrEqual(t, int(txs[1].ToIdx), 256)
654 require.NotEqual(t, txs[1].ToEthAddr, ethCommon.Address{})
655 require.NotEqual(t, txs[1].ToBJJ, babyjub.PublicKeyComp{})
656 // 2. Has ToIdx == 0 && ToEthAddr != 0 && ToBJJ != 0
657 txs[2].ToIdx = 0
658 require.NotEqual(t, txs[2].ToEthAddr, ethCommon.Address{})
659 require.NotEqual(t, txs[2].ToBJJ, babyjub.PublicKeyComp{})
660
661 for i := 0; i < len(txs); i++ {
662 require.NoError(t, txs[i].SetID())
663 require.NoError(t, l2DB.AddTxTest(&txs[i]))
664 }
665 // Verify that the inserts haven't altered any field (specially
666 // ToEthAddr and ToBJJ)
667 for i := 0; i < len(txs); i++ {
668 dbTx, err := l2DB.GetTx(txs[i].TxID)
669 require.NoError(t, err)
670 // Ignore Timestamp, AbsoluteFee, AbsoluteFeeUpdate
671 txs[i].Timestamp = dbTx.Timestamp
672 txs[i].AbsoluteFee = dbTx.AbsoluteFee
673 txs[i].AbsoluteFeeUpdate = dbTx.AbsoluteFeeUpdate
674 assert.Equal(t, txs[i], *dbTx)
675 }
676}