Browse Source

Use til for batches and blocks at historydb

feature/sql-semaphore1
Arnau B 4 years ago
parent
commit
bed25d424a
6 changed files with 300 additions and 188 deletions
  1. +17
    -0
      api/api_test.go
  2. +0
    -10
      db/historydb/historydb.go
  3. +232
    -161
      db/historydb/historydb_test.go
  4. +25
    -15
      db/l2db/l2db_test.go
  5. +2
    -2
      db/migrations/0001.sql
  6. +24
    -0
      test/historydb.go

+ 17
- 0
api/api_test.go

@ -71,6 +71,16 @@ var api *API
// emulating the task of the synchronizer in order to have data to be returned // emulating the task of the synchronizer in order to have data to be returned
// by the API endpoints that will be tested // by the API endpoints that will be tested
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
/*
til update considerations:
1. Two instructions sets should be enough (one for L2 another for historydb)
2. FillBlocksExtra function must be used, there is a coment on top of the function that explains which data is setted
3. Some data will not be generated by til nor FillBlocksExtra, test.GenXXX will still be required to cover this cases
4. Most of the historydb inserts should be replaced with nBlocks calls to AddBlockSCData
5. When defining til instructions, there is no need to have 100s of entries for each table, but it's interesting to
cover all different cases (for instance all tx types)
*/
// Initializations // Initializations
// Swagger // Swagger
router := swagger.NewRouter().WithSwaggerFromFile("./swagger.yml") router := swagger.NewRouter().WithSwaggerFromFile("./swagger.yml")
@ -132,6 +142,7 @@ func TestMain(m *testing.M) {
// Fill HistoryDB and StateDB with fake data // Fill HistoryDB and StateDB with fake data
// Gen blocks and add them to DB // Gen blocks and add them to DB
const nBlocks = 5 const nBlocks = 5
// TODO: UPDATE with til
blocks := test.GenBlocks(1, nBlocks+1) blocks := test.GenBlocks(1, nBlocks+1)
err = api.h.AddBlocks(blocks) err = api.h.AddBlocks(blocks)
if err != nil { if err != nil {
@ -141,6 +152,7 @@ func TestMain(m *testing.M) {
// Gen tokens and add them to DB // Gen tokens and add them to DB
const nTokens = 10 const nTokens = 10
// TODO: UPDATE with til
tokens, ethToken := test.GenTokens(nTokens, blocks) tokens, ethToken := test.GenTokens(nTokens, blocks)
err = api.h.AddTokens(tokens) err = api.h.AddTokens(tokens)
if err != nil { if err != nil {
@ -173,6 +185,7 @@ func TestMain(m *testing.M) {
} }
// Gen batches and add them to DB // Gen batches and add them to DB
const nBatches = 10 const nBatches = 10
// TODO: UPDATE with til
batches := test.GenBatches(nBatches, blocks) batches := test.GenBatches(nBatches, blocks)
err = api.h.AddBatches(batches) err = api.h.AddBatches(batches)
if err != nil { if err != nil {
@ -184,6 +197,7 @@ func TestMain(m *testing.M) {
usrAddr := ethCommon.BigToAddress(big.NewInt(4896847)) usrAddr := ethCommon.BigToAddress(big.NewInt(4896847))
privK := babyjub.NewRandPrivKey() privK := babyjub.NewRandPrivKey()
usrBjj := privK.Public() usrBjj := privK.Public()
// TODO: UPDATE with til
accs := test.GenAccounts(totalAccounts, userAccounts, tokens, &usrAddr, usrBjj, batches) accs := test.GenAccounts(totalAccounts, userAccounts, tokens, &usrAddr, usrBjj, batches)
err = api.h.AddAccounts(accs) err = api.h.AddAccounts(accs)
if err != nil { if err != nil {
@ -207,6 +221,7 @@ func TestMain(m *testing.M) {
} }
// Gen exits and add them to DB // Gen exits and add them to DB
const totalExits = 40 const totalExits = 40
// TODO: UPDATE with til
exits := test.GenExitTree(totalExits, batches, accs) exits := test.GenExitTree(totalExits, batches, accs)
err = api.h.AddExitTree(exits) err = api.h.AddExitTree(exits)
if err != nil { if err != nil {
@ -217,10 +232,12 @@ func TestMain(m *testing.M) {
// Gen L1Txs // Gen L1Txs
const totalL1Txs = 40 const totalL1Txs = 40
const userL1Txs = 4 const userL1Txs = 4
// TODO: UPDATE with til
usrL1Txs, othrL1Txs := test.GenL1Txs(256, totalL1Txs, userL1Txs, &usrAddr, accs, tokens, blocks, batches) usrL1Txs, othrL1Txs := test.GenL1Txs(256, totalL1Txs, userL1Txs, &usrAddr, accs, tokens, blocks, batches)
// Gen L2Txs // Gen L2Txs
const totalL2Txs = 20 const totalL2Txs = 20
const userL2Txs = 4 const userL2Txs = 4
// TODO: UPDATE with til
usrL2Txs, othrL2Txs := test.GenL2Txs(256+totalL1Txs, totalL2Txs, userL2Txs, &usrAddr, accs, tokens, blocks, batches) usrL2Txs, othrL2Txs := test.GenL2Txs(256+totalL1Txs, totalL2Txs, userL2Txs, &usrAddr, accs, tokens, blocks, batches)
// Sort txs // Sort txs
sortedTxs := []txSortFielder{} sortedTxs := []txSortFielder{}

+ 0
- 10
db/historydb/historydb.go

@ -1109,16 +1109,6 @@ func (hdb *HistoryDB) GetExitsAPI(
return db.SlicePtrsToSlice(exits).([]ExitAPI), exits[0].TotalItems - uint64(len(exits)), nil return db.SlicePtrsToSlice(exits).([]ExitAPI), exits[0].TotalItems - uint64(len(exits)), nil
} }
// // GetTx returns a tx from the DB
// func (hdb *HistoryDB) GetTx(txID common.TxID) (*common.Tx, error) {
// tx := new(common.Tx)
// return tx, meddler.QueryRow(
// hdb.db, tx,
// "SELECT * FROM tx WHERE id = $1;",
// txID,
// )
// }
// GetAllL1UserTxs returns all L1UserTxs from the DB // GetAllL1UserTxs returns all L1UserTxs from the DB
func (hdb *HistoryDB) GetAllL1UserTxs() ([]common.L1Tx, error) { func (hdb *HistoryDB) GetAllL1UserTxs() ([]common.L1Tx, error) {
var txs []*common.L1Tx var txs []*common.L1Tx

+ 232
- 161
db/historydb/historydb_test.go

@ -50,27 +50,44 @@ func TestMain(m *testing.M) {
func TestBlocks(t *testing.T) { func TestBlocks(t *testing.T) {
var fromBlock, toBlock int64 var fromBlock, toBlock int64
fromBlock = 1
toBlock = 5
// Delete peviously created rows (clean previous test execs)
fromBlock = 0
toBlock = 7
// Reset DB
test.WipeDB(historyDB.DB()) test.WipeDB(historyDB.DB())
// Generate fake blocks
blocks := test.GenBlocks(fromBlock, toBlock)
// Generate blocks using til
set1 := `
Type: Blockchain
// block 0 is stored as default in the DB
// block 1 does not exist
> block // blockNum=2
> block // blockNum=3
> block // blockNum=4
> block // blockNum=5
> block // blockNum=6
`
tc := til.NewContext(1)
blocks, err := tc.GenerateBlocks(set1)
require.NoError(t, err)
// Save timestamp of a block with UTC and change it without UTC // Save timestamp of a block with UTC and change it without UTC
timestamp := time.Now().Add(time.Second * 13) timestamp := time.Now().Add(time.Second * 13)
blocks[fromBlock].Timestamp = timestamp
blocks[fromBlock].Block.Timestamp = timestamp
// Insert blocks into DB // Insert blocks into DB
for i := 0; i < len(blocks); i++ { for i := 0; i < len(blocks); i++ {
err := historyDB.AddBlock(&blocks[i])
err := historyDB.AddBlock(&blocks[i].Block)
assert.NoError(t, err) assert.NoError(t, err)
} }
// Add block 0 to the generated blocks
blocks = append(
[]common.BlockData{common.BlockData{Block: test.Block0}}, //nolint:gofmt
blocks...,
)
// Get all blocks from DB // Get all blocks from DB
fetchedBlocks, err := historyDB.GetBlocks(fromBlock, toBlock) fetchedBlocks, err := historyDB.GetBlocks(fromBlock, toBlock)
assert.Equal(t, len(blocks), len(fetchedBlocks)) assert.Equal(t, len(blocks), len(fetchedBlocks))
// Compare generated vs getted blocks // Compare generated vs getted blocks
assert.NoError(t, err) assert.NoError(t, err)
for i := range fetchedBlocks { for i := range fetchedBlocks {
assertEqualBlock(t, &blocks[i], &fetchedBlocks[i])
assertEqualBlock(t, &blocks[i].Block, &fetchedBlocks[i])
} }
// Compare saved timestamp vs getted // Compare saved timestamp vs getted
nameZoneUTC, offsetUTC := timestamp.UTC().Zone() nameZoneUTC, offsetUTC := timestamp.UTC().Zone()
@ -78,15 +95,15 @@ func TestBlocks(t *testing.T) {
assert.Equal(t, nameZoneUTC, zoneFetchedBlock) assert.Equal(t, nameZoneUTC, zoneFetchedBlock)
assert.Equal(t, offsetUTC, offsetFetchedBlock) assert.Equal(t, offsetUTC, offsetFetchedBlock)
// Get blocks from the DB one by one // Get blocks from the DB one by one
for i := fromBlock; i < toBlock; i++ {
for i := int64(2); i < toBlock; i++ { // avoid block 0 for simplicity
fetchedBlock, err := historyDB.GetBlock(i) fetchedBlock, err := historyDB.GetBlock(i)
assert.NoError(t, err) assert.NoError(t, err)
assertEqualBlock(t, &blocks[i-1], fetchedBlock)
assertEqualBlock(t, &blocks[i-1].Block, fetchedBlock)
} }
// Get last block // Get last block
lastBlock, err := historyDB.GetLastBlock() lastBlock, err := historyDB.GetLastBlock()
assert.NoError(t, err) assert.NoError(t, err)
assertEqualBlock(t, &blocks[len(blocks)-1], lastBlock)
assertEqualBlock(t, &blocks[len(blocks)-1].Block, lastBlock)
} }
func assertEqualBlock(t *testing.T, expected *common.Block, actual *common.Block) { func assertEqualBlock(t *testing.T, expected *common.Block, actual *common.Block) {
@ -96,23 +113,81 @@ func assertEqualBlock(t *testing.T, expected *common.Block, actual *common.Block
} }
func TestBatches(t *testing.T) { func TestBatches(t *testing.T) {
const fromBlock int64 = 1
const toBlock int64 = 3
// Prepare blocks in the DB
blocks := setTestBlocks(fromBlock, toBlock)
// Generate fake batches
const nBatches = 9
batches := test.GenBatches(nBatches, blocks)
// Test GetLastL1TxsNum with no batches
fetchedLastL1TxsNum, err := historyDB.GetLastL1TxsNum()
assert.NoError(t, err)
assert.Nil(t, fetchedLastL1TxsNum)
// Add batches to the DB
err = historyDB.AddBatches(batches)
assert.NoError(t, err)
// Reset DB
test.WipeDB(historyDB.DB())
// Generate batches using til (and blocks for foreign key)
set := `
Type: Blockchain
AddToken(1) // Will have value in USD
AddToken(2) // Will NOT have value in USD
CreateAccountDeposit(1) A: 2000
CreateAccountDeposit(2) A: 2000
CreateAccountDeposit(1) B: 1000
CreateAccountDeposit(2) B: 1000
> batchL1
> batchL1
Transfer(1) A-B: 100 (5)
Transfer(2) B-A: 100 (199)
> batch // batchNum=2, L2 only batch, forges transfers (mixed case of with(out) USD value)
> block
Transfer(1) A-B: 100 (5)
> batch // batchNum=3, L2 only batch, forges transfer (with USD value)
Transfer(2) B-A: 100 (199)
> batch // batchNum=4, L2 only batch, forges transfer (without USD value)
> block
`
tc := til.NewContext(common.RollupConstMaxL1UserTx)
tilCfgExtra := til.ConfigExtra{
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
CoordUser: "A",
}
blocks, err := tc.GenerateBlocks(set)
require.Nil(t, err)
err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
assert.Nil(t, err)
// Insert to DB
batches := []common.Batch{}
tokensValue := make(map[common.TokenID]float64)
lastL1TxsNum := new(int64)
for _, block := range blocks {
// Insert block
assert.NoError(t, historyDB.AddBlock(&block.Block))
// Insert tokens
for i, token := range block.Rollup.AddedTokens {
assert.NoError(t, historyDB.AddToken(&token)) //nolint:gosec
if i%2 != 0 {
// Set value to the token
value := (float64(i) + 5) * 5.389329
assert.NoError(t, historyDB.UpdateTokenValue(token.Symbol, value))
tokensValue[token.TokenID] = value / math.Pow(10, float64(token.Decimals))
}
}
// Combine all generated batches into single array
for _, batch := range block.Rollup.Batches {
batches = append(batches, batch.Batch)
forgeTxsNum := batch.Batch.ForgeL1TxsNum
if forgeTxsNum != nil && (lastL1TxsNum == nil || *lastL1TxsNum < *forgeTxsNum) {
*lastL1TxsNum = *forgeTxsNum
}
}
}
// Insert batches
assert.NoError(t, historyDB.AddBatches(batches))
// Set expected total fee
for _, batch := range batches {
total := .0
for tokenID, amount := range batch.CollectedFees {
af := new(big.Float).SetInt(amount)
amountFloat, _ := af.Float64()
total += tokensValue[tokenID] * amountFloat
}
batch.TotalFeesUSD = &total
}
// Get batches from the DB // Get batches from the DB
fetchedBatches, err := historyDB.GetBatches(0, common.BatchNum(nBatches))
fetchedBatches, err := historyDB.GetBatches(0, common.BatchNum(len(batches)+1))
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, len(batches), len(fetchedBatches))
for i, fetchedBatch := range fetchedBatches { for i, fetchedBatch := range fetchedBatches {
assert.Equal(t, batches[i], fetchedBatch) assert.Equal(t, batches[i], fetchedBatch)
} }
@ -121,38 +196,9 @@ func TestBatches(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, batches[len(batches)-1].BatchNum, fetchedLastBatchNum) assert.Equal(t, batches[len(batches)-1].BatchNum, fetchedLastBatchNum)
// Test GetLastL1TxsNum // Test GetLastL1TxsNum
fetchedLastL1TxsNum, err = historyDB.GetLastL1TxsNum()
assert.NoError(t, err)
assert.Equal(t, *batches[nBatches-1].ForgeL1TxsNum, *fetchedLastL1TxsNum)
// Test total fee
// Generate fake tokens
const nTokens = 5
tokens, ethToken := test.GenTokens(nTokens, blocks)
err = historyDB.AddTokens(tokens)
assert.NoError(t, err)
tokens = append([]common.Token{ethToken}, tokens...)
feeBatch := batches[0]
feeBatch.BatchNum = 9999
feeBatch.CollectedFees = make(map[common.TokenID]*big.Int)
var total float64
for i, token := range tokens {
value := 3.019237 * float64(i)
assert.NoError(t, historyDB.UpdateTokenValue(token.Symbol, value))
bigAmount := big.NewInt(345000000)
feeBatch.CollectedFees[token.TokenID] = bigAmount
f := new(big.Float).SetInt(bigAmount)
amount, _ := f.Float64()
total += value * (amount / math.Pow(10, float64(token.Decimals)))
}
err = historyDB.AddBatch(&feeBatch)
assert.NoError(t, err)
fetchedBatches, err = historyDB.GetBatches(feeBatch.BatchNum-1, feeBatch.BatchNum+1)
fetchedLastL1TxsNum, err := historyDB.GetLastL1TxsNum()
assert.NoError(t, err) assert.NoError(t, err)
for _, fetchedBatch := range fetchedBatches {
if fetchedBatch.BatchNum == feeBatch.BatchNum {
assert.Equal(t, total, *fetchedBatch.TotalFeesUSD)
}
}
assert.Equal(t, lastL1TxsNum, fetchedLastL1TxsNum)
} }
func TestBids(t *testing.T) { func TestBids(t *testing.T) {
@ -257,119 +303,144 @@ func TestAccounts(t *testing.T) {
} }
func TestTxs(t *testing.T) { func TestTxs(t *testing.T) {
const fromBlock int64 = 1
const toBlock int64 = 5
// Prepare blocks in the DB
blocks := setTestBlocks(fromBlock, toBlock)
// Generate fake tokens
const nTokens = 500
tokens, ethToken := test.GenTokens(nTokens, blocks)
err := historyDB.AddTokens(tokens)
assert.NoError(t, err)
tokens = append([]common.Token{ethToken}, tokens...)
// Generate fake batches
const nBatches = 10
batches := test.GenBatches(nBatches, blocks)
err = historyDB.AddBatches(batches)
assert.NoError(t, err)
// Generate fake accounts
const nAccounts = 3
accs := test.GenAccounts(nAccounts, 0, tokens, nil, nil, batches)
err = historyDB.AddAccounts(accs)
assert.NoError(t, err)
// Reset DB
test.WipeDB(historyDB.DB())
// TODO: Generate batches using til (and blocks for foreign key)
set := `
Type: Blockchain
// Things to test:
// One tx of each type
// batches that forge user L1s
// historic USD is not set if USDUpdate is too old (24h)
`
tc := til.NewContext(common.RollupConstMaxL1UserTx)
tilCfgExtra := til.ConfigExtra{
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
CoordUser: "A",
}
blocks, err := tc.GenerateBlocks(set)
require.Nil(t, err)
err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
assert.Nil(t, err)
/* /*
Uncomment once the transaction generation is fixed
!! test that batches that forge user L1s !!
!! Missing tests to check that historic USD is not set if USDUpdate is too old (24h) !!
// Generate fake L1 txs
const nL1s = 64
_, l1txs := test.GenL1Txs(256, nL1s, 0, nil, accs, tokens, blocks, batches)
err = historyDB.AddL1Txs(l1txs)
OLD TEST
const fromBlock int64 = 1
const toBlock int64 = 5
// Prepare blocks in the DB
blocks := setTestBlocks(fromBlock, toBlock)
// Generate fake tokens
const nTokens = 500
tokens, ethToken := test.GenTokens(nTokens, blocks)
err := historyDB.AddTokens(tokens)
assert.NoError(t, err)
tokens = append([]common.Token{ethToken}, tokens...)
// Generate fake batches
const nBatches = 10
batches := test.GenBatches(nBatches, blocks)
err = historyDB.AddBatches(batches)
assert.NoError(t, err) assert.NoError(t, err)
// Generate fake L2 txs
const nL2s = 2048 - nL1s
_, l2txs := test.GenL2Txs(256, nL2s, 0, nil, accs, tokens, blocks, batches)
err = historyDB.AddL2Txs(l2txs)
// Generate fake accounts
const nAccounts = 3
accs := test.GenAccounts(nAccounts, 0, tokens, nil, nil, batches)
err = historyDB.AddAccounts(accs)
assert.NoError(t, err) assert.NoError(t, err)
// Compare fetched txs vs generated txs.
fetchAndAssertTxs(t, l1txs, l2txs)
// Test trigger: L1 integrity
// from_eth_addr can't be null
l1txs[0].FromEthAddr = ethCommon.Address{}
err = historyDB.AddL1Txs(l1txs)
assert.Error(t, err)
l1txs[0].FromEthAddr = ethCommon.BigToAddress(big.NewInt(int64(5)))
// from_bjj can't be null
l1txs[0].FromBJJ = nil
err = historyDB.AddL1Txs(l1txs)
assert.Error(t, err)
privK := babyjub.NewRandPrivKey()
l1txs[0].FromBJJ = privK.Public()
// load_amount can't be null
l1txs[0].LoadAmount = nil
err = historyDB.AddL1Txs(l1txs)
assert.Error(t, err)
// Test trigger: L2 integrity
// batch_num can't be null
l2txs[0].BatchNum = 0
err = historyDB.AddL2Txs(l2txs)
assert.Error(t, err)
l2txs[0].BatchNum = 1
// nonce can't be null
l2txs[0].Nonce = 0
err = historyDB.AddL2Txs(l2txs)
assert.Error(t, err)
// Test trigger: forge L1 txs
// add next batch to DB
batchNum, toForgeL1TxsNum := test.GetNextToForgeNumAndBatch(batches)
batch := batches[0]
batch.BatchNum = batchNum
batch.ForgeL1TxsNum = toForgeL1TxsNum
assert.NoError(t, historyDB.AddBatch(&batch)) // This should update nL1s / 2 rows
// Set batch num in txs that should have been marked as forged in the DB
for i := 0; i < len(l1txs); i++ {
fetchedTx, err := historyDB.GetTx(l1txs[i].TxID)
Uncomment once the transaction generation is fixed
!! test that batches that forge user L1s !!
!! Missing tests to check that !!
// Generate fake L1 txs
const nL1s = 64
_, l1txs := test.GenL1Txs(256, nL1s, 0, nil, accs, tokens, blocks, batches)
err = historyDB.AddL1Txs(l1txs)
assert.NoError(t, err)
// Generate fake L2 txs
const nL2s = 2048 - nL1s
_, l2txs := test.GenL2Txs(256, nL2s, 0, nil, accs, tokens, blocks, batches)
err = historyDB.AddL2Txs(l2txs)
assert.NoError(t, err) assert.NoError(t, err)
if l1txs[i].ToForgeL1TxsNum == toForgeL1TxsNum {
assert.Equal(t, batchNum, *fetchedTx.BatchNum)
} else {
if fetchedTx.BatchNum != nil {
assert.NotEqual(t, batchNum, *fetchedTx.BatchNum)
// Compare fetched txs vs generated txs.
fetchAndAssertTxs(t, l1txs, l2txs)
// Test trigger: L1 integrity
// from_eth_addr can't be null
l1txs[0].FromEthAddr = ethCommon.Address{}
err = historyDB.AddL1Txs(l1txs)
assert.Error(t, err)
l1txs[0].FromEthAddr = ethCommon.BigToAddress(big.NewInt(int64(5)))
// from_bjj can't be null
l1txs[0].FromBJJ = nil
err = historyDB.AddL1Txs(l1txs)
assert.Error(t, err)
privK := babyjub.NewRandPrivKey()
l1txs[0].FromBJJ = privK.Public()
// load_amount can't be null
l1txs[0].LoadAmount = nil
err = historyDB.AddL1Txs(l1txs)
assert.Error(t, err)
// Test trigger: L2 integrity
// batch_num can't be null
l2txs[0].BatchNum = 0
err = historyDB.AddL2Txs(l2txs)
assert.Error(t, err)
l2txs[0].BatchNum = 1
// nonce can't be null
l2txs[0].Nonce = 0
err = historyDB.AddL2Txs(l2txs)
assert.Error(t, err)
// Test trigger: forge L1 txs
// add next batch to DB
batchNum, toForgeL1TxsNum := test.GetNextToForgeNumAndBatch(batches)
batch := batches[0]
batch.BatchNum = batchNum
batch.ForgeL1TxsNum = toForgeL1TxsNum
assert.NoError(t, historyDB.AddBatch(&batch)) // This should update nL1s / 2 rows
// Set batch num in txs that should have been marked as forged in the DB
for i := 0; i < len(l1txs); i++ {
fetchedTx, err := historyDB.GetTx(l1txs[i].TxID)
assert.NoError(t, err)
if l1txs[i].ToForgeL1TxsNum == toForgeL1TxsNum {
assert.Equal(t, batchNum, *fetchedTx.BatchNum)
} else {
if fetchedTx.BatchNum != nil {
assert.NotEqual(t, batchNum, *fetchedTx.BatchNum)
}
} }
} }
}
// Test helper functions for Synchronizer
// GetLastTxsPosition
expectedPosition := -1
var choosenToForgeL1TxsNum int64 = -1
for _, tx := range l1txs {
if choosenToForgeL1TxsNum == -1 && tx.ToForgeL1TxsNum > 0 {
choosenToForgeL1TxsNum = tx.ToForgeL1TxsNum
expectedPosition = tx.Position
} else if choosenToForgeL1TxsNum == tx.ToForgeL1TxsNum && expectedPosition < tx.Position {
expectedPosition = tx.Position
// Test helper functions for Synchronizer
// GetLastTxsPosition
expectedPosition := -1
var choosenToForgeL1TxsNum int64 = -1
for _, tx := range l1txs {
if choosenToForgeL1TxsNum == -1 && tx.ToForgeL1TxsNum > 0 {
choosenToForgeL1TxsNum = tx.ToForgeL1TxsNum
expectedPosition = tx.Position
} else if choosenToForgeL1TxsNum == tx.ToForgeL1TxsNum && expectedPosition < tx.Position {
expectedPosition = tx.Position
}
} }
}
position, err := historyDB.GetLastTxsPosition(choosenToForgeL1TxsNum)
assert.NoError(t, err)
assert.Equal(t, expectedPosition, position)
// GetL1UserTxs: not needed? tests were broken
// txs, err := historyDB.GetL1UserTxs(2)
// assert.NoError(t, err)
// assert.NotZero(t, len(txs))
// assert.NoError(t, err)
// assert.Equal(t, 22, position)
// // Test Update L1 TX Batch_num
// assert.Equal(t, common.BatchNum(0), txs[0].BatchNum)
// txs[0].BatchNum = common.BatchNum(1)
// txs, err = historyDB.GetL1UserTxs(2)
// assert.NoError(t, err)
// assert.NotZero(t, len(txs))
// assert.Equal(t, common.BatchNum(1), txs[0].BatchNum)
position, err := historyDB.GetLastTxsPosition(choosenToForgeL1TxsNum)
assert.NoError(t, err)
assert.Equal(t, expectedPosition, position)
// GetL1UserTxs: not needed? tests were broken
// txs, err := historyDB.GetL1UserTxs(2)
// assert.NoError(t, err)
// assert.NotZero(t, len(txs))
// assert.NoError(t, err)
// assert.Equal(t, 22, position)
// // Test Update L1 TX Batch_num
// assert.Equal(t, common.BatchNum(0), txs[0].BatchNum)
// txs[0].BatchNum = common.BatchNum(1)
// txs, err = historyDB.GetL1UserTxs(2)
// assert.NoError(t, err)
// assert.NotZero(t, len(txs))
// assert.Equal(t, common.BatchNum(1), txs[0].BatchNum)
*/ */
} }

+ 25
- 15
db/l2db/l2db_test.go

@ -84,6 +84,7 @@ func TestAddTxTest(t *testing.T) {
test.WipeDB(l2DB.DB()) test.WipeDB(l2DB.DB())
txs := test.GenPoolTxs(nInserts, tokens) txs := test.GenPoolTxs(nInserts, tokens)
for _, tx := range txs { for _, tx := range txs {
// TODO: UPDATE with til
err := l2DB.AddTxTest(tx) err := l2DB.AddTxTest(tx)
assert.NoError(t, err) assert.NoError(t, err)
fetchedTx, err := l2DB.GetTx(tx.TxID) fetchedTx, err := l2DB.GetTx(tx.TxID)
@ -123,21 +124,23 @@ func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
assert.Equal(t, expected, actual) assert.Equal(t, expected, actual)
} }
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)
}
// 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) { func TestGetPending(t *testing.T) {
const nInserts = 20 const nInserts = 20
test.WipeDB(l2DB.DB()) test.WipeDB(l2DB.DB())
// TODO: UPDATE with til
txs := test.GenPoolTxs(nInserts, tokens) txs := test.GenPoolTxs(nInserts, tokens)
var pendingTxs []*common.PoolL2Tx var pendingTxs []*common.PoolL2Tx
for _, tx := range txs { for _, tx := range txs {
@ -156,7 +159,7 @@ func TestGetPending(t *testing.T) {
} }
/* /*
WARNING: this should be fixed once transaktio is ready
TODO: update with til
func TestStartForging(t *testing.T) { func TestStartForging(t *testing.T) {
// Generate txs // Generate txs
const nInserts = 60 const nInserts = 60
@ -188,7 +191,7 @@ func TestStartForging(t *testing.T) {
*/ */
/* /*
WARNING: this should be fixed once transaktio is ready
TODO: update with til
func TestDoneForging(t *testing.T) { func TestDoneForging(t *testing.T) {
// Generate txs // Generate txs
const nInserts = 60 const nInserts = 60
@ -220,7 +223,7 @@ func TestDoneForging(t *testing.T) {
*/ */
/* /*
WARNING: this should be fixed once transaktio is ready
TODO: update with til
func TestInvalidate(t *testing.T) { func TestInvalidate(t *testing.T) {
// Generate txs // Generate txs
const nInserts = 60 const nInserts = 60
@ -252,7 +255,10 @@ func TestInvalidate(t *testing.T) {
*/ */
/* /*
WARNING: this should be fixed once transaktio is ready
TODO: update with til
func TestCheckNonces(t *testing.T) { func TestCheckNonces(t *testing.T) {
// Generate txs // Generate txs
const nInserts = 60 const nInserts = 60
@ -303,6 +309,7 @@ func TestReorg(t *testing.T) {
const lastValidBatch common.BatchNum = 20 const lastValidBatch common.BatchNum = 20
const reorgBatch common.BatchNum = lastValidBatch + 1 const reorgBatch common.BatchNum = lastValidBatch + 1
test.WipeDB(l2DB.DB()) test.WipeDB(l2DB.DB())
// TODO: update with til
txs := test.GenPoolTxs(nInserts, tokens) txs := test.GenPoolTxs(nInserts, tokens)
// Add txs to the DB // Add txs to the DB
reorgedTxIDs := []common.TxID{} reorgedTxIDs := []common.TxID{}
@ -341,6 +348,9 @@ func TestReorg(t *testing.T) {
func TestPurge(t *testing.T) { func TestPurge(t *testing.T) {
/* /*
TODO: update with til
WARNING: this should be fixed once transaktio is ready WARNING: this should be fixed once transaktio is ready
// Generate txs // Generate txs
nInserts := l2DB.maxTxs + 20 nInserts := l2DB.maxTxs + 20

+ 2
- 2
db/migrations/0001.sql

@ -453,12 +453,12 @@ BEGIN
NEW.load_amount IS NULL OR NEW.load_amount IS NULL OR
NEW.load_amount_f IS NULL OR NEW.load_amount_f IS NULL OR
(NOT NEW.user_origin AND NEW.batch_num IS NULL) THEN -- If is Coordinator L1, must include batch_num (NOT NEW.user_origin AND NEW.batch_num IS NULL) THEN -- If is Coordinator L1, must include batch_num
RAISE EXCEPTION 'Invalid L1 tx.';
RAISE EXCEPTION 'Invalid L1 tx: %', NEW;
END IF; END IF;
ELSE ELSE
-- Validate -- Validate
IF NEW.batch_num IS NULL OR NEW.nonce IS NULL THEN IF NEW.batch_num IS NULL OR NEW.nonce IS NULL THEN
RAISE EXCEPTION 'Invalid L2 tx.';
RAISE EXCEPTION 'Invalid L2 tx: %', NEW;
END IF; END IF;
-- Set fee if it's null -- Set fee if it's null
IF NEW.fee IS NULL THEN IF NEW.fee IS NULL THEN

+ 24
- 0
test/historydb.go

@ -12,6 +12,30 @@ import (
"github.com/iden3/go-merkletree" "github.com/iden3/go-merkletree"
) )
// Block0 represents Ethereum's genesis block,
// which is stored by default at HistoryDB
var Block0 common.Block = common.Block{
EthBlockNum: 0,
Hash: ethCommon.Hash([32]byte{
212, 229, 103, 64, 248, 118, 174, 248,
192, 16, 184, 106, 64, 213, 245, 103,
69, 161, 24, 208, 144, 106, 52, 230,
154, 236, 140, 13, 177, 203, 143, 163,
}), // 0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3
Timestamp: time.Date(2015, time.July, 30, 3, 26, 13, 0, time.UTC), // 2015-07-30 03:26:13
}
// EthToken represents the Ether coin, which is stored by default in the DB
// with TokenID = 0
var EthToken common.Token = common.Token{
TokenID: 0,
Name: "Ether",
Symbol: "ETH",
Decimals: 18, //nolint:gomnd
EthBlockNum: 0,
EthAddr: ethCommon.BigToAddress(big.NewInt(0)),
}
// WARNING: the generators in this file doesn't necessary follow the protocol // WARNING: the generators in this file doesn't necessary follow the protocol
// they are intended to check that the parsers between struct <==> DB are correct // they are intended to check that the parsers between struct <==> DB are correct

Loading…
Cancel
Save