Skip to content

Commit

Permalink
refactor: calculate tps from tc every 5 blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
PhearZero committed Oct 23, 2024
1 parent 16291f5 commit 55e3fbb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 57 deletions.
35 changes: 35 additions & 0 deletions internal/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"github.com/algorandfoundation/hack-tui/api"
"time"
)

func GetBlock(ctx context.Context, client *api.ClientWithResponses, round uint64) (map[string]interface{}, error) {
Expand All @@ -22,3 +23,37 @@ func GetBlock(ctx context.Context, client *api.ClientWithResponses, round uint64

return block.JSON200.Block, nil
}

type BlockMetrics struct {
AvgTime time.Duration
TPS float64
}

func GetBlockMetrics(ctx context.Context, client *api.ClientWithResponses, round uint64, window int) (*BlockMetrics, error) {
var avgs BlockMetrics

var format api.GetBlockParamsFormat = "json"
a, err := client.GetBlockWithResponse(ctx, int(round), &api.GetBlockParams{
Format: &format,
})
if err != nil {
return nil, err
}
b, err := client.GetBlockWithResponse(ctx, int(round)-window, &api.GetBlockParams{
Format: &format,
})
if err != nil {
return nil, err
}
// Push to the transactions count list
aTimestamp := time.Duration(a.JSON200.Block["ts"].(float64)) * time.Second
bTimestamp := time.Duration(b.JSON200.Block["ts"].(float64)) * time.Second
//
aTransactions := a.JSON200.Block["tc"].(float64)
bTransactions := b.JSON200.Block["tc"].(float64)

avgs.AvgTime = time.Duration((int(aTimestamp - bTimestamp)) / window)
avgs.TPS = (aTransactions - bTransactions) / (float64(window) * avgs.AvgTime.Seconds())

return &avgs, nil
}
31 changes: 31 additions & 0 deletions internal/block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package internal

import (
"context"
"github.com/algorandfoundation/hack-tui/api"
"testing"
"time"
)

func Test_GetBlockMetrics(t *testing.T) {
window := 1000000

expectedAvg := time.Duration(2856041000)

client, err := api.NewClientWithResponses("https://mainnet-api.4160.nodely.dev:443")

metrics, err := GetBlockMetrics(context.Background(), client, uint64(42000000), window)
if err != nil {
t.Fatal(err)
}

if metrics.AvgTime != expectedAvg {
t.Fatal("expected time to be", expectedAvg, "got", metrics.AvgTime)
}

expectedTPS := 25.318608871511294

if metrics.TPS != expectedTPS {
t.Fatal("expected tps to be", expectedTPS, "got", metrics.TPS)
}
}
61 changes: 4 additions & 57 deletions internal/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"errors"
"github.com/algorandfoundation/hack-tui/api"
"time"
)

type StateModel struct {
Expand All @@ -31,9 +30,6 @@ func (s *StateModel) Watch(cb func(model *StateModel, err error), ctx context.Co

lastRound := s.Status.LastRound

// Collection of Transaction Counts
txns := make([]float64, 0)

for {
if !s.Watching {
break
Expand All @@ -52,44 +48,15 @@ func (s *StateModel) Watch(cb func(model *StateModel, err error), ctx context.Co
// Fetch Keys
s.UpdateKeys(ctx, client)

// Fetch Block
var format api.GetBlockParamsFormat = "json"
block, err := client.GetBlockWithResponse(ctx, int(lastRound), &api.GetBlockParams{
Format: &format,
})
if err != nil {
cb(nil, err)
}

// Push to the transactions count list
txnsValue := block.JSON200.Block["txns"]
if txnsValue == nil {
txns = append(txns, 0.0)
}
if txnsValue != nil {
txns = append(txns, float64(len(txnsValue.([]interface{}))))
}

// Run Round Averages and RX/TX every 5 rounds
if s.Status.LastRound%5 == 0 {
s.UpdateMetricsFromRPC(ctx, client)
err := s.UpdateRoundTime(ctx, client, time.Duration(block.JSON200.Block["ts"].(float64))*time.Second)
bm, err := GetBlockMetrics(ctx, client, s.Status.LastRound, s.Metrics.Window)
if err != nil {
cb(nil, err)
}
}
txnSum := 0.0
for i := 0; i < len(txns); i++ {
txnSum += txns[i]
}
txnAvg := txnSum / float64(len(txns))
if s.Metrics.RoundTime != 0 {
s.Metrics.TPS = txnAvg / s.Metrics.RoundTime.Seconds()
}

// Trim data
if len(txns) >= s.Metrics.Window {
txns = txns[1:]
s.Metrics.RoundTime = bm.AvgTime
s.Metrics.TPS = bm.TPS
s.UpdateMetricsFromRPC(ctx, client)
}

lastRound = s.Status.LastRound
Expand All @@ -101,26 +68,6 @@ func (s *StateModel) Stop() {
s.Watching = false
}

func (s *StateModel) UpdateRoundTime(
ctx context.Context,
client *api.ClientWithResponses,
timestamp time.Duration,
) error {
if s == nil {
panic("StateModel is nil while UpdateMetrics is called")
}
previousRound := s.Status.LastRound - uint64(s.Metrics.Window)
previousBlock, err := GetBlock(ctx, client, previousRound)
if err != nil {
s.Metrics.Enabled = false
return err
}
previousBlockTs := time.Duration(previousBlock["ts"].(float64)) * time.Second

s.Metrics.RoundTime = time.Duration(int(timestamp-previousBlockTs) / s.Metrics.Window)
return nil
}

func (s *StateModel) UpdateMetricsFromRPC(ctx context.Context, client *api.ClientWithResponses) {
// Fetch RX/TX
res, err := GetMetrics(ctx, client)
Expand Down

0 comments on commit 55e3fbb

Please sign in to comment.