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