Browse Source

Merge pull request #270 from hermeznetwork/feature/api-state-metrics

API State Metrics
feature/sql-semaphore1
a_bennassar 3 years ago
committed by GitHub
parent
commit
a1b9720e77
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 6 deletions
  1. +2
    -2
      api/state.go
  2. +19
    -0
      api/state_test.go
  3. +32
    -2
      db/historydb/historydb.go
  4. +11
    -2
      db/historydb/views.go

+ 2
- 2
api/state.go

@ -130,11 +130,11 @@ func (a *API) GetNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot
// UpdateMetrics update Status.Metrics information // UpdateMetrics update Status.Metrics information
func (a *API) UpdateMetrics() error { func (a *API) UpdateMetrics() error {
metrics, err := a.h.GetMetrics()
metrics, err := a.h.GetMetrics(a.status.Network.LastBatch.BatchNum)
if err != nil { if err != nil {
return err return err
} }
a.status.Metrics = metrics
a.status.Metrics = *metrics
return nil return nil
} }

+ 19
- 0
api/state_test.go

@ -77,3 +77,22 @@ func TestUpdateNetworkInfo(t *testing.T) {
assert.Equal(t, currentSlotNum, api.status.Network.CurrentSlot) assert.Equal(t, currentSlotNum, api.status.Network.CurrentSlot)
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(api.status.Network.NextForgers)) assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(api.status.Network.NextForgers))
} }
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)
currentSlotNum := int64(1)
err := api.UpdateNetworkInfo(lastBlock, lastBatchNum, currentSlotNum)
assert.NoError(t, err)
err = api.UpdateMetrics()
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.TotalAccounts, int64(0))
assert.Greater(t, api.status.Metrics.TotalBJJs, int64(0))
assert.Greater(t, api.status.Metrics.AvgTransactionFee, float64(0))
}

+ 32
- 2
db/historydb/historydb.go

@ -1463,7 +1463,37 @@ func (hdb *HistoryDB) GetAccountsAPI(
} }
// GetMetrics returns metrics // GetMetrics returns metrics
func (hdb *HistoryDB) GetMetrics() (Metrics, error) {
metrics := Metrics{}
func (hdb *HistoryDB) GetMetrics(lastBatchNum common.BatchNum) (*Metrics, error) {
metricsTotals := &MetricsTotals{}
metrics := &Metrics{}
err := meddler.QueryRow(
hdb.db, metricsTotals, `SELECT COUNT(tx.*) as total_txs, MIN(tx.batch_num) as batch_num
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, err
}
metrics.TransactionsPerSecond = float64(metricsTotals.TotalTransactions / (24 * 60 * 60))
metrics.TransactionsPerBatch = float64(int64(metricsTotals.TotalTransactions) / int64(lastBatchNum-metricsTotals.FirstBatchNum))
err = meddler.QueryRow(
hdb.db, metricsTotals, `SELECT COUNT(*) AS total_batches,
SUM(total_fees_usd) AS total_fees FROM batch
WHERE batch_num > $1;`, metricsTotals.FirstBatchNum)
if err != nil {
return nil, err
}
metrics.BatchFrequency = float64((24 * 60 * 60) / metricsTotals.TotalBatches)
metrics.AvgTransactionFee = metricsTotals.TotalFeesUSD / float64(metricsTotals.TotalTransactions)
err = meddler.QueryRow(
hdb.db, metrics,
`SELECT COUNT(*) AS total_bjjs, COUNT(DISTINCT(bjj)) AS total_accounts FROM account;`)
if err != nil {
return nil, err
}
return metrics, nil return metrics, nil
} }

+ 11
- 2
db/historydb/views.go

@ -303,11 +303,20 @@ type Metrics struct {
TransactionsPerBatch float64 `json:"transactionsPerBatch"` TransactionsPerBatch float64 `json:"transactionsPerBatch"`
BatchFrequency float64 `json:"batchFrequency"` BatchFrequency float64 `json:"batchFrequency"`
TransactionsPerSecond float64 `json:"transactionsPerSecond"` TransactionsPerSecond float64 `json:"transactionsPerSecond"`
TotalAccounts int64 `json:"totalAccounts"`
TotalBJJs int64 `json:"totalBJJs"`
TotalAccounts int64 `json:"totalAccounts" meddler:"total_accounts"`
TotalBJJs int64 `json:"totalBJJs" meddler:"total_bjjs"`
AvgTransactionFee float64 `json:"avgTransactionFee"` AvgTransactionFee float64 `json:"avgTransactionFee"`
} }
// MetricsTotals is used to get temporal information from HistoryDB
// to calculate data to be stored into the Metrics struct
type MetricsTotals struct {
TotalTransactions uint64 `meddler:"total_txs"`
FirstBatchNum common.BatchNum `meddler:"batch_num"`
TotalBatches int64 `meddler:"total_batches"`
TotalFeesUSD float64 `meddler:"total_fees"`
}
// BidAPI is a representation of a bid with additional information // BidAPI is a representation of a bid with additional information
// required by the API // required by the API
type BidAPI struct { type BidAPI struct {

Loading…
Cancel
Save