Skip to content

Commit f1dba53

Browse files
authored
feat: params.RulesHooks.ActivePrecompiles override (#39)
1 parent 99a755f commit f1dba53

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

core/vm/contracts.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ func init() {
148148
}
149149

150150
// ActivePrecompiles returns the precompiles enabled with the current configuration.
151-
func ActivePrecompiles(rules params.Rules) []common.Address {
151+
func ActivePrecompiles(rules params.Rules) (active []common.Address) {
152+
defer func() {
153+
active = rules.Hooks().ActivePrecompiles(append([]common.Address{}, active...))
154+
}()
152155
switch {
153156
case rules.IsCancun:
154157
return PrecompiledAddressesCancun

core/vm/contracts.libevm_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,25 @@ func TestCanCreateContract(t *testing.T) {
423423
})
424424
}
425425
}
426+
427+
func TestActivePrecompilesOverride(t *testing.T) {
428+
newRules := func() params.Rules {
429+
return new(params.ChainConfig).Rules(big.NewInt(0), false, 0)
430+
}
431+
defaultActive := vm.ActivePrecompiles(newRules())
432+
433+
rng := ethtest.NewPseudoRand(0xDecafC0ffeeBad)
434+
precompiles := make([]common.Address, rng.Intn(10)+5)
435+
for i := range precompiles {
436+
precompiles[i] = rng.Address()
437+
}
438+
hooks := &hookstest.Stub{
439+
ActivePrecompilesFn: func(active []common.Address) []common.Address {
440+
assert.Equal(t, defaultActive, active, "ActivePrecompiles() hook receives default addresses")
441+
return precompiles
442+
},
443+
}
444+
hooks.Register(t)
445+
446+
require.Equal(t, precompiles, vm.ActivePrecompiles(newRules()), "vm.ActivePrecompiles() returns overridden addresses")
447+
}

libevm/hookstest/stub.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type Stub struct {
4545
CheckConfigCompatibleFn func(*params.ChainConfig, *big.Int, uint64) *params.ConfigCompatError
4646
DescriptionSuffix string
4747
PrecompileOverrides map[common.Address]libevm.PrecompiledContract
48+
ActivePrecompilesFn func([]common.Address) []common.Address
4849
CanExecuteTransactionFn func(common.Address, *common.Address, libevm.StateReader) error
4950
CanCreateContractFn func(*libevm.AddressContext, uint64, libevm.StateReader) (uint64, error)
5051
}
@@ -71,6 +72,15 @@ func (s Stub) PrecompileOverride(a common.Address) (libevm.PrecompiledContract,
7172
return p, ok
7273
}
7374

75+
// ActivePrecompiles proxies arguments to the s.ActivePrecompilesFn function if
76+
// non-nil, otherwise it acts as a noop.
77+
func (s Stub) ActivePrecompiles(active []common.Address) []common.Address {
78+
if f := s.ActivePrecompilesFn; f != nil {
79+
return f(active)
80+
}
81+
return active
82+
}
83+
7484
// CheckConfigForkOrder proxies arguments to the s.CheckConfigForkOrderFn
7585
// function if non-nil, otherwise it acts as a noop.
7686
func (s Stub) CheckConfigForkOrder() error {

params/hooks.libevm.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ type RulesHooks interface {
4848
// [PrecompiledContract] is non-nil. If it returns `false` then the default
4949
// precompile behaviour is honoured.
5050
PrecompileOverride(common.Address) (_ libevm.PrecompiledContract, override bool)
51+
// ActivePrecompiles receives the addresses that would usually be returned
52+
// by a call to [vm.ActivePrecompiles] and MUST return the value to be
53+
// returned by said function, which will be propagated. It MAY alter the
54+
// received slice. The value it returns MUST be consistent with the
55+
// behaviour of the PrecompileOverride hook.
56+
ActivePrecompiles([]common.Address) []common.Address
5157
}
5258

5359
// RulesAllowlistHooks are a subset of [RulesHooks] that gate actions, signalled
@@ -120,3 +126,8 @@ func (NOOPHooks) CanCreateContract(_ *libevm.AddressContext, gas uint64, _ libev
120126
func (NOOPHooks) PrecompileOverride(common.Address) (libevm.PrecompiledContract, bool) {
121127
return nil, false
122128
}
129+
130+
// ActivePrecompiles echoes the active addresses unchanged.
131+
func (NOOPHooks) ActivePrecompiles(active []common.Address) []common.Address {
132+
return active
133+
}

0 commit comments

Comments
 (0)