mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
refactor: abstract options package (#74)
## Why this should be merged Simplifies the creation and application of variadic options; this is also applicable to many of my other WIP branches (e.g. `snapshot`). ## How this works See `libevm/options/options.go`, which is very simple. ## How this was tested Existing tests of `vm.PrecompileEnvironment.Call()`, which itself uses refactored options.
This commit is contained in:
parent
594abd9f42
commit
44068c8bab
3 changed files with 61 additions and 23 deletions
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/ava-labs/libevm/common"
|
"github.com/ava-labs/libevm/common"
|
||||||
"github.com/ava-labs/libevm/core/types"
|
"github.com/ava-labs/libevm/core/types"
|
||||||
"github.com/ava-labs/libevm/libevm"
|
"github.com/ava-labs/libevm/libevm"
|
||||||
|
"github.com/ava-labs/libevm/libevm/options"
|
||||||
"github.com/ava-labs/libevm/params"
|
"github.com/ava-labs/libevm/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -105,20 +106,14 @@ func (e *environment) callContract(typ CallType, addr common.Address, input []by
|
||||||
}
|
}
|
||||||
|
|
||||||
var caller ContractRef = e.self
|
var caller ContractRef = e.self
|
||||||
for _, o := range opts {
|
if options.As[callConfig](opts...).unsafeCallerAddressProxying {
|
||||||
switch o := o.(type) {
|
// Note that, in addition to being unsafe, this breaks an EVM
|
||||||
case callOptUNSAFECallerAddressProxy:
|
// assumption that the caller ContractRef is always a *Contract.
|
||||||
// Note that, in addition to being unsafe, this breaks an EVM
|
caller = AccountRef(e.self.CallerAddress)
|
||||||
// assumption that the caller ContractRef is always a *Contract.
|
if e.callType == DelegateCall {
|
||||||
caller = AccountRef(e.self.CallerAddress)
|
// self was created with AsDelegate(), which means that
|
||||||
if e.callType == DelegateCall {
|
// CallerAddress was inherited.
|
||||||
// self was created with AsDelegate(), which means that
|
caller = AccountRef(e.self.Address())
|
||||||
// CallerAddress was inherited.
|
|
||||||
caller = AccountRef(e.self.Address())
|
|
||||||
}
|
|
||||||
case nil:
|
|
||||||
default:
|
|
||||||
return nil, gas, fmt.Errorf("unsupported option %T", o)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,15 @@
|
||||||
|
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
// A CallOption modifies the default behaviour of a contract call.
|
import "github.com/ava-labs/libevm/libevm/options"
|
||||||
type CallOption interface {
|
|
||||||
libevmCallOption() // noop to only allow internally defined options
|
type callConfig struct {
|
||||||
|
unsafeCallerAddressProxying bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A CallOption modifies the default behaviour of a contract call.
|
||||||
|
type CallOption = options.Option[callConfig]
|
||||||
|
|
||||||
// WithUNSAFECallerAddressProxying results in precompiles making contract calls
|
// WithUNSAFECallerAddressProxying results in precompiles making contract calls
|
||||||
// specifying their own caller's address as the caller. This is NOT SAFE for
|
// specifying their own caller's address as the caller. This is NOT SAFE for
|
||||||
// regular use as callers of the precompile may not understand that they are
|
// regular use as callers of the precompile may not understand that they are
|
||||||
|
|
@ -29,10 +33,7 @@ type CallOption interface {
|
||||||
// Deprecated: this option MUST NOT be used other than to allow migration to
|
// Deprecated: this option MUST NOT be used other than to allow migration to
|
||||||
// libevm when backwards compatibility is required.
|
// libevm when backwards compatibility is required.
|
||||||
func WithUNSAFECallerAddressProxying() CallOption {
|
func WithUNSAFECallerAddressProxying() CallOption {
|
||||||
return callOptUNSAFECallerAddressProxy{}
|
return options.Func[callConfig](func(c *callConfig) {
|
||||||
|
c.unsafeCallerAddressProxying = true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: see [WithUNSAFECallerAddressProxying].
|
|
||||||
type callOptUNSAFECallerAddressProxy struct{}
|
|
||||||
|
|
||||||
func (callOptUNSAFECallerAddressProxy) libevmCallOption() {}
|
|
||||||
|
|
|
||||||
42
libevm/options/options.go
Normal file
42
libevm/options/options.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2024 the libevm authors.
|
||||||
|
//
|
||||||
|
// The libevm additions to go-ethereum are free software: you can redistribute
|
||||||
|
// them and/or modify them under the terms of the GNU Lesser General Public License
|
||||||
|
// as published by the Free Software Foundation, either version 3 of the License,
|
||||||
|
// or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The libevm additions are distributed in the hope that they will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Package options provides a generic mechanism for defining configuration of
|
||||||
|
// arbitrary types.
|
||||||
|
package options
|
||||||
|
|
||||||
|
// An Option configures values of arbitrary type.
|
||||||
|
type Option[T any] interface {
|
||||||
|
Configure(*T)
|
||||||
|
}
|
||||||
|
|
||||||
|
// As applies Options to a zero-value T, which it then returns.
|
||||||
|
func As[T any](opts ...Option[T]) *T {
|
||||||
|
var t T
|
||||||
|
for _, o := range opts {
|
||||||
|
o.Configure(&t)
|
||||||
|
}
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Func converts a function into an [Option], using itself as the Configure
|
||||||
|
// method.
|
||||||
|
type Func[T any] func(*T)
|
||||||
|
|
||||||
|
var _ Option[struct{}] = Func[struct{}](nil)
|
||||||
|
|
||||||
|
// Configure implements the [Option] interface.
|
||||||
|
func (f Func[T]) Configure(t *T) { f(t) }
|
||||||
Loading…
Reference in a new issue