/
gas_stats.go
96 lines (85 loc) · 2.21 KB
/
gas_stats.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package blockchain
import (
"sort"
"sync"
"github.com/rs/zerolog/log"
)
const (
// GWei one giga-wei used for gas calculations
GWei = 1e9
// ETH one eth in wei
ETH = 1e18
)
// GasStats helper struct to determine gas metrics across all txs of a test
type GasStats struct {
NodeID int
TotalGasUsed int64
SeenHashes map[string]bool
ClientTXs []TXGasData
addMu sync.Mutex
}
// TXGasData transaction gas data
type TXGasData struct {
TXHash string
Value uint64
GasLimit uint64
GasUsed uint64
GasPrice uint64
CumulativeGasUsed uint64
}
// NewGasStats creates new gas stats collector
func NewGasStats(nodeID int) *GasStats {
return &GasStats{
NodeID: nodeID,
SeenHashes: make(map[string]bool),
ClientTXs: make([]TXGasData, 0),
}
}
// AddClientTXData adds client TX data
func (g *GasStats) AddClientTXData(data TXGasData) {
g.addMu.Lock()
defer g.addMu.Unlock()
if _, ok := g.SeenHashes[data.TXHash]; !ok {
g.ClientTXs = append(g.ClientTXs, data)
}
}
func (g *GasStats) txCost(data TXGasData) float64 {
fee := float64(data.GasPrice * data.GasUsed)
val := float64(data.Value)
return (fee + val) / ETH
}
func (g *GasStats) maxGasUsage() uint64 {
if len(g.ClientTXs) == 0 {
return 0
}
sort.Slice(g.ClientTXs, func(i, j int) bool {
return g.ClientTXs[i].GasUsed > g.ClientTXs[j].GasUsed
})
return g.ClientTXs[0].GasUsed
}
func (g *GasStats) totalCost() float64 {
var total float64
for _, tx := range g.ClientTXs {
total += g.txCost(tx)
}
return total
}
// PrintStats prints gas stats and total TXs cost
func (g *GasStats) PrintStats() {
log.Info().Msg("---------- Start Gas Stats ----------")
log.Info().Int("Node", g.NodeID).Uint64("Gas (GWei)", g.maxGasUsage()).Msg("Max gas used")
for _, tx := range g.ClientTXs {
log.Info().
Int("Node", g.NodeID).
Float64("Value (ETH)", float64(tx.Value)/ETH).
Uint64("Gas used", tx.GasUsed).
Float64("Suggested gas price (GWei)", float64(tx.GasPrice)/GWei).
Uint64("Gas Limit", tx.GasLimit).
Float64("Cost (ETH)", g.txCost(tx)).
Msg("TX Cost")
}
log.Info().
Float64("ETH", g.totalCost()).
Msg("Total TXs cost")
log.Info().Msg("---------------- End ---------------")
}