@@ -42,7 +42,7 @@ import (
42
42
// args := &evmCallArgs{evm, staticCall, caller, addr, input, gas, nil /*value*/}
43
43
type evmCallArgs struct {
44
44
evm * EVM
45
- callType callType
45
+ callType CallType
46
46
47
47
// args:start
48
48
caller ContractRef
@@ -53,15 +53,32 @@ type evmCallArgs struct {
53
53
// args:end
54
54
}
55
55
56
- type callType uint8
56
+ // A CallType refers to a *CALL* [OpCode] / respective method on [EVM].
57
+ type CallType uint8
57
58
58
59
const (
59
- call callType = iota + 1
60
- callCode
61
- delegateCall
62
- staticCall
60
+ UnknownCallType CallType = iota
61
+ Call
62
+ CallCode
63
+ DelegateCall
64
+ StaticCall
63
65
)
64
66
67
+ // String returns a human-readable representation of the CallType.
68
+ func (t CallType ) String () string {
69
+ switch t {
70
+ case Call :
71
+ return "Call"
72
+ case CallCode :
73
+ return "CallCode"
74
+ case DelegateCall :
75
+ return "DelegateCall"
76
+ case StaticCall :
77
+ return "StaticCall"
78
+ }
79
+ return fmt .Sprintf ("Unknown %T(%d)" , t , t )
80
+ }
81
+
65
82
// run runs the [PrecompiledContract], differentiating between stateful and
66
83
// regular types.
67
84
func (args * evmCallArgs ) run (p PrecompiledContract , input []byte , suppliedGas uint64 ) (ret []byte , remainingGas uint64 , err error ) {
@@ -115,6 +132,7 @@ type PrecompileEnvironment interface {
115
132
// ReadOnlyState will always be non-nil.
116
133
ReadOnlyState () libevm.StateReader
117
134
Addresses () * libevm.AddressContext
135
+ IncomingCallType () CallType
118
136
119
137
BlockHeader () (types.Header , error )
120
138
BlockNumber () * big.Int
@@ -132,46 +150,30 @@ func (args *evmCallArgs) env() *environment {
132
150
value = args .value
133
151
)
134
152
switch args .callType {
135
- case staticCall :
153
+ case StaticCall :
136
154
value = new (uint256.Int )
137
155
fallthrough
138
- case call :
156
+ case Call :
139
157
self = args .addr
140
158
141
- case delegateCall :
159
+ case DelegateCall :
142
160
value = nil
143
161
fallthrough
144
- case callCode :
162
+ case CallCode :
145
163
self = args .caller .Address ()
146
164
}
147
165
148
166
// This is equivalent to the `contract` variables created by evm.*Call*()
149
167
// methods, for non precompiles, to pass to [EVMInterpreter.Run].
150
168
contract := NewContract (args .caller , AccountRef (self ), value , args .gas )
151
- if args .callType == delegateCall {
169
+ if args .callType == DelegateCall {
152
170
contract = contract .AsDelegate ()
153
171
}
154
172
155
173
return & environment {
156
- evm : args .evm ,
157
- self : contract ,
158
- forceReadOnly : args .readOnly (),
159
- }
160
- }
161
-
162
- func (args * evmCallArgs ) readOnly () bool {
163
- // A switch statement provides clearer code coverage for difficult-to-test
164
- // cases.
165
- switch {
166
- case args .callType == staticCall :
167
- // evm.interpreter.readOnly is only set to true via a call to
168
- // EVMInterpreter.Run() so, if a precompile is called directly with
169
- // StaticCall(), then readOnly might not be set yet.
170
- return true
171
- case args .evm .interpreter .readOnly :
172
- return true
173
- default :
174
- return false
174
+ evm : args .evm ,
175
+ self : contract ,
176
+ callType : args .callType ,
175
177
}
176
178
}
177
179
0 commit comments