|
|
package l2db
import ( "database/sql" "fmt" "os" "testing" "time"
ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/hermez-node/common" dbUtils "github.com/hermeznetwork/hermez-node/db" "github.com/hermeznetwork/hermez-node/db/historydb" "github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/hermez-node/test" "github.com/hermeznetwork/hermez-node/test/til" "github.com/hermeznetwork/tracerr" "github.com/iden3/go-iden3-crypto/babyjub" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" )
var decimals = uint64(3) var tokenValue = 1.0 // The price update gives a value of 1.0 USD to the token
var l2DB *L2DB var l2DBWithACC *L2DB var historyDB *historydb.HistoryDB var tc *til.Context var tokens map[common.TokenID]historydb.TokenWithUSD
var accs map[common.Idx]common.Account
func TestMain(m *testing.M) { // init DB
pass := os.Getenv("POSTGRES_PASS") db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez") if err != nil { panic(err) } l2DB = NewL2DB(db, db, 10, 1000, 0.0, 24*time.Hour, nil) apiConnCon := dbUtils.NewAPIConnectionController(1, time.Second) l2DBWithACC = NewL2DB(db, db, 10, 1000, 0.0, 24*time.Hour, apiConnCon) test.WipeDB(l2DB.DB()) historyDB = historydb.NewHistoryDB(db, db, nil) // Run tests
result := m.Run() // Close DB
if err := db.Close(); err != nil { log.Error("Error closing the history DB:", err) } os.Exit(result) }
func prepareHistoryDB(historyDB *historydb.HistoryDB) error { // Reset DB
test.WipeDB(l2DB.DB()) // Generate pool txs using til
setBlockchain := ` Type: Blockchain
AddToken(1) AddToken(2) CreateAccountDeposit(1) A: 20000 CreateAccountDeposit(2) A: 20000 CreateAccountDeposit(1) B: 10000 CreateAccountDeposit(2) B: 10000 > batchL1 > batchL1 > block > block `
tc = til.NewContext(uint16(0), common.RollupConstMaxL1UserTx) tilCfgExtra := til.ConfigExtra{ BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"), CoordUser: "A", } blocks, err := tc.GenerateBlocks(setBlockchain) if err != nil { return tracerr.Wrap(err) }
err = tc.FillBlocksExtra(blocks, &tilCfgExtra) if err != nil { return tracerr.Wrap(err) } for i := range blocks { block := &blocks[i] for j := range block.Rollup.AddedTokens { token := &block.Rollup.AddedTokens[j] token.Name = fmt.Sprintf("Token %d", token.TokenID) token.Symbol = fmt.Sprintf("TK%d", token.TokenID) token.Decimals = decimals } }
tokens = make(map[common.TokenID]historydb.TokenWithUSD) // tokensValue = make(map[common.TokenID]float64)
accs = make(map[common.Idx]common.Account) now := time.Now().UTC() // Add all blocks except for the last one
for i := range blocks[:len(blocks)-1] { if err := historyDB.AddBlockSCData(&blocks[i]); err != nil { return tracerr.Wrap(err) } for _, batch := range blocks[i].Rollup.Batches { for _, account := range batch.CreatedAccounts { accs[account.Idx] = account } } for _, token := range blocks[i].Rollup.AddedTokens { readToken := historydb.TokenWithUSD{ TokenID: token.TokenID, EthBlockNum: token.EthBlockNum, EthAddr: token.EthAddr, Name: token.Name, Symbol: token.Symbol, Decimals: token.Decimals, USD: &tokenValue, USDUpdate: &now, } tokens[token.TokenID] = readToken // Set value to the tokens
err := historyDB.UpdateTokenValue(readToken.Symbol, *readToken.USD) if err != nil { return tracerr.Wrap(err) } } } return nil }
func generatePoolL2Txs() ([]common.PoolL2Tx, error) { // Fee = 126 corresponds to ~10%
setPool := ` Type: PoolL2 PoolTransfer(1) A-B: 6000 (126) PoolTransfer(2) A-B: 3000 (126) PoolTransfer(1) B-A: 5000 (126) PoolTransfer(2) B-A: 10000 (126) PoolTransfer(1) A-B: 7000 (126) PoolTransfer(2) A-B: 2000 (126) PoolTransfer(1) B-A: 8000 (126) PoolTransfer(2) B-A: 1000 (126) PoolTransfer(1) A-B: 3000 (126) PoolTransferToEthAddr(2) B-A: 5000 (126) PoolTransferToBJJ(2) B-A: 5000 (126)
PoolExit(1) A: 5000 (126) PoolExit(2) B: 3000 (126) ` poolL2Txs, err := tc.GeneratePoolL2Txs(setPool) if err != nil { return nil, tracerr.Wrap(err) } return poolL2Txs, nil }
func TestAddTxTest(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID) require.NoError(t, err) assertTx(t, &poolL2Txs[i], fetchedTx) nameZone, offset := fetchedTx.Timestamp.Zone() assert.Equal(t, "UTC", nameZone) assert.Equal(t, 0, offset) } }
func TestAddTxAPI(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) }
oldMaxTxs := l2DBWithACC.maxTxs // set max number of pending txs that can be kept in the pool to 5
l2DBWithACC.maxTxs = 5
poolL2Txs, err := generatePoolL2Txs() txs := make([]*PoolL2TxWrite, len(poolL2Txs)) for i := range poolL2Txs { txs[i] = NewPoolL2TxWriteFromPoolL2Tx(&poolL2Txs[i]) } require.NoError(t, err) require.GreaterOrEqual(t, len(poolL2Txs), 8) for i := range txs[:5] { err := l2DBWithACC.AddTxAPI(txs[i]) require.NoError(t, err) fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID) require.NoError(t, err) assertTx(t, &poolL2Txs[i], fetchedTx) nameZone, offset := fetchedTx.Timestamp.Zone() assert.Equal(t, "UTC", nameZone) assert.Equal(t, 0, offset) } err = l2DBWithACC.AddTxAPI(txs[5]) assert.Equal(t, errPoolFull, tracerr.Unwrap(err)) // reset maxTxs to original value
l2DBWithACC.maxTxs = oldMaxTxs
// set minFeeUSD to a high value than the tx feeUSD to test the error
// of inserting a tx with lower than min fee
oldMinFeeUSD := l2DBWithACC.minFeeUSD tx := txs[5] feeAmount, err := common.CalcFeeAmount(tx.Amount, tx.Fee) require.NoError(t, err) feeAmountUSD := common.TokensToUSD(feeAmount, decimals, tokenValue) // set minFeeUSD higher than the tx fee to trigger the error
l2DBWithACC.minFeeUSD = feeAmountUSD + 1 err = l2DBWithACC.AddTxAPI(tx) require.Error(t, err) assert.Regexp(t, "tx.feeUSD (.*) < minFeeUSD (.*)", err.Error()) // reset minFeeUSD to original value
l2DBWithACC.minFeeUSD = oldMinFeeUSD }
func TestUpdateTxsInfo(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err)
// once added, change the Info parameter
poolL2Txs[i].Info = "test" } // update the txs
err = l2DB.UpdateTxsInfo(poolL2Txs) require.NoError(t, err)
for i := range poolL2Txs { fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID) require.NoError(t, err) assert.Equal(t, "test", fetchedTx.Info) } }
func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) { // Check that timestamp has been set within the last 3 seconds
assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix()) assert.GreaterOrEqual(t, time.Now().UTC().Unix(), actual.Timestamp.Unix()) expected.Timestamp = actual.Timestamp // Check absolute fee
// find token
token := tokens[expected.TokenID] // If the token has value in USD setted
if token.USDUpdate != nil { assert.Less(t, token.USDUpdate.Unix()-3, actual.AbsoluteFeeUpdate.Unix()) expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate // Set expected fee
amountUSD := common.TokensToUSD(expected.Amount, token.Decimals, *token.USD) expected.AbsoluteFee = amountUSD * expected.Fee.Percentage() test.AssertUSD(t, &expected.AbsoluteFee, &actual.AbsoluteFee) } assert.Equal(t, expected, actual) }
// NO UPDATE: benchmarks will be done after impl is finished
// func BenchmarkAddTxTest(b *testing.B) {
// const nInserts = 20
// test.WipeDB(l2DB.DB())
// txs := test.GenPoolTxs(nInserts, tokens)
// now := time.Now()
// for _, tx := range txs {
// _ = l2DB.AddTxTest(tx)
// }
// elapsedTime := time.Since(now)
// log.Info("Time to insert 2048 txs:", elapsedTime)
// }
func TestGetPending(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) var pendingTxs []*common.PoolL2Tx for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) pendingTxs = append(pendingTxs, &poolL2Txs[i]) } fetchedTxs, err := l2DB.GetPendingTxs() require.NoError(t, err) assert.Equal(t, len(pendingTxs), len(fetchedTxs)) for i := range fetchedTxs { assertTx(t, pendingTxs[i], &fetchedTxs[i]) } // Check AbsoluteFee amount
for i := range fetchedTxs { tx := &fetchedTxs[i] feeAmount, err := common.CalcFeeAmount(tx.Amount, tx.Fee) require.NoError(t, err) feeAmountUSD := common.TokensToUSD(feeAmount, tokens[tx.TokenID].Decimals, *tokens[tx.TokenID].USD) assert.InEpsilon(t, feeAmountUSD, tx.AbsoluteFee, 0.01) } }
func TestStartForging(t *testing.T) { // Generate txs
var fakeBatchNum common.BatchNum = 33 err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) var startForgingTxIDs []common.TxID randomizer := 0 // Add txs to DB
for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 { startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID) } randomizer++ } // Start forging txs
err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum) require.NoError(t, err) // Fetch txs and check that they've been updated correctly
for _, id := range startForgingTxIDs { fetchedTx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State) assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum) } }
func TestDoneForging(t *testing.T) { // Generate txs
var fakeBatchNum common.BatchNum = 33 err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) var startForgingTxIDs []common.TxID randomizer := 0 // Add txs to DB
for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 { startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID) } randomizer++ } // Start forging txs
err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum) require.NoError(t, err)
var doneForgingTxIDs []common.TxID randomizer = 0 for _, txID := range startForgingTxIDs { if randomizer%2 == 0 { doneForgingTxIDs = append(doneForgingTxIDs, txID) } randomizer++ } // Done forging txs
err = l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum) require.NoError(t, err)
// Fetch txs and check that they've been updated correctly
for _, id := range doneForgingTxIDs { fetchedTx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State) assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum) } }
func TestInvalidate(t *testing.T) { // Generate txs
var fakeBatchNum common.BatchNum = 33 err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) var invalidTxIDs []common.TxID randomizer := 0 // Add txs to DB
for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) if poolL2Txs[i].State != common.PoolL2TxStateInvalid && randomizer%2 == 0 { randomizer++ invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID) } } // Invalidate txs
err = l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum) require.NoError(t, err) // Fetch txs and check that they've been updated correctly
for _, id := range invalidTxIDs { fetchedTx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State) assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum) } }
func TestInvalidateOldNonces(t *testing.T) { // Generate txs
var fakeBatchNum common.BatchNum = 33 err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err) // Update Accounts currentNonce
var updateAccounts []common.IdxNonce var currentNonce = common.Nonce(1) for i := range accs { updateAccounts = append(updateAccounts, common.IdxNonce{ Idx: accs[i].Idx, Nonce: common.Nonce(currentNonce), }) } // Add txs to DB
var invalidTxIDs []common.TxID for i := range poolL2Txs { if poolL2Txs[i].Nonce < currentNonce { invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID) } err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) } // sanity check
require.Greater(t, len(invalidTxIDs), 0)
err = l2DB.InvalidateOldNonces(updateAccounts, fakeBatchNum) require.NoError(t, err) // Fetch txs and check that they've been updated correctly
for _, id := range invalidTxIDs { fetchedTx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State) assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum) } }
// TestReorg: first part of the test with reorg
// With invalidated transactions BEFORE reorgBatch
// And forged transactions in reorgBatch
func TestReorg(t *testing.T) { // Generate txs
const lastValidBatch common.BatchNum = 20 const reorgBatch common.BatchNum = lastValidBatch + 1 err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err)
reorgedTxIDs := []common.TxID{} nonReorgedTxIDs := []common.TxID{} var startForgingTxIDs []common.TxID var invalidTxIDs []common.TxID var allTxRandomize []common.TxID randomizer := 0 // Add txs to DB
for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 { startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID) allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID) } else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 { invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID) allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID) } randomizer++ } // Start forging txs
err = l2DB.StartForging(startForgingTxIDs, lastValidBatch) require.NoError(t, err)
var doneForgingTxIDs []common.TxID randomizer = 0 for _, txID := range allTxRandomize { invalidTx := false for i := range invalidTxIDs { if invalidTxIDs[i] == txID { invalidTx = true nonReorgedTxIDs = append(nonReorgedTxIDs, txID) } } if !invalidTx { if randomizer%2 == 0 { doneForgingTxIDs = append(doneForgingTxIDs, txID) reorgedTxIDs = append(reorgedTxIDs, txID) } else { nonReorgedTxIDs = append(nonReorgedTxIDs, txID) } randomizer++ } }
// Invalidate txs BEFORE reorgBatch --> nonReorg
err = l2DB.InvalidateTxs(invalidTxIDs, lastValidBatch) require.NoError(t, err) // Done forging txs in reorgBatch --> Reorg
err = l2DB.DoneForging(doneForgingTxIDs, reorgBatch) require.NoError(t, err)
err = l2DB.Reorg(lastValidBatch) require.NoError(t, err) for _, id := range reorgedTxIDs { tx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Nil(t, tx.BatchNum) assert.Equal(t, common.PoolL2TxStatePending, tx.State) } for _, id := range nonReorgedTxIDs { fetchedTx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum) } }
// TestReorg: second part of test with reorg
// With invalidated transactions in reorgBatch
// And forged transactions BEFORE reorgBatch
func TestReorg2(t *testing.T) { // Generate txs
const lastValidBatch common.BatchNum = 20 const reorgBatch common.BatchNum = lastValidBatch + 1 err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err)
reorgedTxIDs := []common.TxID{} nonReorgedTxIDs := []common.TxID{} var startForgingTxIDs []common.TxID var invalidTxIDs []common.TxID var allTxRandomize []common.TxID randomizer := 0 // Add txs to DB
for i := range poolL2Txs { err := l2DB.AddTxTest(&poolL2Txs[i]) require.NoError(t, err) if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 { startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID) allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID) } else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 { invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID) allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID) } randomizer++ } // Start forging txs
err = l2DB.StartForging(startForgingTxIDs, lastValidBatch) require.NoError(t, err)
var doneForgingTxIDs []common.TxID randomizer = 0 for _, txID := range allTxRandomize { invalidTx := false for i := range invalidTxIDs { if invalidTxIDs[i] == txID { invalidTx = true reorgedTxIDs = append(reorgedTxIDs, txID) } } if !invalidTx { if randomizer%2 == 0 { doneForgingTxIDs = append(doneForgingTxIDs, txID) } nonReorgedTxIDs = append(nonReorgedTxIDs, txID) randomizer++ } } // Done forging txs BEFORE reorgBatch --> nonReorg
err = l2DB.DoneForging(doneForgingTxIDs, lastValidBatch) require.NoError(t, err) // Invalidate txs in reorgBatch --> Reorg
err = l2DB.InvalidateTxs(invalidTxIDs, reorgBatch) require.NoError(t, err)
err = l2DB.Reorg(lastValidBatch) require.NoError(t, err) for _, id := range reorgedTxIDs { tx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Nil(t, tx.BatchNum) assert.Equal(t, common.PoolL2TxStatePending, tx.State) } for _, id := range nonReorgedTxIDs { fetchedTx, err := l2DBWithACC.GetTxAPI(id) require.NoError(t, err) assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum) } }
func TestPurge(t *testing.T) { // Generate txs
err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } // generatePoolL2Txs
generateTx := int(l2DB.maxTxs/8 + 1) var poolL2Tx []common.PoolL2Tx for i := 0; i < generateTx; i++ { poolL2TxAux, err := generatePoolL2Txs() require.NoError(t, err) poolL2Tx = append(poolL2Tx, poolL2TxAux...) }
afterTTLIDs := []common.TxID{} keepedIDs := []common.TxID{} var deletedIDs []common.TxID var invalidTxIDs []common.TxID var doneForgingTxIDs []common.TxID const toDeleteBatchNum common.BatchNum = 30 safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1 // Add txs to the DB
for i := 0; i < len(poolL2Tx); i++ { tx := poolL2Tx[i] if i%2 == 0 { // keep tx
keepedIDs = append(keepedIDs, tx.TxID) } else { // delete after safety period
if i%3 == 0 { doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID) } else if i%5 == 0 { invalidTxIDs = append(invalidTxIDs, tx.TxID) } else { afterTTLIDs = append(afterTTLIDs, tx.TxID) } deletedIDs = append(deletedIDs, poolL2Tx[i].TxID) } err := l2DB.AddTxTest(&tx) require.NoError(t, err) } // Set batchNum keeped txs
for i := range keepedIDs { _, err = l2DB.dbWrite.Exec( "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;", safeBatchNum, keepedIDs[i], ) require.NoError(t, err) } // Start forging txs and set batchNum
err = l2DB.StartForging(doneForgingTxIDs, toDeleteBatchNum) require.NoError(t, err) // Done forging txs and set batchNum
err = l2DB.DoneForging(doneForgingTxIDs, toDeleteBatchNum) require.NoError(t, err) // Invalidate txs and set batchNum
err = l2DB.InvalidateTxs(invalidTxIDs, toDeleteBatchNum) require.NoError(t, err) // Update timestamp of afterTTL txs
deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0) for _, id := range afterTTLIDs { // Set timestamp
_, err = l2DB.dbWrite.Exec( "UPDATE tx_pool SET timestamp = $1, state = $2 WHERE tx_id = $3;", deleteTimestamp, common.PoolL2TxStatePending, id, ) require.NoError(t, err) }
// Purge txs
err = l2DB.Purge(safeBatchNum) require.NoError(t, err) // Check results
for _, id := range deletedIDs { _, err := l2DB.GetTx(id) assert.Error(t, err) } for _, id := range keepedIDs { _, err := l2DB.GetTx(id) require.NoError(t, err) } }
func TestAuth(t *testing.T) { test.WipeDB(l2DB.DB()) const nAuths = 5 chainID := uint16(0) hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6") // Generate authorizations
auths := test.GenAuths(nAuths, chainID, hermezContractAddr) for i := 0; i < len(auths); i++ { // Add to the DB
err := l2DB.AddAccountCreationAuth(auths[i]) require.NoError(t, err) // Fetch from DB
auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr) require.NoError(t, err) // Check fetched vs generated
assert.Equal(t, auths[i].EthAddr, auth.EthAddr) assert.Equal(t, auths[i].BJJ, auth.BJJ) assert.Equal(t, auths[i].Signature, auth.Signature) assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix()) nameZone, offset := auths[i].Timestamp.Zone() assert.Equal(t, "UTC", nameZone) assert.Equal(t, 0, offset) } }
func TestManyAuth(t *testing.T) { test.WipeDB(l2DB.DB()) const nAuths = 5 chainID := uint16(0) hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6") // Generate authorizations
genAuths := test.GenAuths(nAuths, chainID, hermezContractAddr) auths := make([]common.AccountCreationAuth, len(genAuths)) // Convert to a non-pointer slice
for i := 0; i < len(genAuths); i++ { auths[i] = *genAuths[i] }
// Add a duplicate one to check the not exist condition
err := l2DB.AddAccountCreationAuth(genAuths[0]) require.NoError(t, err)
// Add to the DB
err = l2DB.AddManyAccountCreationAuth(auths) require.NoError(t, err)
// Assert the result
for i := 0; i < len(auths); i++ { // Fetch from DB
auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr) require.NoError(t, err) // Check fetched vs generated
assert.Equal(t, auths[i].EthAddr, auth.EthAddr) assert.Equal(t, auths[i].BJJ, auth.BJJ) assert.Equal(t, auths[i].Signature, auth.Signature) assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix()) nameZone, offset := auths[i].Timestamp.Zone() assert.Equal(t, "UTC", nameZone) assert.Equal(t, 0, offset) } }
func TestAddGet(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } poolL2Txs, err := generatePoolL2Txs() require.NoError(t, err)
// We will work with only 3 txs
require.GreaterOrEqual(t, len(poolL2Txs), 3) txs := poolL2Txs[:3] // NOTE: By changing the tx fields, the signature will no longer be
// valid, but we are not checking the signautre here so it's OK.
// 0. Has ToIdx >= 256 && ToEthAddr == 0 && ToBJJ == 0
require.GreaterOrEqual(t, int(txs[0].ToIdx), 256) txs[0].ToEthAddr = ethCommon.Address{} txs[0].ToBJJ = babyjub.PublicKeyComp{} // 1. Has ToIdx >= 256 && ToEthAddr != 0 && ToBJJ != 0
require.GreaterOrEqual(t, int(txs[1].ToIdx), 256) require.NotEqual(t, txs[1].ToEthAddr, ethCommon.Address{}) require.NotEqual(t, txs[1].ToBJJ, babyjub.PublicKeyComp{}) // 2. Has ToIdx == 0 && ToEthAddr != 0 && ToBJJ != 0
txs[2].ToIdx = 0 require.NotEqual(t, txs[2].ToEthAddr, ethCommon.Address{}) require.NotEqual(t, txs[2].ToBJJ, babyjub.PublicKeyComp{})
for i := 0; i < len(txs); i++ { require.NoError(t, txs[i].SetID()) require.NoError(t, l2DB.AddTxTest(&txs[i])) } // Verify that the inserts haven't altered any field (specially
// ToEthAddr and ToBJJ)
for i := 0; i < len(txs); i++ { dbTx, err := l2DB.GetTx(txs[i].TxID) require.NoError(t, err) // Ignore Timestamp, AbsoluteFee, AbsoluteFeeUpdate
txs[i].Timestamp = dbTx.Timestamp txs[i].AbsoluteFee = dbTx.AbsoluteFee txs[i].AbsoluteFeeUpdate = dbTx.AbsoluteFeeUpdate assert.Equal(t, txs[i], *dbTx) } }
func TestPurgeByExternalDelete(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { log.Error("Error prepare historyDB", err) } txs, err := generatePoolL2Txs() require.NoError(t, err)
// We will work with 8 txs
require.GreaterOrEqual(t, len(txs), 8) txs = txs[:8] for i := range txs { require.NoError(t, l2DB.AddTxTest(&txs[i])) }
// We will recreate this scenario:
// tx index, status , external_delete
// 0 , pending, false
// 1 , pending, false
// 2 , pending, true // will be deleted
// 3 , pending, true // will be deleted
// 4 , fging , false
// 5 , fging , false
// 6 , fging , true
// 7 , fging , true
require.NoError(t, l2DB.StartForging( []common.TxID{txs[4].TxID, txs[5].TxID, txs[6].TxID, txs[7].TxID}, 1)) _, err = l2DB.dbWrite.Exec( `UPDATE tx_pool SET external_delete = true WHERE tx_id IN ($1, $2, $3, $4) ;`, txs[2].TxID, txs[3].TxID, txs[6].TxID, txs[7].TxID, ) require.NoError(t, err) require.NoError(t, l2DB.PurgeByExternalDelete())
// Query txs that are have been not deleted
for _, i := range []int{0, 1, 4, 5, 6, 7} { txID := txs[i].TxID _, err := l2DB.GetTx(txID) require.NoError(t, err) }
// Query txs that have been deleted
for _, i := range []int{2, 3} { txID := txs[i].TxID _, err := l2DB.GetTx(txID) require.Equal(t, sql.ErrNoRows, tracerr.Unwrap(err)) } }
|