go-ethereum/libevm/hookstest/stub.go
Arran Schlosberg 04543ea837
chore: golangci-lint CI workflow (#16)
* chore: `golangci-lint` CI workflow

* fix: make `golangci-lint` happy

* chore: bump `actions/{checkout,setup-go}` versions

* chore: overhaul `.golanci.yml` config

* fix: all linter issues

* chore: exclude non-libevm linters + change deprecated option

* fix: add overflow check in example

* fix: try again; different local version?

* chore: this is trying my patience

* chore: enable `gci` and fix ordering

* chore: mark `ethclient/gethclient` test as flaky

* chore: mark `eth/catalyst` test as flaky
2024-09-12 20:31:04 +01:00

76 lines
2.5 KiB
Go

// Package hookstest provides test doubles and convenience wrappers for testing
// libevm hooks.
package hookstest
import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/libevm"
"github.com/ethereum/go-ethereum/params"
)
// Register clears any registered [params.Extras] and then registers `extras`
// for the lifetime of the current test, clearing them via tb's
// [testing.TB.Cleanup].
func Register[C params.ChainConfigHooks, R params.RulesHooks](tb testing.TB, extras params.Extras[C, R]) {
tb.Helper()
params.TestOnlyClearRegisteredExtras()
tb.Cleanup(params.TestOnlyClearRegisteredExtras)
params.RegisterExtras(extras)
}
// A Stub is a test double for [params.ChainConfigHooks] and
// [params.RulesHooks]. Each of the fields, if non-nil, back their respective
// hook methods, which otherwise fall back to the default behaviour.
type Stub struct {
PrecompileOverrides map[common.Address]libevm.PrecompiledContract
CanExecuteTransactionFn func(common.Address, *common.Address, libevm.StateReader) error
CanCreateContractFn func(*libevm.AddressContext, libevm.StateReader) error
}
// Register is a convenience wrapper for registering s as both the
// [params.ChainConfigHooks] and [params.RulesHooks] via [Register].
func (s *Stub) Register(tb testing.TB) {
tb.Helper()
Register(tb, params.Extras[*Stub, *Stub]{
NewRules: func(_ *params.ChainConfig, _ *params.Rules, _ *Stub, blockNum *big.Int, isMerge bool, timestamp uint64) *Stub {
return s
},
})
}
// PrecompileOverride uses the s.PrecompileOverrides map, if non-empty, as the
// canonical source of all overrides. If the map is empty then no precompiles
// are overridden.
func (s Stub) PrecompileOverride(a common.Address) (libevm.PrecompiledContract, bool) {
if len(s.PrecompileOverrides) == 0 {
return nil, false
}
p, ok := s.PrecompileOverrides[a]
return p, ok
}
// CanExecuteTransaction proxies arguments to the s.CanExecuteTransactionFn
// function if non-nil, otherwise it acts as a noop.
func (s Stub) CanExecuteTransaction(from common.Address, to *common.Address, sr libevm.StateReader) error {
if f := s.CanExecuteTransactionFn; f != nil {
return f(from, to, sr)
}
return nil
}
// CanCreateContract proxies arguments to the s.CanCreateContractFn function if
// non-nil, otherwise it acts as a noop.
func (s Stub) CanCreateContract(cc *libevm.AddressContext, sr libevm.StateReader) error {
if f := s.CanCreateContractFn; f != nil {
return f(cc, sr)
}
return nil
}
var _ interface {
params.ChainConfigHooks
params.RulesHooks
} = Stub{}