Skip to content

Commit c63b031

Browse files
committed
feat: precompile can override default caller in Call()
1 parent 5c1f285 commit c63b031

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

core/vm/contracts.libevm.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ type PrecompileEnvironment interface {
135135
BlockNumber() *big.Int
136136
BlockTime() uint64
137137

138-
Call(common.Address, []byte, uint64, *uint256.Int) ([]byte, uint64, error)
138+
// Call is equivalent to [EVM.Call], with the caller defaulting to the
139+
// precompile receiving the environment, or to its own caller if invoked via
140+
// a delegated call.
141+
Call(addr common.Address, input []byte, gas uint64, value *uint256.Int, _ ...CallOption) (ret []byte, gasRemaining uint64, _ error)
139142
}
140143

141144
var _ PrecompileEnvironment = (*evmCallArgs)(nil)
@@ -198,7 +201,7 @@ func (args *evmCallArgs) BlockNumber() *big.Int {
198201

199202
func (args *evmCallArgs) BlockTime() uint64 { return args.evm.Context.Time }
200203

201-
func (args *evmCallArgs) Call(addr common.Address, input []byte, gas uint64, value *uint256.Int) ([]byte, uint64, error) {
204+
func (args *evmCallArgs) Call(addr common.Address, input []byte, gas uint64, value *uint256.Int, opts ...CallOption) ([]byte, uint64, error) {
202205
in := args.evm.interpreter
203206

204207
// The precompile run didn't increment the depth so this is necessary even
@@ -220,7 +223,19 @@ func (args *evmCallArgs) Call(addr common.Address, input []byte, gas uint64, val
220223
if args.delegation == delegated {
221224
precompile = precompile.AsDelegate()
222225
}
223-
return args.evm.Call(precompile, addr, input, gas, value)
226+
var caller ContractRef = precompile
227+
228+
for _, o := range opts {
229+
switch o := o.(type) {
230+
case withCallerOpt:
231+
caller = o.ContractRef
232+
case nil:
233+
default:
234+
return nil, gas, fmt.Errorf("unsupported option %T", o)
235+
}
236+
}
237+
238+
return args.evm.Call(caller, addr, input, gas, value)
224239
}
225240

226241
var (

core/vm/options.libevm.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2024 the libevm authors.
2+
//
3+
// The libevm additions to go-ethereum are free software: you can redistribute
4+
// them and/or modify them under the terms of the GNU Lesser General Public License
5+
// as published by the Free Software Foundation, either version 3 of the License,
6+
// or (at your option) any later version.
7+
//
8+
// The libevm additions are distributed in the hope that they will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+
// General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Lesser General Public License
14+
// along with the go-ethereum library. If not, see
15+
// <http://www.gnu.org/licenses/>.
16+
17+
package vm
18+
19+
// A CallOption modifies the default behaviour of a contract call.
20+
type CallOption interface {
21+
libevmCallOption() // noop to only allow internally defined options
22+
}
23+
24+
// WithCaller overrides the default caller.
25+
func WithCaller(c ContractRef) CallOption {
26+
return withCallerOpt{c}
27+
}
28+
29+
type withCallerOpt struct {
30+
ContractRef
31+
}
32+
33+
func (withCallerOpt) libevmCallOption() {}

0 commit comments

Comments
 (0)