Browse Source

Merge pull request #442 from hermeznetwork/feature/new-metrics-tests

Added new metrics tests
feature/sql-semaphore1
a_bennassar 4 years ago
committed by GitHub
parent
commit
65abdd408a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 175 additions and 8 deletions
  1. +2
    -3
      api/state_test.go
  2. +13
    -5
      db/historydb/historydb.go
  3. +158
    -0
      db/historydb/historydb_test.go
  4. +2
    -0
      db/historydb/views.go

+ 2
- 3
api/state_test.go

@ -64,7 +64,6 @@ func TestUpdateNetworkInfo(t *testing.T) {
}
func TestUpdateMetrics(t *testing.T) {
// TODO: Improve checks when til is integrated
// Update Metrics needs api.status.Network.LastBatch.BatchNum to be updated
lastBlock := tc.blocks[3]
lastBatchNum := common.BatchNum(3)
@ -76,7 +75,7 @@ func TestUpdateMetrics(t *testing.T) {
assert.NoError(t, err)
assert.Greater(t, api.status.Metrics.TransactionsPerBatch, float64(0))
assert.Greater(t, api.status.Metrics.BatchFrequency, float64(0))
assert.Greater(t, api.status.Metrics.TransactionsPerBatch, float64(0))
assert.Greater(t, api.status.Metrics.TransactionsPerSecond, float64(0))
assert.Greater(t, api.status.Metrics.TotalAccounts, int64(0))
assert.Greater(t, api.status.Metrics.TotalBJJs, int64(0))
assert.Greater(t, api.status.Metrics.AvgTransactionFee, float64(0))
@ -126,7 +125,7 @@ func TestGetState(t *testing.T) {
// TODO: perform real asserts (not just greater than 0)
assert.Greater(t, status.Metrics.TransactionsPerBatch, float64(0))
assert.Greater(t, status.Metrics.BatchFrequency, float64(0))
assert.Greater(t, status.Metrics.TransactionsPerBatch, float64(0))
assert.Greater(t, status.Metrics.TransactionsPerSecond, float64(0))
assert.Greater(t, status.Metrics.TotalAccounts, int64(0))
assert.Greater(t, status.Metrics.TotalBJJs, int64(0))
assert.Greater(t, status.Metrics.AvgTransactionFee, float64(0))

+ 13
- 5
db/historydb/historydb.go

@ -1823,17 +1823,25 @@ func (hdb *HistoryDB) GetMetrics(lastBatchNum common.BatchNum) (*Metrics, error)
metrics := &Metrics{}
err := meddler.QueryRow(
hdb.db, metricsTotals, `SELECT COUNT(tx.*) as total_txs,
COALESCE (MIN(tx.batch_num), 0) as batch_num
COALESCE (MIN(tx.batch_num), 0) as batch_num, COALESCE (MIN(block.timestamp),
NOW()) AS min_timestamp, COALESCE (MAX(block.timestamp), NOW()) AS max_timestamp
FROM tx INNER JOIN block ON tx.eth_block_num = block.eth_block_num
WHERE block.timestamp >= NOW() - INTERVAL '24 HOURS';`)
if err != nil {
return nil, tracerr.Wrap(err)
}
metrics.TransactionsPerSecond = float64(metricsTotals.TotalTransactions / (24 * 60 * 60))
seconds := metricsTotals.MaxTimestamp.Sub(metricsTotals.MinTimestamp).Seconds()
// Avoid dividing by 0
if seconds == 0 {
seconds++
}
metrics.TransactionsPerSecond = float64(metricsTotals.TotalTransactions) / seconds
if (lastBatchNum - metricsTotals.FirstBatchNum) > 0 {
metrics.TransactionsPerBatch = float64(int64(metricsTotals.TotalTransactions) /
int64(lastBatchNum-metricsTotals.FirstBatchNum))
metrics.TransactionsPerBatch = float64(metricsTotals.TotalTransactions) /
float64(lastBatchNum-metricsTotals.FirstBatchNum+1)
} else {
metrics.TransactionsPerBatch = float64(0)
}
@ -1846,7 +1854,7 @@ func (hdb *HistoryDB) GetMetrics(lastBatchNum common.BatchNum) (*Metrics, error)
return nil, tracerr.Wrap(err)
}
if metricsTotals.TotalBatches > 0 {
metrics.BatchFrequency = float64((24 * 60 * 60) / metricsTotals.TotalBatches)
metrics.BatchFrequency = seconds / float64(metricsTotals.TotalBatches)
} else {
metrics.BatchFrequency = 0
}

+ 158
- 0
db/historydb/historydb_test.go

@ -1028,6 +1028,164 @@ func TestAddEscapeHatchWithdrawals(t *testing.T) {
assert.Equal(t, escapeHatchWithdrawals, dbEscapeHatchWithdrawals)
}
func TestGetMetrics(t *testing.T) {
test.WipeDB(historyDB.DB())
set := `
Type: Blockchain
AddToken(1)
CreateAccountDeposit(1) A: 1000 // numTx=1
CreateAccountDeposit(1) B: 2000 // numTx=2
CreateAccountDeposit(1) C: 3000 //numTx=3
// block 0 is stored as default in the DB
// block 1 does not exist
> batchL1 // numBatches=1
> batchL1 // numBatches=2
> block // blockNum=2
Transfer(1) C-A : 10 (1) // numTx=4
> batch // numBatches=3
> block // blockNum=3
Transfer(1) B-C : 10 (1) // numTx=5
> batch // numBatches=5
> block // blockNum=4
Transfer(1) A-B : 10 (1) // numTx=6
> batch // numBatches=5
> block // blockNum=5
Transfer(1) A-B : 10 (1) // numTx=7
> batch // numBatches=6
> block // blockNum=6
`
const numBatches int = 6
const numTx int = 7
const blockNum = 6 - 1
tc := til.NewContext(uint16(0), common.RollupConstMaxL1UserTx)
tilCfgExtra := til.ConfigExtra{
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
CoordUser: "A",
}
blocks, err := tc.GenerateBlocks(set)
require.NoError(t, err)
err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
require.NoError(t, err)
// Sanity check
require.Equal(t, blockNum, len(blocks))
// Adding one batch per block
// batch frequency can be chosen
const frequency int = 15
for i := range blocks {
blocks[i].Block.Timestamp = time.Now().Add(-time.Second * time.Duration(frequency*(len(blocks)-i)))
err = historyDB.AddBlockSCData(&blocks[i])
assert.NoError(t, err)
}
res, err := historyDB.GetMetrics(common.BatchNum(numBatches))
assert.NoError(t, err)
assert.Equal(t, float64(numTx)/float64(numBatches-1), res.TransactionsPerBatch)
// Frequency is not exactly the desired one, some decimals may appear
assert.GreaterOrEqual(t, res.BatchFrequency, float64(frequency))
assert.Less(t, res.BatchFrequency, float64(frequency+1))
// Truncate frecuency into an int to do an exact check
assert.Equal(t, frequency, int(res.BatchFrequency))
// This may also be different in some decimals
// Truncate it to the third decimal to compare
assert.Equal(t, math.Trunc((float64(numTx)/float64(frequency*blockNum-frequency))/0.001)*0.001, math.Trunc(res.TransactionsPerSecond/0.001)*0.001)
assert.Equal(t, int64(3), res.TotalAccounts)
assert.Equal(t, int64(3), res.TotalBJJs)
// Til does not set fees
assert.Equal(t, float64(0), res.AvgTransactionFee)
}
func TestGetMetricsMoreThan24Hours(t *testing.T) {
test.WipeDB(historyDB.DB())
testUsersLen := 3
var set []til.Instruction
for user := 0; user < testUsersLen; user++ {
set = append(set, til.Instruction{
Typ: common.TxTypeCreateAccountDeposit,
TokenID: common.TokenID(0),
DepositAmount: big.NewInt(1000000),
Amount: big.NewInt(0),
From: fmt.Sprintf("User%02d", user),
})
set = append(set, til.Instruction{Typ: til.TypeNewBlock})
}
set = append(set, til.Instruction{Typ: til.TypeNewBatchL1})
set = append(set, til.Instruction{Typ: til.TypeNewBatchL1})
set = append(set, til.Instruction{Typ: til.TypeNewBlock})
// Transfers
for x := 0; x < 6000; x++ {
set = append(set, til.Instruction{
Typ: common.TxTypeTransfer,
TokenID: common.TokenID(0),
DepositAmount: big.NewInt(1),
Amount: big.NewInt(0),
From: "User00",
To: "User01",
})
set = append(set, til.Instruction{Typ: til.TypeNewBatch})
set = append(set, til.Instruction{Typ: til.TypeNewBlock})
}
var chainID uint16 = 0
tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocksFromInstructions(set)
assert.NoError(t, err)
tilCfgExtra := til.ConfigExtra{
CoordUser: "A",
}
err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
require.NoError(t, err)
const numBatches int = 6002
const numTx int = 6003
const blockNum = 6005 - 1
// Sanity check
require.Equal(t, blockNum, len(blocks))
// Adding one batch per block
// batch frequency can be chosen
const frequency int = 15
for i := range blocks {
blocks[i].Block.Timestamp = time.Now().Add(-time.Second * time.Duration(frequency*(len(blocks)-i)))
err = historyDB.AddBlockSCData(&blocks[i])
assert.NoError(t, err)
}
res, err := historyDB.GetMetrics(common.BatchNum(numBatches))
assert.NoError(t, err)
assert.Equal(t, math.Trunc((float64(numTx)/float64(numBatches-1))/0.001)*0.001, math.Trunc(res.TransactionsPerBatch/0.001)*0.001)
// Frequency is not exactly the desired one, some decimals may appear
assert.GreaterOrEqual(t, res.BatchFrequency, float64(frequency))
assert.Less(t, res.BatchFrequency, float64(frequency+1))
// Truncate frecuency into an int to do an exact check
assert.Equal(t, frequency, int(res.BatchFrequency))
// This may also be different in some decimals
// Truncate it to the third decimal to compare
assert.Equal(t, math.Trunc((float64(numTx)/float64(frequency*blockNum-frequency))/0.001)*0.001, math.Trunc(res.TransactionsPerSecond/0.001)*0.001)
assert.Equal(t, int64(3), res.TotalAccounts)
assert.Equal(t, int64(3), res.TotalBJJs)
// Til does not set fees
assert.Equal(t, float64(0), res.AvgTransactionFee)
}
func TestGetMetricsEmpty(t *testing.T) {
test.WipeDB(historyDB.DB())
_, err := historyDB.GetMetrics(0)

+ 2
- 0
db/historydb/views.go

@ -318,6 +318,8 @@ type MetricsTotals struct {
FirstBatchNum common.BatchNum `meddler:"batch_num"`
TotalBatches int64 `meddler:"total_batches"`
TotalFeesUSD float64 `meddler:"total_fees"`
MinTimestamp time.Time `meddler:"min_timestamp,utctime"`
MaxTimestamp time.Time `meddler:"max_timestamp,utctime"`
}
// BidAPI is a representation of a bid with additional information

Loading…
Cancel
Save