• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lmittmann / w3 / 13387471603

18 Feb 2025 09:34AM UTC coverage: 63.466% (+0.1%) from 63.344%
13387471603

Pull #224

github

lmittmann
w3types: added `BlockOverrides`
Pull Request #224: w3types: added `BlockOverrides`

14 of 16 new or added lines in 1 file covered. (87.5%)

13 existing lines in 1 file now uncovered.

2003 of 3156 relevant lines covered (63.47%)

763.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.35
/module/debug/trace.go
1
package debug
2

3
import (
4
        "encoding/hex"
5
        "encoding/json"
6
        "fmt"
7
        "math/big"
8

9
        "github.com/ethereum/go-ethereum/common"
10
        "github.com/ethereum/go-ethereum/core/vm"
11
        "github.com/holiman/uint256"
12
        "github.com/lmittmann/w3/internal/module"
13
        "github.com/lmittmann/w3/w3types"
14
)
15

16
// TraceCall requests the trace of the given message.
17
func TraceCall(msg *w3types.Message, blockNumber *big.Int, config *TraceConfig) w3types.RPCCallerFactory[*Trace] {
1✔
18
        if config == nil {
1✔
19
                config = &TraceConfig{}
×
20
        }
×
21
        return module.NewFactory(
1✔
22
                "debug_traceCall",
1✔
23
                []any{msg, module.BlockNumberArg(blockNumber), config},
1✔
24
                module.WithArgsWrapper[*Trace](msgArgsWrapper),
1✔
25
        )
1✔
26
}
27

28
// TraceTx requests the trace of the transaction with the given hash.
29
func TraceTx(txHash common.Hash, config *TraceConfig) w3types.RPCCallerFactory[*Trace] {
2✔
30
        if config == nil {
3✔
31
                config = &TraceConfig{}
1✔
32
        }
1✔
33
        return module.NewFactory[*Trace](
2✔
34
                "debug_traceTransaction",
2✔
35
                []any{txHash, config},
2✔
36
        )
2✔
37
}
38

39
type TraceConfig struct {
40
        Overrides     w3types.State // Override account state
41
        EnableStack   bool          // Enable stack capture
42
        EnableMemory  bool          // Enable memory capture
43
        EnableStorage bool          // Enable storage capture
44
        Limit         uint64        // Maximum number of StructLog's to capture (all if zero)
45
}
46

47
// MarshalJSON implements the [json.Marshaler].
48
func (c *TraceConfig) MarshalJSON() ([]byte, error) {
3✔
49
        type config struct {
3✔
50
                Overrides        w3types.State `json:"stateOverrides,omitempty"`
3✔
51
                DisableStorage   bool          `json:"disableStorage,omitempty"`
3✔
52
                DisableStack     bool          `json:"disableStack,omitempty"`
3✔
53
                EnableMemory     bool          `json:"enableMemory,omitempty"`
3✔
54
                EnableReturnData bool          `json:"enableReturnData,omitempty"`
3✔
55
                Limit            uint64        `json:"limit,omitempty"`
3✔
56
        }
3✔
57

3✔
58
        return json.Marshal(config{
3✔
59
                Overrides:        c.Overrides,
3✔
60
                DisableStorage:   !c.EnableStorage,
3✔
61
                DisableStack:     !c.EnableStack,
3✔
62
                EnableMemory:     c.EnableMemory,
3✔
63
                EnableReturnData: true,
3✔
64
                Limit:            c.Limit,
3✔
65
        })
3✔
66
}
3✔
67

68
type Trace struct {
69
        Gas        uint64       `json:"gas"`
70
        Failed     bool         `json:"failed"`
71
        Output     []byte       `json:"returnValue"`
72
        StructLogs []*StructLog `json:"structLogs"`
73
}
74

75
type StructLog struct {
76
        Pc      uint64
77
        Depth   uint
78
        Gas     uint64
79
        GasCost uint
80
        Op      vm.OpCode
81
        Stack   []uint256.Int
82
        Memory  []byte
83
        Storage w3types.Storage
84
}
85

86
func (l *StructLog) UnmarshalJSON(data []byte) error {
3✔
87
        type structLog struct {
3✔
88
                Pc      uint64
3✔
89
                Depth   uint
3✔
90
                Gas     uint64
3✔
91
                GasCost uint
3✔
92
                Op      string
3✔
93
                Stack   []uint256.Int
3✔
94
                Memory  memory
3✔
95
                Storage map[optionalPrefixedHash]optionalPrefixedHash
3✔
96
        }
3✔
97

3✔
98
        var dec structLog
3✔
99
        if err := json.Unmarshal(data, &dec); err != nil {
3✔
UNCOV
100
                return err
×
UNCOV
101
        }
×
102

103
        l.Pc = dec.Pc
3✔
104
        l.Depth = dec.Depth
3✔
105
        l.Gas = dec.Gas
3✔
106
        l.GasCost = dec.GasCost
3✔
107
        l.Op = vm.StringToOp(dec.Op)
3✔
108
        l.Stack = dec.Stack
3✔
109
        l.Memory = dec.Memory
3✔
110

3✔
111
        if len(dec.Storage) > 0 {
3✔
UNCOV
112
                l.Storage = make(w3types.Storage, len(dec.Storage))
×
UNCOV
113
                for k, v := range dec.Storage {
×
UNCOV
114
                        l.Storage[(common.Hash)(k)] = (common.Hash)(v)
×
115
                }
×
116
        }
117
        return nil
3✔
118
}
119

120
// optionalPrefixedHash is a helper for unmarshaling hashes with or without
121
// "0x"-prefix.
122
type optionalPrefixedHash common.Hash
123

124
func (h *optionalPrefixedHash) UnmarshalText(data []byte) error {
3✔
125
        if len(data) > 2 && data[0] == '0' && (data[1] == 'x' || data[1] == 'X') {
3✔
UNCOV
126
                data = data[2:]
×
UNCOV
127
        }
×
128

129
        if len(data) != 2*common.HashLength {
3✔
130
                return fmt.Errorf("hex string has length %d, want 64", len(data))
×
UNCOV
131
        }
×
132

133
        _, err := hex.Decode((*h)[:], data)
3✔
134
        return err
3✔
135
}
136

137
type memory []byte
138

139
func (m *memory) UnmarshalJSON(data []byte) error {
3✔
140
        var dec []optionalPrefixedHash
3✔
141
        if err := json.Unmarshal(data, &dec); err != nil {
3✔
UNCOV
142
                return err
×
UNCOV
143
        }
×
144

145
        *m = make([]byte, 0, 32*len(dec))
3✔
146
        for _, data := range dec {
6✔
147
                *m = append(*m, data[:]...)
3✔
148
        }
3✔
149
        return nil
3✔
150
}
151

152
func msgArgsWrapper(slice []any) ([]any, error) {
2✔
153
        msg := slice[0].(*w3types.Message)
2✔
154
        if msg.Input != nil || msg.Func == nil {
4✔
155
                return slice, nil
2✔
156
        }
2✔
157

UNCOV
158
        input, err := msg.Func.EncodeArgs(msg.Args...)
×
UNCOV
159
        if err != nil {
×
UNCOV
160
                return nil, err
×
161
        }
×
162
        msg.Input = input
×
163
        slice[0] = msg
×
164
        return slice, nil
×
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc