mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 10:20:44 +00:00
feat: params.RulesHooks.ActivePrecompiles override (#39)
This commit is contained in:
parent
99a755f040
commit
f1dba53688
4 changed files with 47 additions and 1 deletions
|
|
@ -148,7 +148,10 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||||
func ActivePrecompiles(rules params.Rules) []common.Address {
|
func ActivePrecompiles(rules params.Rules) (active []common.Address) {
|
||||||
|
defer func() {
|
||||||
|
active = rules.Hooks().ActivePrecompiles(append([]common.Address{}, active...))
|
||||||
|
}()
|
||||||
switch {
|
switch {
|
||||||
case rules.IsCancun:
|
case rules.IsCancun:
|
||||||
return PrecompiledAddressesCancun
|
return PrecompiledAddressesCancun
|
||||||
|
|
|
||||||
|
|
@ -423,3 +423,25 @@ func TestCanCreateContract(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestActivePrecompilesOverride(t *testing.T) {
|
||||||
|
newRules := func() params.Rules {
|
||||||
|
return new(params.ChainConfig).Rules(big.NewInt(0), false, 0)
|
||||||
|
}
|
||||||
|
defaultActive := vm.ActivePrecompiles(newRules())
|
||||||
|
|
||||||
|
rng := ethtest.NewPseudoRand(0xDecafC0ffeeBad)
|
||||||
|
precompiles := make([]common.Address, rng.Intn(10)+5)
|
||||||
|
for i := range precompiles {
|
||||||
|
precompiles[i] = rng.Address()
|
||||||
|
}
|
||||||
|
hooks := &hookstest.Stub{
|
||||||
|
ActivePrecompilesFn: func(active []common.Address) []common.Address {
|
||||||
|
assert.Equal(t, defaultActive, active, "ActivePrecompiles() hook receives default addresses")
|
||||||
|
return precompiles
|
||||||
|
},
|
||||||
|
}
|
||||||
|
hooks.Register(t)
|
||||||
|
|
||||||
|
require.Equal(t, precompiles, vm.ActivePrecompiles(newRules()), "vm.ActivePrecompiles() returns overridden addresses")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ type Stub struct {
|
||||||
CheckConfigCompatibleFn func(*params.ChainConfig, *big.Int, uint64) *params.ConfigCompatError
|
CheckConfigCompatibleFn func(*params.ChainConfig, *big.Int, uint64) *params.ConfigCompatError
|
||||||
DescriptionSuffix string
|
DescriptionSuffix string
|
||||||
PrecompileOverrides map[common.Address]libevm.PrecompiledContract
|
PrecompileOverrides map[common.Address]libevm.PrecompiledContract
|
||||||
|
ActivePrecompilesFn func([]common.Address) []common.Address
|
||||||
CanExecuteTransactionFn func(common.Address, *common.Address, libevm.StateReader) error
|
CanExecuteTransactionFn func(common.Address, *common.Address, libevm.StateReader) error
|
||||||
CanCreateContractFn func(*libevm.AddressContext, uint64, libevm.StateReader) (uint64, error)
|
CanCreateContractFn func(*libevm.AddressContext, uint64, libevm.StateReader) (uint64, error)
|
||||||
}
|
}
|
||||||
|
|
@ -71,6 +72,15 @@ func (s Stub) PrecompileOverride(a common.Address) (libevm.PrecompiledContract,
|
||||||
return p, ok
|
return p, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActivePrecompiles proxies arguments to the s.ActivePrecompilesFn function if
|
||||||
|
// non-nil, otherwise it acts as a noop.
|
||||||
|
func (s Stub) ActivePrecompiles(active []common.Address) []common.Address {
|
||||||
|
if f := s.ActivePrecompilesFn; f != nil {
|
||||||
|
return f(active)
|
||||||
|
}
|
||||||
|
return active
|
||||||
|
}
|
||||||
|
|
||||||
// CheckConfigForkOrder proxies arguments to the s.CheckConfigForkOrderFn
|
// CheckConfigForkOrder proxies arguments to the s.CheckConfigForkOrderFn
|
||||||
// function if non-nil, otherwise it acts as a noop.
|
// function if non-nil, otherwise it acts as a noop.
|
||||||
func (s Stub) CheckConfigForkOrder() error {
|
func (s Stub) CheckConfigForkOrder() error {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,12 @@ type RulesHooks interface {
|
||||||
// [PrecompiledContract] is non-nil. If it returns `false` then the default
|
// [PrecompiledContract] is non-nil. If it returns `false` then the default
|
||||||
// precompile behaviour is honoured.
|
// precompile behaviour is honoured.
|
||||||
PrecompileOverride(common.Address) (_ libevm.PrecompiledContract, override bool)
|
PrecompileOverride(common.Address) (_ libevm.PrecompiledContract, override bool)
|
||||||
|
// ActivePrecompiles receives the addresses that would usually be returned
|
||||||
|
// by a call to [vm.ActivePrecompiles] and MUST return the value to be
|
||||||
|
// returned by said function, which will be propagated. It MAY alter the
|
||||||
|
// received slice. The value it returns MUST be consistent with the
|
||||||
|
// behaviour of the PrecompileOverride hook.
|
||||||
|
ActivePrecompiles([]common.Address) []common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// RulesAllowlistHooks are a subset of [RulesHooks] that gate actions, signalled
|
// RulesAllowlistHooks are a subset of [RulesHooks] that gate actions, signalled
|
||||||
|
|
@ -120,3 +126,8 @@ func (NOOPHooks) CanCreateContract(_ *libevm.AddressContext, gas uint64, _ libev
|
||||||
func (NOOPHooks) PrecompileOverride(common.Address) (libevm.PrecompiledContract, bool) {
|
func (NOOPHooks) PrecompileOverride(common.Address) (libevm.PrecompiledContract, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActivePrecompiles echoes the active addresses unchanged.
|
||||||
|
func (NOOPHooks) ActivePrecompiles(active []common.Address) []common.Address {
|
||||||
|
return active
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue