arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
Merge pull request #270 from hermeznetwork/feature/api-state-metrics

API State Metrics
a_bennassar arnaubennassar5@gmail.com
Mon, 09 Nov 2020 16:54:25 +0100
commit

a1b9720e77addde2630c37a4b407e9f1446c8a58

parent

8190755d499f98d7b008cf6def3576d83a67b573

4 files changed, 64 insertions(+), 6 deletions(-)

jump to
M api/state.go → api/state.go

@@ -130,11 +130,11 @@ // Metrics

// UpdateMetrics update Status.Metrics information func (a *API) UpdateMetrics() error { - metrics, err := a.h.GetMetrics() + metrics, err := a.h.GetMetrics(a.status.Network.LastBatch.BatchNum) if err != nil { return err } - a.status.Metrics = metrics + a.status.Metrics = *metrics return nil }
M api/state_test.go → api/state_test.go

@@ -77,3 +77,22 @@ assert.Equal(t, lastBatchNum, api.status.Network.LastBatch.BatchNum)

assert.Equal(t, currentSlotNum, api.status.Network.CurrentSlot) 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)) +}
M db/historydb/historydb.go → db/historydb/historydb.go

@@ -1463,7 +1463,37 @@ accounts[0].TotalItems - uint64(len(accounts)), nil

} // 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 }
M db/historydb/views.go → db/historydb/views.go

@@ -303,9 +303,18 @@ type Metrics struct {

TransactionsPerBatch float64 `json:"transactionsPerBatch"` BatchFrequency float64 `json:"batchFrequency"` 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"` +} + +// 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