Browse Source

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

Added new metrics tests
feature/sql-semaphore1
a_bennassar 3 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) { func TestUpdateMetrics(t *testing.T) {
// TODO: Improve checks when til is integrated
// Update Metrics needs api.status.Network.LastBatch.BatchNum to be updated // Update Metrics needs api.status.Network.LastBatch.BatchNum to be updated
lastBlock := tc.blocks[3] lastBlock := tc.blocks[3]
lastBatchNum := common.BatchNum(3) lastBatchNum := common.BatchNum(3)
@ -76,7 +75,7 @@ func TestUpdateMetrics(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Greater(t, api.status.Metrics.TransactionsPerBatch, float64(0)) assert.Greater(t, api.status.Metrics.TransactionsPerBatch, float64(0))
assert.Greater(t, api.status.Metrics.BatchFrequency, 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.TotalAccounts, int64(0))
assert.Greater(t, api.status.Metrics.TotalBJJs, int64(0)) assert.Greater(t, api.status.Metrics.TotalBJJs, int64(0))
assert.Greater(t, api.status.Metrics.AvgTransactionFee, float64(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) // TODO: perform real asserts (not just greater than 0)
assert.Greater(t, status.Metrics.TransactionsPerBatch, float64(0)) assert.Greater(t, status.Metrics.TransactionsPerBatch, float64(0))
assert.Greater(t, status.Metrics.BatchFrequency, 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.TotalAccounts, int64(0))
assert.Greater(t, status.Metrics.TotalBJJs, int64(0)) assert.Greater(t, status.Metrics.TotalBJJs, int64(0))
assert.Greater(t, status.Metrics.AvgTransactionFee, float64(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{} metrics := &Metrics{}
err := meddler.QueryRow( err := meddler.QueryRow(
hdb.db, metricsTotals, `SELECT COUNT(tx.*) as total_txs, 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 FROM tx INNER JOIN block ON tx.eth_block_num = block.eth_block_num
WHERE block.timestamp >= NOW() - INTERVAL '24 HOURS';`) WHERE block.timestamp >= NOW() - INTERVAL '24 HOURS';`)
if err != nil { if err != nil {
return nil, tracerr.Wrap(err) 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 { 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 { } else {
metrics.TransactionsPerBatch = float64(0) metrics.TransactionsPerBatch = float64(0)
} }
@ -1846,7 +1854,7 @@ func (hdb *HistoryDB) GetMetrics(lastBatchNum common.BatchNum) (*Metrics, error)
return nil, tracerr.Wrap(err) return nil, tracerr.Wrap(err)
} }
if metricsTotals.TotalBatches > 0 { if metricsTotals.TotalBatches > 0 {
metrics.BatchFrequency = float64((24 * 60 * 60) / metricsTotals.TotalBatches)
metrics.BatchFrequency = seconds / float64(metricsTotals.TotalBatches)
} else { } else {
metrics.BatchFrequency = 0 metrics.BatchFrequency = 0
} }

+ 158
- 0
db/historydb/historydb_test.go

@ -1028,6 +1028,164 @@ func TestAddEscapeHatchWithdrawals(t *testing.T) {
assert.Equal(t, escapeHatchWithdrawals, dbEscapeHatchWithdrawals) 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) { func TestGetMetricsEmpty(t *testing.T) {
test.WipeDB(historyDB.DB()) test.WipeDB(historyDB.DB())
_, err := historyDB.GetMetrics(0) _, err := historyDB.GetMetrics(0)

+ 2
- 0
db/historydb/views.go

@ -318,6 +318,8 @@ type MetricsTotals struct {
FirstBatchNum common.BatchNum `meddler:"batch_num"` FirstBatchNum common.BatchNum `meddler:"batch_num"`
TotalBatches int64 `meddler:"total_batches"` TotalBatches int64 `meddler:"total_batches"`
TotalFeesUSD float64 `meddler:"total_fees"` 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 // BidAPI is a representation of a bid with additional information

Loading…
Cancel
Save