diff --git a/db/l2db/l2db_test.go b/db/l2db/l2db_test.go index f0ecd96..731c9d1 100644 --- a/db/l2db/l2db_test.go +++ b/db/l2db/l2db_test.go @@ -1,23 +1,28 @@ package l2db import ( + "math" "math/big" "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/jmoiron/sqlx" + "github.com/hermeznetwork/hermez-node/test/til" "github.com/stretchr/testify/assert" ) var l2DB *L2DB -var tokens []common.Token -var tokensUSD []historydb.TokenWithUSD +var historyDB *historydb.HistoryDB +var tc *til.Context +var tokens map[common.TokenID]historydb.TokenWithUSD +var tokensValue map[common.TokenID]float64 +var accs map[common.Idx]common.Account func TestMain(m *testing.M) { // init DB @@ -28,7 +33,7 @@ func TestMain(m *testing.M) { } l2DB = NewL2DB(db, 10, 100, 24*time.Hour) test.WipeDB(l2DB.DB()) - tokens, tokensUSD = prepareHistoryDB(db) + historyDB = historydb.NewHistoryDB(db) // Run tests result := m.Run() // Close DB @@ -38,59 +43,116 @@ func TestMain(m *testing.M) { os.Exit(result) } -func prepareHistoryDB(db *sqlx.DB) ([]common.Token, []historydb.TokenWithUSD) { - historyDB := historydb.NewHistoryDB(db) - const fromBlock int64 = 1 - const toBlock int64 = 5 - // Store blocks to historyDB - blocks := test.GenBlocks(fromBlock, toBlock) - if err := historyDB.AddBlocks(blocks); err != nil { - panic(err) +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: 2000 + CreateAccountDeposit(2) A: 2000 + CreateAccountDeposit(1) B: 1000 + CreateAccountDeposit(2) B: 1000 + > batchL1 + > batchL1 + > block + > block + ` + + tc = til.NewContext(common.RollupConstMaxL1UserTx) + tilCfgExtra := til.ConfigExtra{ + BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"), + CoordUser: "A", } - // Store tokens to historyDB - const nTokens = 5 - tokens, ethToken := test.GenTokens(nTokens, blocks) - if err := historyDB.AddTokens(tokens); err != nil { - panic(err) + blocks, err := tc.GenerateBlocks(setBlockchain) + if err != nil { + return err } - tokens = append([]common.Token{ethToken}, tokens...) - readTokens := []historydb.TokenWithUSD{} - for i, token := range tokens { - readToken := historydb.TokenWithUSD{ - TokenID: token.TokenID, - EthBlockNum: token.EthBlockNum, - EthAddr: token.EthAddr, - Name: token.Name, - Symbol: token.Symbol, - Decimals: token.Decimals, + + err = tc.FillBlocksExtra(blocks, &tilCfgExtra) + if err != nil { + return err + } + tokens = make(map[common.TokenID]historydb.TokenWithUSD) + tokensValue = make(map[common.TokenID]float64) + accs = make(map[common.Idx]common.Account) + value := 5 * 5.389329 + now := time.Now().UTC() + // Add all blocks except for the last one + for i := range blocks[:len(blocks)-1] { + err = historyDB.AddBlockSCData(&blocks[i]) + if err != nil { + return err + } + for _, batch := range blocks[i].Rollup.Batches { + for _, account := range batch.CreatedAccounts { + accs[account.Idx] = account + } } - if i%2 != 0 { - value := float64(i) * 5.4321 - if err := historyDB.UpdateTokenValue(token.Symbol, value); err != nil { - panic(err) + 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, } - now := time.Now().UTC() + tokensValue[token.TokenID] = value / math.Pow(10, float64(token.Decimals)) readToken.USDUpdate = &now readToken.USD = &value + tokens[token.TokenID] = readToken } - readTokens = append(readTokens, readToken) + // Set value to the tokens (tokens have no symbol) + tokenSymbol := "" + err := historyDB.UpdateTokenValue(tokenSymbol, value) + if err != nil { + return err + } + } + return nil +} + +func generatePoolL2Txs() ([]common.PoolL2Tx, error) { + setPool := ` + Type: PoolL2 + PoolTransfer(1) A-B: 6 (4) + PoolTransfer(2) A-B: 3 (1) + PoolTransfer(1) B-A: 5 (2) + PoolTransfer(2) B-A: 10 (3) + PoolTransfer(1) A-B: 7 (2) + PoolTransfer(2) A-B: 2 (1) + PoolTransfer(1) B-A: 8 (2) + PoolTransfer(2) B-A: 1 (1) + PoolTransfer(1) A-B: 3 (1) + PoolTransfer(2) B-A: 5 (2) + + PoolExit(1) A: 5 (2) + PoolExit(2) B: 3 (1) + ` + poolL2Txs, err := tc.GeneratePoolL2Txs(setPool) + if err != nil { + return nil, err } - return tokens, readTokens + return poolL2Txs, nil } func TestAddTxTest(t *testing.T) { - // Gen poolTxs - const nInserts = 20 - test.WipeDB(l2DB.DB()) - txs := test.GenPoolTxs(nInserts, tokens) - for _, tx := range txs { - // TODO: UPDATE with til - err := l2DB.AddTxTest(tx) + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) + for i := range poolL2Txs { + err := l2DB.AddTxTest(&poolL2Txs[i]) assert.NoError(t, err) - fetchedTx, err := l2DB.GetTx(tx.TxID) + fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID) assert.NoError(t, err) - // assertReadTx(t, commonToRead(tx, tokens), fetchedTx) - assertTx(t, tx, fetchedTx) + assertTx(t, &poolL2Txs[i], fetchedTx) nameZone, offset := fetchedTx.Timestamp.Zone() assert.Equal(t, "UTC", nameZone) assert.Equal(t, 0, offset) @@ -104,13 +166,7 @@ func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) { expected.Timestamp = actual.Timestamp // Check absolute fee // find token - token := historydb.TokenWithUSD{} - for _, tkn := range tokensUSD { - if expected.TokenID == tkn.TokenID { - token = tkn - break - } - } + token := tokens[expected.TokenID] // If the token has value in USD setted if token.USDUpdate != nil { assert.Equal(t, token.USDUpdate.Unix(), actual.AbsoluteFeeUpdate.Unix()) @@ -138,17 +194,17 @@ func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) { // } func TestGetPending(t *testing.T) { - const nInserts = 20 - test.WipeDB(l2DB.DB()) - // TODO: UPDATE with til - txs := test.GenPoolTxs(nInserts, tokens) + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) var pendingTxs []*common.PoolL2Tx - for _, tx := range txs { - err := l2DB.AddTxTest(tx) + for i := range poolL2Txs { + err := l2DB.AddTxTest(&poolL2Txs[i]) assert.NoError(t, err) - if tx.State == common.PoolL2TxStatePending { - pendingTxs = append(pendingTxs, tx) - } + pendingTxs = append(pendingTxs, &poolL2Txs[i]) } fetchedTxs, err := l2DB.GetPendingTxs() assert.NoError(t, err) @@ -158,180 +214,219 @@ func TestGetPending(t *testing.T) { } } -/* - TODO: update with til func TestStartForging(t *testing.T) { // Generate txs - const nInserts = 60 const fakeBatchNum common.BatchNum = 33 - test.WipeDB(l2DB.DB()) - txs := test.GenPoolTxs(nInserts, tokens) + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) var startForgingTxIDs []common.TxID randomizer := 0 // Add txs to DB - for _, tx := range txs { - err := l2DB.AddTxTest(tx) + for i := range poolL2Txs { + err := l2DB.AddTxTest(&poolL2Txs[i]) assert.NoError(t, err) - if tx.State == common.PoolL2TxStatePending && randomizer%2 == 0 { - randomizer++ - startForgingTxIDs = append(startForgingTxIDs, tx.TxID) + if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 { + startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID) } + randomizer++ } // Start forging txs - err := l2DB.StartForging(startForgingTxIDs, fakeBatchNum) + err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum) assert.NoError(t, err) // Fetch txs and check that they've been updated correctly for _, id := range startForgingTxIDs { - fetchedTx, err := l2DB.GetTx(id) + fetchedTx, err := l2DB.GetTxAPI(id) assert.NoError(t, err) assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State) assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum) } } -*/ -/* - TODO: update with til func TestDoneForging(t *testing.T) { // Generate txs - const nInserts = 60 const fakeBatchNum common.BatchNum = 33 - test.WipeDB(l2DB.DB()) - txs := test.GenPoolTxs(nInserts, tokens) - var doneForgingTxIDs []common.TxID + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) + var startForgingTxIDs []common.TxID randomizer := 0 // Add txs to DB - for _, tx := range txs { - err := l2DB.AddTxTest(tx) + for i := range poolL2Txs { + err := l2DB.AddTxTest(&poolL2Txs[i]) assert.NoError(t, err) - if tx.State == common.PoolL2TxStateForging && randomizer%2 == 0 { - randomizer++ - doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID) + if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 { + startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID) } + randomizer++ } // Start forging txs - err := l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum) + err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum) assert.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) + assert.NoError(t, err) + // Fetch txs and check that they've been updated correctly for _, id := range doneForgingTxIDs { - fetchedTx, err := l2DB.GetTx(id) + fetchedTx, err := l2DB.GetTxAPI(id) assert.NoError(t, err) assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State) assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum) } } -*/ -/* - TODO: update with til func TestInvalidate(t *testing.T) { // Generate txs - const nInserts = 60 const fakeBatchNum common.BatchNum = 33 - test.WipeDB(l2DB.DB()) - txs := test.GenPoolTxs(nInserts, tokens) + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) var invalidTxIDs []common.TxID randomizer := 0 // Add txs to DB - for _, tx := range txs { - err := l2DB.AddTxTest(tx) + for i := range poolL2Txs { + err := l2DB.AddTxTest(&poolL2Txs[i]) assert.NoError(t, err) - if tx.State != common.PoolL2TxStateInvalid && randomizer%2 == 0 { + if poolL2Txs[i].State != common.PoolL2TxStateInvalid && randomizer%2 == 0 { randomizer++ - invalidTxIDs = append(invalidTxIDs, tx.TxID) + invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID) } } - // Start forging txs - err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum) + // Invalidate txs + err = l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum) assert.NoError(t, err) // Fetch txs and check that they've been updated correctly for _, id := range invalidTxIDs { - fetchedTx, err := l2DB.GetTx(id) + fetchedTx, err := l2DB.GetTxAPI(id) assert.NoError(t, err) assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State) assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum) } } -*/ - -/* - - TODO: update with til - func TestCheckNonces(t *testing.T) { // Generate txs - const nInserts = 60 const fakeBatchNum common.BatchNum = 33 - test.WipeDB(l2DB.DB()) - txs := test.GenPoolTxs(nInserts, tokens) - var invalidTxIDs []common.TxID - // Generate accounts - const nAccoutns = 2 - const currentNonce = 2 - accs := []common.Account{} - for i := 0; i < nAccoutns; i++ { - accs = append(accs, common.Account{ - Idx: common.Idx(i), - Nonce: currentNonce, - }) + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) + // Update Accounts currentNonce + var updateAccounts []common.Account + const currentNonce = common.Nonce(1) + for i := range accs { + account := accs[i] + account.Nonce = common.Nonce(currentNonce) + updateAccounts = append(updateAccounts, account) } // Add txs to DB - for i := 0; i < len(txs); i++ { - if txs[i].State != common.PoolL2TxStateInvalid { - if i%2 == 0 { // Ensure transaction will be marked as invalid due to old nonce - txs[i].Nonce = accs[i%len(accs)].Nonce - txs[i].FromIdx = accs[i%len(accs)].Idx - invalidTxIDs = append(invalidTxIDs, txs[i].TxID) - } else { // Ensure transaction will NOT be marked as invalid due to old nonce - txs[i].Nonce = currentNonce + 1 - } + var invalidTxIDs []common.TxID + for i := range poolL2Txs { + if poolL2Txs[i].Nonce <= currentNonce { + invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID) } - err := l2DB.AddTxTest(txs[i]) + err := l2DB.AddTxTest(&poolL2Txs[i]) assert.NoError(t, err) } - // Start forging txs - err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum) + + err = l2DB.CheckNonces(updateAccounts, fakeBatchNum) assert.NoError(t, err) // Fetch txs and check that they've been updated correctly for _, id := range invalidTxIDs { - fetchedTx, err := l2DB.GetTx(id) + fetchedTx, err := l2DB.GetTxAPI(id) assert.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 nInserts = 20 const lastValidBatch common.BatchNum = 20 const reorgBatch common.BatchNum = lastValidBatch + 1 - test.WipeDB(l2DB.DB()) - // TODO: update with til - txs := test.GenPoolTxs(nInserts, tokens) - // Add txs to the DB + err := prepareHistoryDB(historyDB) + if err != nil { + log.Error("Error prepare historyDB", err) + } + poolL2Txs, err := generatePoolL2Txs() + assert.NoError(t, err) + reorgedTxIDs := []common.TxID{} nonReorgedTxIDs := []common.TxID{} - for i := 0; i < len(txs); i++ { - err := l2DB.AddTxTest(txs[i]) + 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]) assert.NoError(t, err) - var batchNum common.BatchNum - if txs[i].State == common.PoolL2TxStateForged || txs[i].State == common.PoolL2TxStateInvalid { - reorgedTxIDs = append(reorgedTxIDs, txs[i].TxID) - batchNum = reorgBatch - } else { - nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID) - batchNum = lastValidBatch + 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) } - _, err = l2DB.db.Exec( - "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;", - batchNum, txs[i].TxID, - ) - assert.NoError(t, err) + randomizer++ } - err := l2DB.Reorg(lastValidBatch) + // Start forging txs + err = l2DB.StartForging(startForgingTxIDs, lastValidBatch) + assert.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) + assert.NoError(t, err) + // Done forging txs in reorgBatch --> Reorg + err = l2DB.DoneForging(doneForgingTxIDs, reorgBatch) + assert.NoError(t, err) + + err = l2DB.Reorg(lastValidBatch) assert.NoError(t, err) for _, id := range reorgedTxIDs { tx, err := l2DB.GetTxAPI(id) @@ -346,73 +441,166 @@ func TestReorg(t *testing.T) { } } -func TestPurge(t *testing.T) { - /* - - TODO: update with til - - WARNING: this should be fixed once transaktio is ready - // Generate txs - nInserts := l2DB.maxTxs + 20 - test.WipeDB(l2DB.DB()) - txs := test.GenPoolTxs(int(nInserts), tokens) - deletedIDs := []common.TxID{} - keepedIDs := []common.TxID{} - const toDeleteBatchNum common.BatchNum = 30 - safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1 - // Add txs to the DB - for i := 0; i < int(l2DB.maxTxs); i++ { - var batchNum common.BatchNum - if i%2 == 0 { // keep tx - batchNum = safeBatchNum - keepedIDs = append(keepedIDs, txs[i].TxID) - } else { // delete after safety period - batchNum = toDeleteBatchNum - if i%3 == 0 { - txs[i].State = common.PoolL2TxStateForged - } else { - txs[i].State = common.PoolL2TxStateInvalid - } - deletedIDs = append(deletedIDs, txs[i].TxID) +// 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() + assert.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]) + assert.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) + assert.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) } - err := l2DB.AddTxTest(txs[i]) - assert.NoError(t, err) - // Set batchNum - _, err = l2DB.db.Exec( - "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;", - batchNum, txs[i].TxID, - ) - assert.NoError(t, err) } - for i := int(l2DB.maxTxs); i < len(txs); i++ { - // Delete after TTL - deletedIDs = append(deletedIDs, txs[i].TxID) - err := l2DB.AddTxTest(txs[i]) - assert.NoError(t, err) - // Set timestamp - deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0) - _, err = l2DB.db.Exec( - "UPDATE tx_pool SET timestamp = $1 WHERE tx_id = $2;", - deleteTimestamp, txs[i].TxID, - ) - assert.NoError(t, err) + if !invalidTx { + if randomizer%2 == 0 { + doneForgingTxIDs = append(doneForgingTxIDs, txID) + } + nonReorgedTxIDs = append(nonReorgedTxIDs, txID) + randomizer++ } - // Purge txs - err := l2DB.Purge(safeBatchNum) + } + // Done forging txs BEFORE reorgBatch --> nonReorg + err = l2DB.DoneForging(doneForgingTxIDs, lastValidBatch) + assert.NoError(t, err) + // Invalidate txs in reorgBatch --> Reorg + err = l2DB.InvalidateTxs(invalidTxIDs, reorgBatch) + assert.NoError(t, err) + + err = l2DB.Reorg(lastValidBatch) + assert.NoError(t, err) + for _, id := range reorgedTxIDs { + tx, err := l2DB.GetTxAPI(id) assert.NoError(t, err) - // Check results - for _, id := range deletedIDs { - tx, err := l2DB.GetTx(id) - if err == nil { - log.Debug(tx) + assert.Nil(t, tx.BatchNum) + assert.Equal(t, common.PoolL2TxStatePending, tx.State) + } + for _, id := range nonReorgedTxIDs { + fetchedTx, err := l2DB.GetTxAPI(id) + assert.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 generate 10 txs + generateTx := int(l2DB.maxTxs/10 + 1) + var poolL2Tx []common.PoolL2Tx + for i := 0; i < generateTx; i++ { + poolL2TxAux, err := generatePoolL2Txs() + assert.NoError(t, err) + poolL2Tx = append(poolL2Tx, poolL2TxAux...) + } + + deletedIDs := []common.TxID{} + keepedIDs := []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 < int(l2DB.maxTxs); 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 { + invalidTxIDs = append(invalidTxIDs, tx.TxID) } - assert.Error(t, err) + deletedIDs = append(deletedIDs, tx.TxID) } - for _, id := range keepedIDs { - _, err := l2DB.GetTx(id) - assert.NoError(t, err) + err := l2DB.AddTxTest(&tx) + assert.NoError(t, err) + } + // Set batchNum keeped txs + for i := range keepedIDs { + _, err = l2DB.db.Exec( + "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;", + safeBatchNum, keepedIDs[i], + ) + assert.NoError(t, err) + } + // Start forging txs and set batchNum + err = l2DB.StartForging(doneForgingTxIDs, toDeleteBatchNum) + assert.NoError(t, err) + // Done forging txs and set batchNum + err = l2DB.DoneForging(doneForgingTxIDs, toDeleteBatchNum) + assert.NoError(t, err) + // Invalidate txs and set batchNum + err = l2DB.InvalidateTxs(invalidTxIDs, toDeleteBatchNum) + assert.NoError(t, err) + for i := int(l2DB.maxTxs); i < len(poolL2Tx); i++ { + // Delete after TTL + deletedIDs = append(deletedIDs, poolL2Tx[i].TxID) + err := l2DB.AddTxTest(&poolL2Tx[i]) + assert.NoError(t, err) + // Set timestamp + deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0) + _, err = l2DB.db.Exec( + "UPDATE tx_pool SET timestamp = $1 WHERE tx_id = $2;", + deleteTimestamp, poolL2Tx[i].TxID, + ) + assert.NoError(t, err) + } + + // Purge txs + err = l2DB.Purge(safeBatchNum) + assert.NoError(t, err) + // Check results + for _, id := range deletedIDs { + tx, err := l2DB.GetTx(id) + if err == nil { + log.Debug(tx) } - */ + assert.Error(t, err) + } + for _, id := range keepedIDs { + _, err := l2DB.GetTx(id) + assert.NoError(t, err) + } } func TestAuth(t *testing.T) { diff --git a/test/til/txs.go b/test/til/txs.go index 829261b..48d1afa 100644 --- a/test/til/txs.go +++ b/test/til/txs.go @@ -591,6 +591,7 @@ func (tc *Context) GeneratePoolL2Txs(set string) ([]common.PoolL2Tx, error) { TokenID: inst.tokenID, Amount: big.NewInt(int64(inst.amount)), Nonce: tc.Users[inst.from].Accounts[inst.tokenID].Nonce, + State: common.PoolL2TxStatePending, Type: common.TxTypeExit, } nTx, err := common.NewPoolL2Tx(&tx)