-
Notifications
You must be signed in to change notification settings - Fork 3
/
gasTracer.go
112 lines (91 loc) · 3.45 KB
/
gasTracer.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package contexts
// GasTraceMap is the map that holds gas traces for all API functions, depending on SCAddress and functionName
type gasTraceMap map[string]map[string][]uint64
// gasTracer holds information about the gas trace
type gasTracer struct {
gasTrace gasTraceMap
functionNameTraced string
scAddress string
}
// NewEnabledGasTracer creates a new gasTracer
func NewEnabledGasTracer() *gasTracer {
return &gasTracer{
gasTrace: make(map[string]map[string][]uint64)}
}
// NewDisabledGasTracer creates a new disabledGasTracer
func NewDisabledGasTracer() *disabledGasTracer {
return &disabledGasTracer{}
}
// BeginTrace prepares the gasTracer to trace the correct scAddress and function
func (gt *gasTracer) BeginTrace(scAddress string, functionName string) {
gt.setCurrentFunctionTraced(functionName)
gt.setCurrentScAddressTraced(scAddress)
gt.createGasTraceIfNil(scAddress, functionName)
gt.newTrace(scAddress, functionName)
}
// AddToCurrentTrace ads the usedGas passed at the current trace value
func (gt *gasTracer) AddToCurrentTrace(usedGas uint64) {
gt.createGasTraceIfNil(gt.scAddress, gt.functionNameTraced)
funcTrace := gt.gasTrace[gt.scAddress][gt.functionNameTraced]
length := len(funcTrace)
if length > 0 {
gt.gasTrace[gt.scAddress][gt.functionNameTraced][length-1] += usedGas
} else {
gt.gasTrace[gt.scAddress][gt.functionNameTraced] = append(funcTrace, usedGas)
}
}
// AddTracedGas directly ads usedGas in the gasTrace map
func (gt *gasTracer) AddTracedGas(scAddress string, functionName string, usedGas uint64) {
gt.createGasTraceIfNil(scAddress, functionName)
gt.gasTrace[scAddress][functionName] = append(gt.gasTrace[scAddress][functionName], usedGas)
}
func (gt *gasTracer) setCurrentFunctionTraced(functionName string) {
gt.functionNameTraced = functionName
}
func (gt *gasTracer) setCurrentScAddressTraced(scAddress string) {
gt.scAddress = scAddress
}
func (gt *gasTracer) newTrace(scAddress string, functionName string) {
gt.gasTrace[scAddress][functionName] = append(gt.gasTrace[scAddress][functionName], 0)
}
func (gt *gasTracer) createGasTraceIfNil(scAddress string, functionName string) {
gt.createSCAdressGasTracingIfNil(scAddress)
gt.createFunctionNameGasTracingIfNil(scAddress, functionName)
}
func (gt *gasTracer) createSCAdressGasTracingIfNil(scAddress string) {
if gt.gasTrace[scAddress] == nil {
gt.gasTrace[scAddress] = make(map[string][]uint64)
}
}
func (gt *gasTracer) createFunctionNameGasTracingIfNil(scAddress string, functionName string) {
if gt.gasTrace[scAddress][functionName] == nil {
gt.gasTrace[scAddress][functionName] = make([]uint64, 0)
}
}
// GetGasTrace returns the gasTrace map
func (gt *gasTracer) GetGasTrace() map[string]map[string][]uint64 {
return gt.gasTrace
}
// IsInterfaceNil returns true if there is no value under the interface
func (gt *gasTracer) IsInterfaceNil() bool {
return gt == nil
}
type disabledGasTracer struct {
}
// BeginTrace does nothing
func (dgt *disabledGasTracer) BeginTrace(_ string, _ string) {
}
// AddToCurrentTrace does nothing
func (dgt *disabledGasTracer) AddToCurrentTrace(_ uint64) {
}
// AddTracedGas does nothing
func (dgt *disabledGasTracer) AddTracedGas(_ string, _ string, _ uint64) {
}
// GetGasTrace returns nil
func (dgt *disabledGasTracer) GetGasTrace() map[string]map[string][]uint64 {
return nil
}
// IsInterfaceNil returns true if there is no value under the interface
func (dgt *disabledGasTracer) IsInterfaceNil() bool {
return dgt == nil
}